Skip to content

Commit e4e85fe

Browse files
committed
(Legacy): added formats.
(GPC): Adv98 engine image format. (PIC): Grocer image format. (PL4): Pearl Soft images. (PAK,QDO): Red-Zone resources.
1 parent 08ab953 commit e4e85fe

File tree

11 files changed

+1088
-4
lines changed

11 files changed

+1088
-4
lines changed

Legacy/Adv98/ImageGPC.cs

Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
//! \file ImageGPC.cs
2+
//! \date 2023 Sep 22
3+
//! \brief Adv98 engine image format (PC-98).
4+
//
5+
// Copyright (C) 2023 by morkt
6+
//
7+
// Permission is hereby granted, free of charge, to any person obtaining a copy
8+
// of this software and associated documentation files (the "Software"), to
9+
// deal in the Software without restriction, including without limitation the
10+
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
11+
// sell copies of the Software, and to permit persons to whom the Software is
12+
// furnished to do so, subject to the following conditions:
13+
//
14+
// The above copyright notice and this permission notice shall be included in
15+
// all copies or substantial portions of the Software.
16+
//
17+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22+
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23+
// IN THE SOFTWARE.
24+
//
25+
26+
using System.ComponentModel.Composition;
27+
using System.IO;
28+
using System.Windows.Media;
29+
using System.Windows.Media.Imaging;
30+
31+
namespace GameRes.Formats.Adv98
32+
{
33+
internal class GpcMetaData : ImageMetaData
34+
{
35+
public long PaletteOffset;
36+
public long DataOffset;
37+
public int Interleaving;
38+
}
39+
40+
[Export(typeof(ImageFormat))]
41+
public class GpcFormat : ImageFormat
42+
{
43+
public override string Tag => "GPC/PC98";
44+
public override string Description => "Adv98 engine image format";
45+
public override uint Signature => 0x38394350; // 'PC98'
46+
47+
public override ImageMetaData ReadMetaData (IBinaryStream file)
48+
{
49+
var header = file.ReadHeader (0x20);
50+
if (!header.AsciiEqual (4, ")GPCFILE \0"))
51+
return null;
52+
uint info_pos = header.ToUInt32 (0x18);
53+
var info = new GpcMetaData
54+
{
55+
Interleaving = header.ToUInt16 (0x10),
56+
PaletteOffset = header.ToUInt32 (0x14),
57+
DataOffset = info_pos + 0x10,
58+
BPP = 4,
59+
};
60+
file.Position = info_pos;
61+
info.Width = file.ReadUInt16();
62+
info.Height = file.ReadUInt16();
63+
file.Position = info_pos + 0xA;
64+
info.OffsetX = file.ReadInt16();
65+
info.OffsetY = file.ReadInt16();
66+
return info;
67+
}
68+
69+
public override ImageData Read (IBinaryStream file, ImageMetaData info)
70+
{
71+
var reader = new GpcReader (file, (GpcMetaData)info);
72+
return reader.Unpack();
73+
}
74+
75+
public override void Write (Stream file, ImageData image)
76+
{
77+
throw new System.NotImplementedException ("GpcFormat.Write not implemented");
78+
}
79+
}
80+
81+
internal class GpcReader
82+
{
83+
IBinaryStream m_input;
84+
GpcMetaData m_info;
85+
int m_stride;
86+
87+
public BitmapPalette Palette { get; private set; }
88+
89+
public GpcReader (IBinaryStream input, GpcMetaData info)
90+
{
91+
m_input = input;
92+
m_info = info;
93+
}
94+
95+
public ImageData Unpack ()
96+
{
97+
m_input.Position = m_info.PaletteOffset;
98+
Palette = ReadPalette();
99+
int plane_stride = (m_info.iWidth + 7) >> 3;
100+
int row_size = plane_stride * 4 + 1;
101+
var data = new byte[row_size * m_info.iHeight];
102+
m_input.Position = m_info.DataOffset;
103+
UnpackData (data);
104+
RestoreData (data, row_size);
105+
m_stride = plane_stride * 4;
106+
var pixels = new byte[m_stride * m_info.iHeight];
107+
ConvertTo8bpp (data, pixels, plane_stride);
108+
return ImageData.Create (m_info, PixelFormats.Indexed4, Palette, pixels, m_stride);
109+
}
110+
111+
void ConvertTo8bpp (byte[] input, byte[] output, int plane_stride)
112+
{
113+
int interleaving_step = m_stride * m_info.Interleaving;
114+
int src_row = 1;
115+
int dst_row = 0;
116+
int i = 0;
117+
for (int y = 0; y < m_info.iHeight; ++y)
118+
{
119+
if (dst_row >= output.Length)
120+
{
121+
dst_row = m_stride * ++i;
122+
}
123+
int p0 = src_row;
124+
int p1 = p0 + plane_stride;
125+
int p2 = p1 + plane_stride;
126+
int p3 = p2 + plane_stride;
127+
src_row = p3 + plane_stride + 1;
128+
int dst = dst_row;
129+
for (int x = plane_stride; x > 0; --x)
130+
{
131+
byte b0 = input[p0++];
132+
byte b1 = input[p1++];
133+
byte b2 = input[p2++];
134+
byte b3 = input[p3++];
135+
for (int j = 0; j < 8; j += 2)
136+
{
137+
byte px = (byte)((((b0 << j) & 0x80) >> 3)
138+
| (((b1 << j) & 0x80) >> 2)
139+
| (((b2 << j) & 0x80) >> 1)
140+
| (((b3 << j) & 0x80) ));
141+
px |= (byte)((((b0 << j) & 0x40) >> 6)
142+
| (((b1 << j) & 0x40) >> 5)
143+
| (((b2 << j) & 0x40) >> 4)
144+
| (((b3 << j) & 0x40) >> 3));
145+
output[dst++] = px;
146+
}
147+
}
148+
dst_row += interleaving_step;
149+
}
150+
}
151+
152+
void UnpackData (byte[] output)
153+
{
154+
int dst = 0;
155+
int ctl = 0;
156+
int ctl_mask = 0;
157+
while (dst < output.Length)
158+
{
159+
if (0 == ctl_mask)
160+
{
161+
ctl = m_input.ReadByte();
162+
if (-1 == ctl)
163+
break;
164+
ctl_mask = 0x80;
165+
}
166+
if ((ctl & ctl_mask) != 0)
167+
{
168+
int cmd = m_input.ReadByte();
169+
for (int cmd_mask = 0x80; cmd_mask != 0; cmd_mask >>= 1)
170+
{
171+
if ((cmd & cmd_mask) != 0)
172+
output[dst++] = m_input.ReadUInt8();
173+
else
174+
++dst;
175+
}
176+
}
177+
else
178+
{
179+
dst += 8;
180+
}
181+
ctl_mask >>= 1;
182+
}
183+
}
184+
185+
void RestoreData (byte[] data, int stride)
186+
{
187+
int src = 0;
188+
for (int y = 0; y < m_info.iHeight; ++y)
189+
{
190+
int interleave = data[src];
191+
if (interleave != 0)
192+
{
193+
byte lastValue = 0;
194+
for (int i = 0; i < interleave; ++i)
195+
{
196+
int pos = 1 + i;
197+
while (pos < stride)
198+
{
199+
data[src + pos] ^= lastValue;
200+
lastValue = data[src + pos];
201+
pos += interleave;
202+
}
203+
}
204+
205+
}
206+
if (y > 0)
207+
{
208+
int prev = src - stride;
209+
int length = (stride - 1) & -4;
210+
for (int x = 1; x <= length; ++x)
211+
{
212+
data[src + x] ^= data[prev + x];
213+
214+
}
215+
}
216+
src += stride;
217+
}
218+
}
219+
220+
BitmapPalette ReadPalette ()
221+
{
222+
int count = m_input.ReadUInt16();
223+
int elem_size = m_input.ReadUInt16();
224+
if (elem_size != 2)
225+
throw new InvalidFormatException (string.Format ("Invalid palette element size {0}", elem_size));
226+
var colors = new Color[count];
227+
for (int i = 0; i < count; ++i)
228+
{
229+
int v = m_input.ReadUInt16();
230+
int r = (v >> 4) & 0xF;
231+
int g = (v >> 8) & 0xF;
232+
int b = (v ) & 0xF;
233+
colors[i] = Color.FromRgb ((byte)(r * 0x11), (byte)(g * 0x11), (byte)(b * 0x11));
234+
}
235+
// colors[0].A = 0; // force transparency
236+
return new BitmapPalette (colors);
237+
}
238+
}
239+
}

Legacy/Blucky/Aliases.cs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
//! \file Aliases.cs
2+
//! \date 2023 Sep 17
3+
//! \brief Blucky formats aliases.
4+
//
5+
// Copyright (C) 2023 by morkt
6+
//
7+
// Permission is hereby granted, free of charge, to any person obtaining a copy
8+
// of this software and associated documentation files (the "Software"), to
9+
// deal in the Software without restriction, including without limitation the
10+
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
11+
// sell copies of the Software, and to permit persons to whom the Software is
12+
// furnished to do so, subject to the following conditions:
13+
//
14+
// The above copyright notice and this permission notice shall be included in
15+
// all copies or substantial portions of the Software.
16+
//
17+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22+
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23+
// IN THE SOFTWARE.
24+
//
25+
26+
using System.ComponentModel.Composition;
27+
28+
// [970627][Blucky] Rekiai
29+
30+
namespace GameRes.Formats.Blucky
31+
{
32+
[Export(typeof(ResourceAlias))]
33+
[ExportMetadata("Extension", "OSA")]
34+
[ExportMetadata("Target", "BMP")]
35+
public class OsaFormat : ResourceAlias { }
36+
37+
[Export(typeof(ResourceAlias))]
38+
[ExportMetadata("Extension", "WF")]
39+
[ExportMetadata("Target", "WAV")]
40+
public class WfFormat : ResourceAlias { }
41+
}

0 commit comments

Comments
 (0)