diff --git a/CREDITS b/CREDITS index edd4511..a50c45e 100644 --- a/CREDITS +++ b/CREDITS @@ -10,7 +10,7 @@ N: Robert Vokac E: mail@robertvokac.com -W: https://nanoboot.org -P: 4096R/E3329055 322B D109 0AA8 C324 EA9C 72F5 693D 30BE E332 9055 +W: https://robertvokac.com +P: 4096R/C459E1E4 B209 C3F1 25C7 2618 FB18 AC8E C459 E1E4 B4A9 86BB D: Founder S: Czech Republic diff --git a/src/main/java/org/nanoboot/spriteutils/core/SpriteSheet.java b/src/main/java/org/nanoboot/spriteutils/core/SpriteSheet.java index 8ea2e23..32432f9 100644 --- a/src/main/java/org/nanoboot/spriteutils/core/SpriteSheet.java +++ b/src/main/java/org/nanoboot/spriteutils/core/SpriteSheet.java @@ -1,7 +1,22 @@ -/* - * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license - * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template - */ +/////////////////////////////////////////////////////////////////////////////////////////////// +// sprite-utils: Tool used to work with sprites +// Copyright (C) 2024 the original author or authors. +// +// This program is free software: you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation, either version 3 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see +// or write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +/////////////////////////////////////////////////////////////////////////////////////////////// package org.nanoboot.spriteutils.core; import java.io.File; @@ -9,6 +24,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Optional; import lombok.Data; import lombok.ToString; @@ -29,83 +45,93 @@ public class SpriteSheet { public SpriteSheet(File file) { List rows = new ArrayList<>(); String text = Utils.readTextFromFile(file); - text.lines().skip(1).takeWhile(l->!l.contains("skipskip")) + text.lines().skip(1).takeWhile(l -> !l.contains("skipskip")) .forEach(l -> { - final SpriteSheetRow spriteSheetRow = new SpriteSheetRow(l); + processLine(l, rows); + }); + saveComputedFile(file, text, rows); - if (lastSpriteSheetRow != null) { - if (!spriteSheetRow.file.equals(lastSpriteSheetRow.file)) { - lastSpriteSheetRow = null; - } - } - if (lastSpriteSheetRow == null) { - spriteSheetRow.numberPerSheet = 1; - if (spriteSheetRow.getRow() != 1) { - String msg = "Row of the first sprite in file must be equal to 1, but value for file " + spriteSheetRow.file + " is " + spriteSheetRow.getRow(); - throw new SpriteUtilsException(msg); - } - if (spriteSheetRow.getColumn() != 1) { - String msg = "Column of the first sprite in file must be equal to 1, but value for file " + spriteSheetRow.file + " is " + spriteSheetRow.getColumn(); - throw new SpriteUtilsException(msg); - } + } - } else { - spriteSheetRow.numberPerSheet = lastSpriteSheetRow.numberPerSheet + 1; - - if(spriteSheetRow.row > lastSpriteSheetRow.row) { - if(spriteSheetRow.row != (lastSpriteSheetRow.row + 1)) { - throw new SpriteUtilsException("Unexpected row for " + spriteSheetRow.createId()); - } - } - if(spriteSheetRow.row < lastSpriteSheetRow.row) { - throw new SpriteUtilsException("Unexpected row for " + spriteSheetRow.createId()); - } - - if(spriteSheetRow.row == lastSpriteSheetRow.row) { - if(spriteSheetRow.column != (lastSpriteSheetRow.column + 1)) - throw new SpriteUtilsException("Unexpected column for " + spriteSheetRow.createId()); - } - } - rows.add(spriteSheetRow); - if (!map.containsKey(spriteSheetRow.file)) { - map.put(spriteSheetRow.file, new ArrayList<>()); - } - map.get(spriteSheetRow.file).add(spriteSheetRow); - if (spriteSheetRow.x == -1) { - if (spriteSheetRow.column == 1) { - spriteSheetRow.x = 0; - } else { - if (lastX == -1) { - throw new SpriteUtilsException("Could not compute X for " + spriteSheetRow.createId()); - } else { - spriteSheetRow.x = lastX + lastWidth; - } - } - } - lastX = spriteSheetRow.getX(); - lastWidth = spriteSheetRow.getWidth(); - if (spriteSheetRow.height <= 0) { - if (lastHeight == -1) { - throw new SpriteUtilsException("Could not compute height for " + spriteSheetRow.createId()); - } else { - spriteSheetRow.height = lastHeight + ((-1) * spriteSheetRow.height); - } - } - lastHeight = spriteSheetRow.height; - lastSpriteSheetRow = spriteSheetRow; - System.out.println(spriteSheetRow.toCsvLine()); - }); + private void saveComputedFile(File file, String text, List rows) { File computed = new File(file.getAbsolutePath() + ".computed.csv"); - if(computed.exists()){ + if (computed.exists()) { computed.delete(); } StringBuilder sb = new StringBuilder(text.lines().limit(1).findFirst().orElse("")); sb.append("\n"); - rows.stream().forEach(r-> { - sb.append(r.toCsvLine()).append("\n"); + rows.stream().forEach(r -> { + sb.append(r.toCsvLine()).append("\n"); }); Utils.writeTextToFile(sb.toString(), computed); + } + private void processLine(String line, List rows) throws SpriteUtilsException { + final SpriteSheetRow spriteSheetRow = new SpriteSheetRow(line); + + validateRow(spriteSheetRow); + + updateSpriteSheetRow(spriteSheetRow); + + rows.add(spriteSheetRow); + updateMap(spriteSheetRow); + System.out.println(spriteSheetRow.toCsvLine()); + } + + private void updateSpriteSheetRow(final SpriteSheetRow spriteSheetRow) { + if (spriteSheetRow.x == -1) { + spriteSheetRow.x = (spriteSheetRow.column == 1) ? 0 + : Optional.of(lastX == -1 ? null : (lastX + lastWidth)).orElseThrow(() -> new SpriteUtilsException("Could not compute X for " + spriteSheetRow.createId())); + } + lastX = spriteSheetRow.getX(); + lastWidth = spriteSheetRow.getWidth(); + + if (spriteSheetRow.height <= 0) { + spriteSheetRow.height = Optional.of((lastHeight != -1) ? (lastHeight + (-spriteSheetRow.height)) : null).orElseThrow(() -> new SpriteUtilsException("Could not compute height for " + spriteSheetRow.createId())); + } + lastHeight = spriteSheetRow.height; + lastSpriteSheetRow = spriteSheetRow; + } + + private void updateMap(final SpriteSheetRow spriteSheetRow) { + if (!map.containsKey(spriteSheetRow.file)) { + map.put(spriteSheetRow.file, new ArrayList<>()); + } + map.get(spriteSheetRow.file).add(spriteSheetRow); + } + + private void validateRow(final SpriteSheetRow spriteSheetRow) { + if (lastSpriteSheetRow != null) { + if (!spriteSheetRow.file.equals(lastSpriteSheetRow.file)) { + lastSpriteSheetRow = null; + } + } + if (lastSpriteSheetRow == null) { + validateFirstRow(spriteSheetRow); + + } else { + validateSubsequentRow(spriteSheetRow); + } + } + + private void validateSubsequentRow(SpriteSheetRow spriteSheetRow) { + spriteSheetRow.numberPerSheet = lastSpriteSheetRow.numberPerSheet + 1; + if (spriteSheetRow.row > lastSpriteSheetRow.row) { + if (spriteSheetRow.row != (lastSpriteSheetRow.row + 1)) { + throw new SpriteUtilsException("Unexpected row for " + spriteSheetRow.createId()); + } + } else if (spriteSheetRow.row < lastSpriteSheetRow.row) { + throw new SpriteUtilsException("Unexpected row for " + spriteSheetRow.createId()); + } else if (spriteSheetRow.column != (lastSpriteSheetRow.column + 1)) { + throw new SpriteUtilsException("Unexpected column for " + spriteSheetRow.createId()); + } + } + + private void validateFirstRow(SpriteSheetRow spriteSheetRow) { + if (spriteSheetRow.getRow() != 1 || spriteSheetRow.getColumn() != 1) { + throw new SpriteUtilsException("Invalid initial row or column for file " + spriteSheetRow.file); + } + spriteSheetRow.numberPerSheet = 1; } public List getSpriteSheets(String file) { diff --git a/src/main/java/org/nanoboot/spriteutils/core/SpriteSheetRow.java b/src/main/java/org/nanoboot/spriteutils/core/SpriteSheetRow.java index b413496..5ff3e88 100644 --- a/src/main/java/org/nanoboot/spriteutils/core/SpriteSheetRow.java +++ b/src/main/java/org/nanoboot/spriteutils/core/SpriteSheetRow.java @@ -17,13 +17,11 @@ // or write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. /////////////////////////////////////////////////////////////////////////////////////////////// + package org.nanoboot.spriteutils.core; import java.util.Arrays; import java.util.List; -import java.util.stream.Collector; -import java.util.stream.Collectors; -import java.util.stream.Stream; import lombok.Data; import lombok.ToString; @@ -50,19 +48,21 @@ public class SpriteSheetRow { public SpriteSheetRow(String csvLine) { String[] csvColumn = csvLine.split(";"); + if (csvColumn.length < 10) { + throw new IllegalArgumentException("CSV line does not contain enough (10) columns."); + } int i = 0; file = csvColumn[i++]; group = csvColumn[i++]; - numberInGroup = Integer.valueOf(csvColumn[i++]); - row = Integer.valueOf(csvColumn[i++]); - column = Integer.valueOf(csvColumn[i++]); - String xString = csvColumn[i++]; - x = xString.isBlank() ? -1 : Integer.valueOf(xString); - y = Integer.valueOf(csvColumn[i++]); - width = Integer.valueOf(csvColumn[i++]); - height = Integer.valueOf(csvColumn[i++]); + numberInGroup = Integer.parseInt(csvColumn[i++]); + row = Integer.parseInt(csvColumn[i++]); + column = Integer.parseInt(csvColumn[i++]); + x = csvColumn[i++].isBlank() ? -1 : Integer.parseInt(csvColumn[i - 1]); + y = Integer.parseInt(csvColumn[i++]); + width = Integer.parseInt(csvColumn[i++]); + height = Integer.parseInt(csvColumn[i++]); if (column > 1) { - height = height * (-1); + height = -height; } notes = csvColumn.length >= 10 ? csvColumn[i++] : ""; tags = csvColumn.length > 11 ? csvColumn[i++] : ""; @@ -72,9 +72,10 @@ public class SpriteSheetRow { return file + __ + group + __ + numberInGroup; } private static final String __ = "__"; + private static final String DELIMITER = ";"; public String toCsvLine() { - List l = Stream.of( + List fields = Arrays.asList( file, group, String.valueOf(numberInGroup), @@ -86,9 +87,9 @@ public class SpriteSheetRow { String.valueOf(height), notes, tags, - String.valueOf(numberPerSheet)).toList(); - return l.stream().collect(Collectors.joining(";")); - + String.valueOf(numberPerSheet) + ); + return String.join(DELIMITER, fields); } }