Last active
September 20, 2022 07:53
-
-
Save bbbradsmith/b21472e912933b08bed6670b2ccbcd88 to your computer and use it in GitHub Desktop.
Ice Kiss (DOS) graphics extractor
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Extracts sprites from the Korean DOS game Ice Kiss | |
# First run icekiss_sprite_file_extract.py to create the sprite bin files | |
# Also, take a screenshot of the gameplay with DOSBox to make a PNG with the correct palette | |
# Then run this to extract graphics from them | |
import PIL.Image | |
screenshot = PIL.Image.open("screenshot.png") # use for palette | |
def decode_file(filename): | |
print(filename) | |
f = open(filename,"rb").read() | |
count = f[0x20] | (f[0x21]<<8) | |
print("%2d images" % (count)) | |
offset = 0x22 | |
last_offset = offset | |
for i in range(count): | |
w = f[offset+0] | (f[offset+1]<<8) | |
h = f[offset+2] | (f[offset+3]<<8) | |
comp = f[offset+4] | |
size = f[offset+5] | (f[offset+6]<<8) | |
print("%2d: %3d x %3d (%d) $%04X @ $%08X" % (i,w,h,comp,size,offset)) | |
img = PIL.Image.new("P",(w,h),255) | |
img.putpalette(screenshot.getpalette()) | |
offset += 0x35 | |
if comp == 0: | |
# uncompressed, non-planar image | |
for y in range(h): | |
for x in range(w): | |
img.putpixel((x,y),f[offset]) | |
offset += 1 | |
else: | |
assert (comp == 1) | |
# each image is split into 4 byteplains (unchained VGA style) | |
# starting at 0,0 in the image, each packet is 2 bytes: | |
# byte A = pixels to skip over | |
# byte B = pixels to copy | |
# followed by B pixels to copy | |
# if byte A = FF this is a "newline" command | |
# after the image height is completed, jump to the next plane of 4 | |
# repeat until the image is full | |
# (rows can be completed in multiple passes) | |
end_offset = offset + size | |
r = 0 | |
x = 0 | |
x_max = 0 | |
x_start = 0 | |
while (offset < end_offset): | |
skip = f[offset] | |
if skip == 0xFF: # "newline" | |
#print("$%08X: %02X" % (offset,skip)) | |
offset += 1 | |
x_max = max(x,x_max) | |
r += 1 | |
if (r %(h*4)) == 0: # multiple passes: resume where previous pass left off? | |
x_start = x_max | |
x = x_start | |
continue | |
raw = f[offset+1] | |
#print("$%08X: %02X + %02X = %d" % (offset,skip,raw,skip+raw)) | |
offset += 2 | |
x += skip | |
p = (r // h) % 4 | |
dy = r % h | |
for j in range(raw): | |
dx = (x*4)+p | |
assert (dx < w) | |
img.putpixel((dx,dy),f[offset]) | |
offset += 1 | |
x += 1 | |
fo = "%s.%02d.png" % (filename,i) | |
print("%-30s ($%4X bytes)" % (fo,offset - last_offset)) | |
img.save(fo) | |
# advance to next image | |
end_offset = offset | |
new_offset = last_offset + size + 0x35 | |
if end_offset != new_offset: | |
print("Skipped bytes at: %08X - %08X" % (end_offset,new_offset)) | |
offset = new_offset | |
last_offset = offset | |
print("done.") | |
for i in range(0,10): | |
decode_file("Sprite.%d.bin" % (i)) | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Extracts packed graphics files from Korean DOS game Ice Kiss | |
# (Files are packed within ICEKISS.EXE) | |
exe = open("ICEKISS.EXE","rb").read() | |
s = "O2 Object Sprite".encode("ASCII") | |
fo = [] | |
for i in range(len(exe)): | |
for j in range(len(s)): | |
if i+j > len(exe): break | |
if s[j] != exe[i+j]: break | |
if j == len(s)-1: | |
fo.append(i) | |
print("$%08X" % (i)) | |
print(fo) | |
print(s) | |
for i in range(len(fo)): | |
si = fo[i] | |
ei = len(exe) | |
if i+1 < len(fo): | |
ei = fo[i+1] | |
f = exe[si:ei] | |
open("Sprite.%1d.bin" % (i),"wb").write(f) | |
print("done") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment