anderlli0053 Posted September 16 Posted September 16 Hello! I'm trying to extract custom file formats from DOS videogame Cool Spot. Formats are compressed by some modification of RLE compression i think + something else. I'm interested in everything except those 2 DOS binaries/executables(.exe) provided in the archive, since the all of the data is in other files. Cool-Spot_DOS_EN.7z
Engineers Rabatini Posted 5 hours ago Engineers Posted 5 hours ago (edited) On 9/16/2025 at 1:18 PM, anderlli0053 said: Hello! I'm trying to extract custom file formats from DOS videogame Cool Spot. Formats are compressed by some modification of RLE compression i think + something else. I'm interested in everything except those 2 DOS binaries/executables(.exe) provided in the archive, since the all of the data is in other files. Cool-Spot_DOS_EN.7z 573.63 kB · 4 downloads Here the Rle logic. Vertical: std::vector<uint8_t> decompress_type1(const std::vector<uint8_t>& data, int width, int height) { if (width <= 0 || height <= 0) return {}; // Aloca buffer de saída (W * H) // Usamos long long para evitar overflow no calculo do tamanho se as dimensoes forem grandes size_t total_pixels = (size_t)width * (size_t)height; std::vector<uint8_t> output(total_pixels, 0); // Coordenadas para escrita vertical (x, y) int x = 0; int y = 0; size_t data_pos = 0; size_t data_len = data.size(); // Helper para escrever pixel na geometria correta (Vertical: Top->Down, depois Left->Right) auto write_pixel = [&](uint8_t val) { if (x < width && y < height) { output[y * width + x] = val; } y++; if (y >= height) { y = 0; x++; } }; while (data_pos < data_len) { // Se já preencheu a largura total, para if (x >= width) break; uint8_t cmd = data[data_pos++]; if (cmd == 0) break; // Marcador de fim // Verifica bit 7 (0x80): Raw Copy (Literais) if (cmd & 0x80) { int count = (cmd & 0x7F) + 1; for (int i = 0; i < count; ++i) { if (data_pos < data_len) { write_pixel(data[data_pos++]); } } } // RLE (Repetição) else { int count = 0; // Verifica bit 6 (0x40): Contagem estendida (2 bytes) if (cmd & 0x40) { if (data_pos < data_len) { // Remove flags e combina com próximo byte (Little Endian) count = ((cmd & 0x3F) << 8) | data[data_pos++]; } } else { count = cmd; } count += 1; if (data_pos < data_len) { uint8_t val = data[data_pos++]; for (int i = 0; i < count; ++i) { write_pixel(val); } } } } return output; } horizontal std::vector<uint8_t> decompress_type3(const std::vector<uint8_t>& data, int width, int height) { if (width <= 0 || height <= 0) return {}; size_t total_pixels = (size_t)width * (size_t)height; std::vector<uint8_t> output(total_pixels, 0); size_t pos = 0; size_t data_pos = 0; size_t data_len = data.size(); while (data_pos < data_len && pos < total_pixels) { uint8_t cmd = data[data_pos++]; if (cmd == 0) { break; // fim dos dados } if (cmd & 0x80) { // Literais size_t count = (cmd & 0x7F) + 1; for (size_t i = 0; i < count && data_pos < data_len && pos < total_pixels; ++i) { output[pos++] = data[data_pos++]; } } else { // Repetido size_t count = 0; if (cmd & 0x40) { // Contagem estendida if (data_pos >= data_len) break; count = ((cmd & 0x3F) << 8) | data[data_pos++]; } else { count = cmd; } count += 1; if (data_pos >= data_len) break; uint8_t val = data[data_pos++]; for (size_t i = 0; i < count && pos < total_pixels; ++i) { output[pos++] = val; } } } return output; } Edited 3 hours ago by Rabatini
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now