~nordfriese/freerct/debian-building

« back to all changes in this revision

Viewing changes to utils/GenerateSpritesheet.java

  • Committer: Benedikt Straub
  • Date: 2021-07-01 16:54:22 UTC
  • Revision ID: benedikt_straub-20210701165422-kwxa3y9ga23kirrr
Initial commit (da71e14)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * This file is part of FreeRCT.
 
3
 * FreeRCT 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, version 2.
 
4
 * FreeRCT 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.
 
5
 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with FreeRCT. If not, see <http://www.gnu.org/licenses/>.
 
6
 */
 
7
 
 
8
import java.awt.image.*;
 
9
import java.io.*;
 
10
import javax.imageio.ImageIO;
 
11
 
 
12
/**
 
13
 * This program provides an easy way to generate spritesheets for ride animations from individual (blender) images.
 
14
 * Let's assume you've made an animation with `f` frames for a ride with a size of `x` × `y` tiles.
 
15
 * The base images, all of which are of size `w` × `h`, are located in `src_dir`.
 
16
 * The images are called "PREFIX0000.png" through "PREFIX9999.png", where `PREFIX` may be different for each of the four rotations
 
17
 * (let's call the prefixes `se`,`ne`,`nw`,`sw` in this order). The number of the
 
18
 * animation's starting frame is `idOff_<p>` for each of the four prefixes <p>.
 
19
 *
 
20
 * To generate the spritesheet and save it as `output_file`, run
 
21
 *    java GenerateSpritesheet src_dir output_file idOff_se se idOff_ne ne idOff_nw nw idOff_sw sw f x y w h TIMA
 
22
 *
 
23
 * The last parameter declares which indexing algorithm to use. The indexing algorithm decides at which coordinates
 
24
 * in the resulting spritesheet each input image should be located. See below for available indexing algorithms.
 
25
 *
 
26
 * Before running the program the first time you need to run
 
27
 *    javac GenerateSpritesheet.java
 
28
 */
 
29
 
 
30
public class GenerateSpritesheet {
 
31
        public static enum IndexingAlgorithm {
 
32
                /** Arranges the individual images in the way expected by the TIMA and FSET node generators. */
 
33
                TIMA,
 
34
                /** Just put one sprite after the other, without considering rotations or other fancy processing. */
 
35
                PLAIN,
 
36
        }
 
37
 
 
38
        public static void main(String[] args) throws Exception {
 
39
                System.out.println("Usage: java GenerateSpritesheet src_dir output_file idOff_se se idOff_ne ne idOff_nw nw idOff_sw sw nr_frames x y w h indexer");
 
40
                int arg_index = 0;
 
41
                final String src = args[arg_index++];
 
42
                final String result = args[arg_index++];
 
43
                final String[] prefixes = new String[4];
 
44
                final int[] idOff = new int[4];
 
45
                for (int i = 0; i < prefixes.length; ++i) {
 
46
                        idOff[i] = Integer.valueOf(args[arg_index++]);
 
47
                        prefixes[i] = args[arg_index++];
 
48
                }
 
49
                final int frames = Integer.valueOf(args[arg_index++]);
 
50
                final int sprites_x = Integer.valueOf(args[arg_index++]);
 
51
                final int sprites_y = Integer.valueOf(args[arg_index++]);
 
52
                final int sprite_w = Integer.valueOf(args[arg_index++]);
 
53
                final int sprite_h = Integer.valueOf(args[arg_index++]);
 
54
                final IndexingAlgorithm indexer = IndexingAlgorithm.valueOf(args[arg_index++]);
 
55
 
 
56
                BufferedImage out = new BufferedImage(frames * sprite_w * sprites_x, sprite_h * sprites_y * 4, BufferedImage.TYPE_INT_ARGB);
 
57
                for (int f = 0; f < frames; ++f)
 
58
                for (int v = 0; v < 4; ++v)
 
59
                for (int x = 0; x < sprites_x; ++x)
 
60
                for (int y = 0; y < sprites_y; ++y)
 
61
                {
 
62
                        int tileIndex = Integer.MIN_VALUE;
 
63
                        switch (indexer) {
 
64
                                case TIMA:
 
65
                                        switch (v) {
 
66
                                                case 0:
 
67
                                                case 1:
 
68
                                                        tileIndex = x * sprites_y + sprites_y - y - 1;
 
69
                                                        break;
 
70
                                                case 2:
 
71
                                                case 3:
 
72
                                                        tileIndex = y + sprites_y * (sprites_x - x - 1);
 
73
                                                        break;
 
74
                                        }
 
75
                                        break;
 
76
                                case PLAIN:
 
77
                                        tileIndex = y * sprites_x + x;
 
78
                                        break;
 
79
                                default:
 
80
                                        System.out.println("Invalid indexing algorithm " + indexer);
 
81
                                        System.exit(1);
 
82
                        }
 
83
                        final int imageID = idOff[v] + f + frames * tileIndex;
 
84
                        String filename = "" + imageID;
 
85
                        while (filename.length() < 4) filename = "0" + filename;
 
86
                        filename = prefixes[v] + filename + ".png";
 
87
                        System.out.println(String.format("[x=%d y=%d v=%d f=%d idx=%d] Loading %s %s", x, y, v, f, tileIndex, src, filename));
 
88
                        BufferedImage in = ImageIO.read(new File(src, filename));
 
89
                        if (in.getWidth() != sprite_w || in.getHeight() != sprite_h) {
 
90
                                System.out.println("Wrong height");
 
91
                                System.exit(1);
 
92
                        }
 
93
                        final int xpos = f * sprite_w * sprites_x + x * sprite_w;
 
94
                        final int ypos = v * sprite_h * sprites_y + y * sprite_h;
 
95
                        for (int i = 0; i < sprite_w; ++i)
 
96
                        for (int j = 0; j < sprite_h; ++j)
 
97
                        out.setRGB(xpos + i, ypos + j, in.getRGB(i, j));
 
98
                }
 
99
                ImageIO.write(out, "png", new File(result));
 
100
                System.out.println("Success!");
 
101
        }
 
102
}