@jjlmoya/utils-games-development 1.55.0 → 1.56.0

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.
Files changed (38) hide show
  1. package/package.json +1 -1
  2. package/src/entries.ts +4 -1
  3. package/src/index.ts +1 -0
  4. package/src/tests/contrast_legibility.test.ts +56 -10
  5. package/src/tests/locale_completeness.test.ts +2 -2
  6. package/src/tests/tool_validation.test.ts +2 -2
  7. package/src/tool/localizationSanitizer/localization-sanitizer.css +4 -2
  8. package/src/tool/pixelArtPaletteSwapper/app-client.ts +229 -0
  9. package/src/tool/pixelArtPaletteSwapper/bibliography.astro +6 -0
  10. package/src/tool/pixelArtPaletteSwapper/bibliography.ts +16 -0
  11. package/src/tool/pixelArtPaletteSwapper/component.astro +153 -0
  12. package/src/tool/pixelArtPaletteSwapper/entry.ts +28 -0
  13. package/src/tool/pixelArtPaletteSwapper/i18n/de.ts +233 -0
  14. package/src/tool/pixelArtPaletteSwapper/i18n/en.ts +233 -0
  15. package/src/tool/pixelArtPaletteSwapper/i18n/es.ts +233 -0
  16. package/src/tool/pixelArtPaletteSwapper/i18n/fr.ts +233 -0
  17. package/src/tool/pixelArtPaletteSwapper/i18n/id.ts +233 -0
  18. package/src/tool/pixelArtPaletteSwapper/i18n/it.ts +233 -0
  19. package/src/tool/pixelArtPaletteSwapper/i18n/ja.ts +225 -0
  20. package/src/tool/pixelArtPaletteSwapper/i18n/ko.ts +225 -0
  21. package/src/tool/pixelArtPaletteSwapper/i18n/nl.ts +233 -0
  22. package/src/tool/pixelArtPaletteSwapper/i18n/pl.ts +233 -0
  23. package/src/tool/pixelArtPaletteSwapper/i18n/pt.ts +233 -0
  24. package/src/tool/pixelArtPaletteSwapper/i18n/ru.ts +233 -0
  25. package/src/tool/pixelArtPaletteSwapper/i18n/sv.ts +233 -0
  26. package/src/tool/pixelArtPaletteSwapper/i18n/tr.ts +233 -0
  27. package/src/tool/pixelArtPaletteSwapper/i18n/zh.ts +225 -0
  28. package/src/tool/pixelArtPaletteSwapper/index.ts +12 -0
  29. package/src/tool/pixelArtPaletteSwapper/logic.test.ts +43 -0
  30. package/src/tool/pixelArtPaletteSwapper/logic.ts +171 -0
  31. package/src/tool/pixelArtPaletteSwapper/pixel-art-palette-swapper.css +728 -0
  32. package/src/tool/pixelArtPaletteSwapper/seo.astro +15 -0
  33. package/src/tool/pixelArtPaletteSwapper/ui.ts +35 -0
  34. package/src/tool/retroSfxGenerator/client.ts +9 -2
  35. package/src/tool/retroSfxGenerator/logic.test.ts +21 -0
  36. package/src/tool/retroSfxGenerator/logic.ts +1 -1
  37. package/src/tool/retroSfxGenerator/retro-sfx-generator.css +10 -4
  38. package/src/tools.ts +2 -0
@@ -0,0 +1,35 @@
1
+ export interface PixelArtPaletteSwapperUI extends Record<string, string> {
2
+ uploadTitle: string;
3
+ uploadHint: string;
4
+ chooseImage: string;
5
+ replaceImage: string;
6
+ paletteTitle: string;
7
+ gameBoyPalette: string;
8
+ nesPalette: string;
9
+ pico8Palette: string;
10
+ commodore64Palette: string;
11
+ dawnBringerPalette: string;
12
+ customPalette: string;
13
+ customPaletteHint: string;
14
+ applyCustomPalette: string;
15
+ resetCustomPalette: string;
16
+ sourcePreview: string;
17
+ resultPreview: string;
18
+ waitingForImage: string;
19
+ uploadToPreview: string;
20
+ resultEmpty: string;
21
+ downloadPng: string;
22
+ downloadDisabled: string;
23
+ colorCount: string;
24
+ mappedCount: string;
25
+ imageSize: string;
26
+ paletteCount: string;
27
+ preserveAlpha: string;
28
+ zoomLabel: string;
29
+ processing: string;
30
+ invalidPalette: string;
31
+ invalidImage: string;
32
+ readyStatus: string;
33
+ dropActive: string;
34
+ mappedSummary: string;
35
+ }
@@ -37,6 +37,8 @@ if (root) {
37
37
  const frequencyLabel = root.dataset.frequencyLabel ?? 'Frequency';
38
38
  const frequencyEndLabel = root.dataset.frequencyEndLabel ?? 'End frequency';
39
39
  const durationLabel = root.dataset.durationLabel ?? 'Duration';
40
+ const activePresetButton = presetButtons.find((button) => button.classList.contains('is-active'));
41
+ let currentPreset = (activePresetButton?.dataset.preset as SfxPreset | undefined) ?? 'explosion';
40
42
  let params = createDefaultParams();
41
43
  let generated = generateSfx(params);
42
44
  let audioContext: AudioContext | undefined;
@@ -234,6 +236,7 @@ if (root) {
234
236
  presetButtons.forEach((button) => {
235
237
  button.addEventListener('click', () => {
236
238
  const preset = button.dataset.preset as SfxPreset;
239
+ currentPreset = preset;
237
240
  presetButtons.forEach((item) => item.classList.toggle('is-active', item === button));
238
241
  regenerate(getPresetParams(preset));
239
242
  });
@@ -241,9 +244,13 @@ if (root) {
241
244
  playButton?.addEventListener('click', () => void playAudio());
242
245
  stopButton?.addEventListener('click', stopAudio);
243
246
  downloadButton?.addEventListener('click', downloadWav);
244
- randomizeButton?.addEventListener('click', () => regenerate(getPresetParams('laser')));
247
+ randomizeButton?.addEventListener('click', () => {
248
+ regenerate(getPresetParams(currentPreset));
249
+ void playAudio();
250
+ });
245
251
  resetButton?.addEventListener('click', () => {
246
- presetButtons.forEach((item) => item.classList.toggle('is-active', item.dataset.preset === 'laser'));
252
+ currentPreset = 'explosion';
253
+ presetButtons.forEach((item) => item.classList.toggle('is-active', item.dataset.preset === 'explosion'));
247
254
  regenerate(createDefaultParams());
248
255
  });
249
256
  window.addEventListener('resize', drawWaveform);
@@ -1,10 +1,13 @@
1
1
  import { describe, expect, it } from 'vitest';
2
2
  import {
3
3
  calculateEndFrequency,
4
+ createDefaultParams,
4
5
  encodeWav,
5
6
  generateSfx,
6
7
  getPresetParams,
7
8
  updateSweep,
9
+ type SfxPreset,
10
+ type SfxWaveform,
8
11
  } from './logic';
9
12
 
10
13
  describe('retroSfxGenerator logic', () => {
@@ -15,6 +18,24 @@ describe('retroSfxGenerator logic', () => {
15
18
  expect(first.frequencyEnd).toBe(calculateEndFrequency(first.frequency, first.sweep));
16
19
  });
17
20
 
21
+ it('keeps random variations inside the selected preset family', () => {
22
+ const families: Array<[SfxPreset, SfxWaveform]> = [
23
+ ['explosion', 'noise'],
24
+ ['laser', 'sawtooth'],
25
+ ['jump', 'square'],
26
+ ['coin', 'square'],
27
+ ['powerUp', 'triangle'],
28
+ ];
29
+
30
+ families.forEach(([preset, waveform]) => {
31
+ expect(getPresetParams(preset, () => 0.25).waveform).toBe(waveform);
32
+ });
33
+ });
34
+
35
+ it('uses the visible explosion preset as the default family', () => {
36
+ expect(createDefaultParams().waveform).toBe('noise');
37
+ });
38
+
18
39
  it('maps sweep to a bounded end frequency', () => {
19
40
  expect(calculateEndFrequency(440, -1)).toBeGreaterThanOrEqual(40);
20
41
  expect(calculateEndFrequency(440, 1)).toBeLessThanOrEqual(12000);
@@ -87,7 +87,7 @@ export function clamp(value: number, min: number, max: number): number {
87
87
  }
88
88
 
89
89
  export function createDefaultParams(): SfxParams {
90
- return getPresetParams('laser', () => 0.5);
90
+ return getPresetParams('explosion', () => 0.5);
91
91
  }
92
92
 
93
93
  export function getPresetParams(preset: SfxPreset, random: () => number = Math.random): SfxParams {
@@ -12,6 +12,9 @@
12
12
  --rsfx-yellow: #f2c14e;
13
13
  --rsfx-pink: #b0306a;
14
14
  --rsfx-cream: #fff8df;
15
+ --rsfx-on-accent: #fff8df;
16
+ --rsfx-play-bg: #bc4d30;
17
+ --rsfx-download-ink: #211d3d;
15
18
  --rsfx-shadow: #33294d;
16
19
  --rsfx-scope-panel: #f2c14e;
17
20
  --rsfx-scope-screen: #fff3c4;
@@ -50,6 +53,9 @@
50
53
  --rsfx-yellow: #f2c14e;
51
54
  --rsfx-pink: #f477a8;
52
55
  --rsfx-cream: #fff8df;
56
+ --rsfx-on-accent: #101b32;
57
+ --rsfx-play-bg: #ff805c;
58
+ --rsfx-download-ink: #101b32;
53
59
  --rsfx-shadow: #080714;
54
60
  --rsfx-scope-panel: #302555;
55
61
  --rsfx-scope-screen: #101b32;
@@ -206,7 +212,7 @@
206
212
  background: var(--rsfx-cyan);
207
213
  border-color: var(--rsfx-ink-strong);
208
214
  box-shadow: 3px 3px 0 var(--rsfx-shadow);
209
- color: var(--rsfx-cream);
215
+ color: var(--rsfx-on-accent);
210
216
  }
211
217
 
212
218
  .rsfx-preset-glyph {
@@ -356,10 +362,10 @@
356
362
  }
357
363
 
358
364
  .rsfx-action-play {
359
- background: var(--rsfx-orange);
365
+ background: var(--rsfx-play-bg);
360
366
  border: 2px solid var(--rsfx-ink-strong);
361
367
  box-shadow: 3px 3px 0 var(--rsfx-shadow);
362
- color: var(--rsfx-cream);
368
+ color: var(--rsfx-on-accent);
363
369
  }
364
370
 
365
371
  .rsfx-action-stop {
@@ -373,7 +379,7 @@
373
379
  background: var(--rsfx-yellow);
374
380
  border: 2px solid var(--rsfx-ink-strong);
375
381
  box-shadow: 3px 3px 0 var(--rsfx-shadow);
376
- color: var(--rsfx-ink-strong);
382
+ color: var(--rsfx-download-ink);
377
383
  }
378
384
 
379
385
  .rsfx-text-action {
package/src/tools.ts CHANGED
@@ -8,6 +8,7 @@ import { SAVE_FILE_EDITOR_TOOL } from './tool/saveFileEditor';
8
8
  import { LOCALIZATION_SANITIZER_TOOL } from './tool/localizationSanitizer';
9
9
  import { STEAM_BBCODE_TRANSLATOR_TOOL } from './tool/steamBbcodeTranslator';
10
10
  import { RETRO_SFX_GENERATOR_TOOL } from './tool/retroSfxGenerator';
11
+ import { PIXEL_ART_PALETTE_SWAPPER_TOOL } from './tool/pixelArtPaletteSwapper';
11
12
 
12
13
  export const ALL_TOOLS: ToolDefinition[] = [
13
14
  STEAM_CAPSULE_GENERATOR_TOOL,
@@ -18,4 +19,5 @@ export const ALL_TOOLS: ToolDefinition[] = [
18
19
  LOCALIZATION_SANITIZER_TOOL,
19
20
  STEAM_BBCODE_TRANSLATOR_TOOL,
20
21
  RETRO_SFX_GENERATOR_TOOL,
22
+ PIXEL_ART_PALETTE_SWAPPER_TOOL,
21
23
  ];