1 package com.tapina.robe.swi.os;
2
3 import com.tapina.robe.runtime.ByteArrayUtils;
4
5 import java.awt.*;
6 import java.awt.image.*;
7
8 /***
9 * Created by IntelliJ IDEA.
10 * User: gareth
11 * Date: Sep 4, 2003
12 * Time: 6:41:10 PM
13 */
14 public final class Sprite {
15 final byte[] data;
16 final String name;
17 final int width;
18 final int height;
19 final int bpp;
20
21 final BufferedImage image;
22
23 public Sprite(byte[] data) {
24 this.data = data;
25
26 name = ByteArrayUtils.getStringN(data, 4, 12);
27
28
29 final int spriteType = ByteArrayUtils.getInt(data, 40);
30 if ((spriteType & 0xf8000000) == 0) {
31 final int mode = (spriteType & 0x0000007f);
32 switch (mode) {
33 case 0:
34 case 4:
35 case 18:
36 case 25:
37 bpp = 1;
38 break;
39 case 1:
40 case 5:
41 case 19:
42 case 26:
43 bpp = 2;
44 break;
45 case 12:
46 case 20:
47 case 27:
48 bpp = 4;
49 break;
50 case 28:
51 bpp = 8;
52 break;
53 default:
54 bpp = 4;
55 }
56 final int firstBit = ByteArrayUtils.getInt(data, 24);
57 final int lastBit = ByteArrayUtils.getInt(data, 28);
58 final int scanLineStride = (ByteArrayUtils.getInt(data, 16) + 1) * 4;
59 width = (scanLineStride * 8 - (firstBit + (31 - lastBit))) / bpp;
60 height = ByteArrayUtils.getInt(data, 20) + 1;
61
62 final SampleModel sm = new MultiPixelPackedSampleModel(DataBuffer.TYPE_BYTE, width, height,
63 bpp, scanLineStride, firstBit);
64 final int spriteOffset = ByteArrayUtils.getInt(data, 32);
65 final int maskOffset = ByteArrayUtils.getInt(data, 36);
66 final DataBuffer dataBuffer = new DataBufferByte(data,
67 scanLineStride * height,
68 spriteOffset);
69 final WritableRaster raster = Raster.createWritableRaster(sm, dataBuffer, new Point());
70
71 final int colours = 1<<bpp;
72 final int[] palette = new int[colours];
73 if (spriteOffset > 44 && maskOffset > 44) {
74
75 for (int i = 0; i < colours; i++) {
76 int acornPaletteEntry = ByteArrayUtils.getInt(data, 44 + i * 8);
77 palette[i] = ACORN_COLOR_MODEL.getRGB(acornPaletteEntry);
78 }
79 }
80 final ColorModel colorModel = new IndexColorModel(bpp, 1<<bpp, palette, 0, true, 0,
81 DataBuffer.TYPE_BYTE);
82 BufferedImage indexedImage = new BufferedImage(colorModel, raster, false, null);
83
84 image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
85 int[] rgbArray = new int[width * height];
86 indexedImage.getRGB(0, 0, width, height, rgbArray, 0, width);
87 image.setRGB(0, 0, width, height, rgbArray, 0, width);
88 } else {
89 throw new RuntimeException("Cannot handle new format sprites");
90 }
91 }
92
93 public final String getName() {
94 return name;
95 }
96
97 private final static DirectColorModel ACORN_COLOR_MODEL =
98 new DirectColorModel(32, 0xff00, 0xff0000, 0xff000000);
99
100
101
102 public final BufferedImage getImage() {
103 return image;
104 }
105 }