Skip to content

Commit a1c4510

Browse files
committed
1.1.0
1 parent d64c800 commit a1c4510

File tree

7 files changed

+78
-34
lines changed

7 files changed

+78
-34
lines changed

CHANGELOG

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# Changelog
22

3+
## [1.1.0]
4+
- Export spritesheet
5+
36
## [1.0.0]
47
- New engine
58
- Real custom mappings & DPLCs

TODO

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,18 @@
1-
DOC
2-
==
3-
1.0.0 - breaking change to select mapping format
4-
data parser, not text
5-
push project files to disassemblies
6-
7-
BUFFER
8-
==
9-
10-
111
// formats to support
122

133
// crackers
144
// kid chameleon
155
// go back to qiuu with questions
166
// chaotix
177
// s3k sonic saving
18-
// plane mappings / snap to
198
// ristar
209
// github issues
2110
/* https://raw.githubusercontent.com/Dandaman955/Streets-of-Rage-1-Disassembly-Redux/master/SoR.asm */
2211
/* http://info.sonicretro.org/Disassemblies */
2312

2413
ROADMAP
25-
generate project files -> use to create s3portal
14+
look at issues related to crashes
2615
rotsprite
27-
export spritesheet
2816
animation editor
2917
==
3018
BUGS

app/controls/commands.js

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { environment } from '#store/environment';
22
import { mappingState } from '#components/mappings/state';
33
import { importState } from '#components/import/state';
44
import { undo, redo } from '#store/history';
5-
import { exportPNG, importImg } from '#formats/image';
5+
import { exportPNG, importImg, exportSpritesheet } from '#formats/image';
66
import { getDistance } from './distance';
77
import { toJS } from 'mobx';
88

@@ -207,11 +207,15 @@ export const commands = [
207207

208208
[
209209
{
210-
map: 'e', name: 'Export PNG', color: 'blue', noMultiplier: true,
210+
map: 'e', name: 'Export Image', color: 'blue', noMultiplier: true,
211211
func: () => exportPNG(),
212212
},
213213
{
214-
map: 'i', name: 'Import Over Sprite', color: 'blue', noMultiplier: true,
214+
map: 'E', name: 'Export Spritesheet', color: 'blue', noMultiplier: true,
215+
func: () => exportSpritesheet(),
216+
},
217+
{
218+
map: 'i', name: 'Import Image', color: 'blue', noMultiplier: true,
215219
func: () => importImg(),
216220
},
217221
{
@@ -226,7 +230,7 @@ export const commands = [
226230
{
227231
map: 'd s', name: 'Delete Sprite', color: 'red',
228232
func: () => {
229-
const { currentSprite, dplcsEnabled } = environment.config;
233+
const { currentSprite } = environment.config;
230234
environment.mappings.splice(currentSprite, 1);
231235
environment.dplcs.splice(currentSprite, 1);
232236
},
@@ -235,7 +239,7 @@ export const commands = [
235239
map: 'd m', name: 'Delete Mappings', color: 'red',
236240
func: () => {
237241
const { selectedIndices, hasActive } = mappingState;
238-
const { currentSprite, dplcsEnabled } = environment;
242+
const { currentSprite } = environment;
239243
if (hasActive) {
240244
selectedIndices.forEach((i) => {
241245
currentSprite.mappings[i].rip = true;

app/controls/keyboard.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ flatten(commands)
1616

1717
// handle multiplier
1818
let multiplier = '';
19-
Mousetrap.bind(['0','1','2','3','4','5','6','7','8','9'], (e) => {
19+
Mousetrap.bind([...'0123456789'], (e) => {
2020
multiplier += String(e.key);
2121
});
2222
Mousetrap.bind('esc', () => {

app/formats/image.js

Lines changed: 61 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,15 @@ import { writeFile } from 'fs';
44
import { errorMsg } from '#util/dialog';
55
import { colorMatch } from '#components/import/color-match';
66

7-
const debug = false;
7+
function exportSprite({ buffer, mappings }) {
88

9-
export function exportPNG() {
10-
const { currentSprite: { buffer, mappings }, palettesRGB, sprites } = environment;
11-
12-
if (!mappings.length || !sprites.length) return;
9+
const { palettesRGB } = environment;
1310

1411
const canvas = document.createElement('canvas');
15-
if (debug) {
16-
canvas.className = 'canvas-debug';
17-
canvas.style.width = '200px';
18-
document.body.appendChild(canvas);
12+
if (!mappings.length) {
13+
canvas.width = 32;
14+
canvas.height = 32;
15+
return canvas;
1916
}
2017
const ctx = canvas.getContext('2d');
2118
let tileBuffer = ctx.getImageData(0, 0, 8, 8);
@@ -84,10 +81,64 @@ export function exportPNG() {
8481

8582
});
8683

84+
return canvas;
85+
}
86+
87+
88+
export function exportSpritesheet() {
89+
const { sprites } = environment;
90+
if (!sprites.length) return;
91+
92+
const canvases = sprites.map(({ buffer, mappings }) => exportSprite({ buffer, mappings }));
93+
94+
const canvas = document.createElement('canvas');
95+
canvas.width = 8;
96+
canvas.height = 8;
97+
const ctx = canvas.getContext('2d');
98+
// canvas.className = 'canvas-debug';
99+
// document.body.appendChild(canvas);
100+
101+
let cursor = 8;
102+
103+
canvases.forEach(current => {
104+
const last = ctx.getImageData(0, 0, canvas.width, canvas.height);
105+
const { width, height } = current;
106+
const diff = width + 8;
107+
canvas.width += diff
108+
canvas.height = Math.max(canvas.height, height + 8);
109+
ctx.putImageData(last, 0, 0);
110+
ctx.drawImage(current, cursor, 8);
111+
cursor += diff;
112+
});
113+
114+
dialog.showSaveDialog({
115+
title: 'Export Spritesheet',
116+
defaultPath: `spritesheet.png`,
117+
filters: [{name: 'PNG Image', extensions: ['png']}],
118+
})
119+
.then(({ filePath }) => {
120+
if (filePath) {
121+
const base64Data = canvas.toDataURL().replace(/data(.*?),/, '');
122+
writeFile(filePath, Buffer.from(base64Data, 'base64'), (err, success) => {
123+
err && errorMsg('Error exporting spritesheet', String(err));
124+
});
125+
}
126+
})
127+
.catch(console.error);
128+
129+
}
130+
131+
export function exportPNG() {
132+
const { currentSprite: { buffer, mappings }, sprites } = environment;
133+
134+
if (!mappings.length || !sprites.length) return;
135+
136+
const canvas = exportSprite({ buffer, mappings });
137+
87138
dialog.showSaveDialog({
88139
title: 'Export Sprite',
89140
defaultPath: `0x${environment.config.currentSprite.toString(16).toUpperCase()}.png`,
90-
filters: [{name: 'PNG Image File', extensions: ['png']}],
141+
filters: [{name: 'PNG Image', extensions: ['png']}],
91142
})
92143
.then(({ filePath }) => {
93144
if (filePath) {
@@ -98,7 +149,6 @@ export function exportPNG() {
98149
}
99150
})
100151
.catch(console.error);
101-
102152
}
103153

104154
export async function importImg() {
@@ -170,7 +220,6 @@ export async function importImg() {
170220
}
171221

172222
});
173-
174223
}
175224

176225
function flipBuffer(buffer, hflip, vflip) {

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"version": "1.0.0",
2+
"version": "1.1.0",
33
"scripts": {
44
"start": "electron ./static --dev"
55
},

styles/main.scss

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@ a {
5454
.canvas-debug {
5555
position: absolute;
5656
z-index: 10;
57-
bottom: 0;
58-
left: 0;
57+
bottom: 20px;
58+
left: 20px;
5959
image-rendering: pixelated;
6060
background-color: rgba(255,0,0,0.5);
6161
}

0 commit comments

Comments
 (0)