132 lines
5.4 KiB
C
Executable File
132 lines
5.4 KiB
C
Executable File
/// _ _
|
|
/// __ ___ __ _ __(_) |_ ___
|
|
/// \ \/ / '_ \| '__| | __/ _ \
|
|
/// > <| |_) | | | | || __/
|
|
/// /_/\_\ .__/|_| |_|\__\___|
|
|
/// |_|
|
|
///
|
|
/// Copyright (c) 1997 - Ognjen 'xolatile' Milan Robovic
|
|
///
|
|
/// xolatile@chud.cyou - xprite - Custom file format for semi-efficient and very fast encoding and decoding of simple images.
|
|
///
|
|
/// This program is free software, free as in freedom and as in free beer, 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 any later version if you wish...
|
|
///
|
|
/// This program is distributed in the hope that it will be useful, but it is probably not, and without any warranty, without even the implied
|
|
/// warranty of merchantability or fitness for a particular purpose, because it is pointless. Please see the GNU (Geenoo) General Public License
|
|
/// for more details, if you dare, it is a lot of text that nobody wants to read...
|
|
|
|
static unsigned integer sprite_colour [128] = {
|
|
0x00000000, 0xff222222, 0xff444444, 0xff666666, 0xff888888, 0xffaaaaaa, 0xffcccccc, 0xffeeeeee,
|
|
0x11000000, 0xff000022, 0xff000044, 0xff000066, 0xff000088, 0xff0000aa, 0xff0000cc, 0xff0000ee,
|
|
0x22000000, 0xff002200, 0xff004400, 0xff006600, 0xff008800, 0xff00aa00, 0xff00cc00, 0xff00ee00,
|
|
0x33000000, 0xff220000, 0xff440000, 0xff660000, 0xff880000, 0xffaa0000, 0xffcc0000, 0xffee0000,
|
|
0x44000000, 0xff002222, 0xff004444, 0xff006666, 0xff008888, 0xff00aaaa, 0xff00cccc, 0xff00eeee,
|
|
0x55000000, 0xff222200, 0xff444400, 0xff666600, 0xff888800, 0xffaaaa00, 0xffcccc00, 0xffeeee00,
|
|
0x66000000, 0xff220022, 0xff440044, 0xff660066, 0xff880088, 0xffaa00aa, 0xffcc00cc, 0xffee00ee,
|
|
0x77000000, 0xff001122, 0xff002244, 0xff003366, 0xff004488, 0xff0055aa, 0xff0066cc, 0xff0077ee,
|
|
0x88000000, 0xff110022, 0xff220044, 0xff330066, 0xff440088, 0xff5500aa, 0xff6600cc, 0xff7700ee,
|
|
0x99000000, 0xff002211, 0xff004422, 0xff006633, 0xff008844, 0xff00aa55, 0xff00cc66, 0xff00ee77,
|
|
0xaa000000, 0xff112200, 0xff224400, 0xff336600, 0xff448800, 0xff55aa00, 0xff66cc00, 0xff77ee00,
|
|
0xbb000000, 0xff220011, 0xff440022, 0xff660033, 0xff880044, 0xffaa0055, 0xffcc0066, 0xffee0077,
|
|
0xcc000000, 0xff221100, 0xff442200, 0xff663300, 0xff884400, 0xffaa5500, 0xffcc6600, 0xffee7700,
|
|
0xdd000000, 0xff112222, 0xff224444, 0xff336666, 0xff448888, 0xff55aaaa, 0xff66cccc, 0xff77eeee,
|
|
0xee000000, 0xff222211, 0xff444422, 0xff666633, 0xff888844, 0xffaaaa55, 0xffcccc66, 0xffeeee77,
|
|
0xff000000, 0xff221122, 0xff442244, 0xff663366, 0xff884488, 0xffaa55aa, 0xffcc66cc, 0xffee77ee
|
|
};
|
|
|
|
static generic * sprite_import (character * path, integer * width, integer * height) {
|
|
unsigned character check_width = 0;
|
|
unsigned character check_height = 0;
|
|
|
|
integer file, move;
|
|
|
|
unsigned integer * data = null;
|
|
|
|
file = file_open (path, file_flag_read);
|
|
|
|
file_read (file, & check_width, (integer) sizeof (check_width));
|
|
file_read (file, & check_height, (integer) sizeof (check_height));
|
|
|
|
* width = (integer) check_width;
|
|
* height = (integer) check_height;
|
|
|
|
fatal_failure ((* width) == 0, "sprite_import: Invalid sprite width.");
|
|
fatal_failure ((* height) == 0, "sprite_import: Invalid sprite height.");
|
|
|
|
data = allocate ((* width) * (* height) * (integer) sizeof (* data));
|
|
|
|
for (move = 0; move < (* width) * (* height); ++move) {
|
|
integer colour = 0;
|
|
integer repeat = 0;
|
|
|
|
file_read (file, & colour, 1);
|
|
|
|
if ((colour & 0x80) == 0) {
|
|
data [move] = sprite_colour [colour];
|
|
} else {
|
|
integer offset;
|
|
|
|
file_read (file, & repeat, 1);
|
|
|
|
colour &= 0x7f;
|
|
repeat += 1;
|
|
|
|
for (offset = 0; offset < repeat; ++offset) {
|
|
data [move + offset] = sprite_colour [colour];
|
|
}
|
|
|
|
move += repeat - 1;
|
|
}
|
|
}
|
|
|
|
file = file_close (file);
|
|
|
|
return (data);
|
|
}
|
|
|
|
static procedure sprite_export (character * path, integer width, integer height, unsigned integer * data) {
|
|
integer file, move;
|
|
|
|
file = file_open (path, file_flag_edit | file_flag_truncate | file_flag_create);
|
|
|
|
fatal_failure ((width <= 0) || (width >= 256), "sprite_export: Invalid sprite width.");
|
|
fatal_failure ((height <= 0) || (height >= 256), "sprite_export: Invalid sprite height.");
|
|
|
|
file_write (file, & width, 1);
|
|
file_write (file, & height, 1);
|
|
|
|
for (move = 0; move < width * height; ++move) {
|
|
integer colour = 0;
|
|
integer repeat = 0;
|
|
|
|
for (repeat = 1; (move + repeat < width * height) && (data [move] == data [move + repeat]) && (repeat < 256); ++repeat);
|
|
|
|
for (colour = 0; (data [move] != sprite_colour [colour]) && (colour < 128); ++colour);
|
|
|
|
if (colour == 128) colour = 127;
|
|
|
|
if (repeat == 1) {
|
|
file_write (file, & colour, 1);
|
|
} else {
|
|
colour |= 0x80;
|
|
repeat -= 1;
|
|
move += repeat;
|
|
|
|
file_write (file, & colour, 1);
|
|
file_write (file, & repeat, 1);
|
|
|
|
}
|
|
}
|
|
|
|
file = file_close (file);
|
|
}
|
|
|
|
static procedure sprite_swap_channels (unsigned integer * data, integer width, integer height) {
|
|
integer move;
|
|
|
|
for (move = 0; move < width * height; ++move) {
|
|
data [move] = (data [move] & 0xff00ff00) | ((data [move] & 0xff0000) >> 16) | ((data [move] & 0xff) << 16);
|
|
}
|
|
}
|