Skip to content

Instantly share code, notes, and snippets.

@deckarep
Created June 28, 2024 17:34
Show Gist options
  • Save deckarep/d6e0f0884a22c8a4a4b9392155f9dad0 to your computer and use it in GitHub Desktop.
Save deckarep/d6e0f0884a22c8a4a4b9392155f9dad0 to your computer and use it in GitHub Desktop.
Extracts all .wav audio from Leisure Suit Larry Casino - originally written by @Doomlazer
# Original credit: @doomlazer
# https://github.com/Doomlazer/TrivialQuest/blob/main/audio/jokes/ExtractWavs.py
# Extract wav files from Larry's Casino audio.vol
# Sound effects can also be dumped from resources.vol
# jokes are 71.wav - 183.wav
#
# command to convert wav to mp3:
# for f in *.wav; do ffmpeg -i "$f" "${f%.wav}.mp3"; done
import struct
AUDIO_DEST_FOLDER = "extracted_audio/"
def dump_audio(from_file):
fnum = 0
with open(from_file, "rb") as f:
while (byte := f.read(1)):
if byte == b'\x52' and f.read(1) == b'\x49' and f.read(1) == b'\x46' and f.read(1) == b'\x46':
print("Found RIFF starting at: ", f.tell()-4)
size = struct.unpack('<i', f.read(4))[0]
print("wav size: ", size)
f.seek(-8, 1)
wav = f.read(size+8)
s = AUDIO_DEST_FOLDER + str(fnum) + "_" + from_file + ".wav"
fnum=fnum+1
nf = open(s, 'bw+')
nf.write(wav)
nf.close()
# Extract music + sfx.
dump_audio("resource.vol")
# Extract cast voice audio.
dump_audio("audio.vol")
@deckarep
Copy link
Author

All good @Doomlazer - I'm updating these notes so I don't lose track of my findings and for you to also know when you feel up to the task but please tackle this at your discretion.

@deckarep
Copy link
Author

This has admittedly turned into a full blown obsession for me...still have stuff to work out that I don't fully understand but i've managed to get Peter looking a lot more like Peter. 😁

0

@Doomlazer
Copy link

Damn, that is nearly there! Keep going!

@deckarep
Copy link
Author

Thank you for the encouragement, I think i'm almost there...this is insane as I've never cracked something like this before...there's no magic to it other than me tediously counting pixels, offsets and trying to figure out these damn patterns. Another thing I've been doing is reading all the variations of RLE encoding in the wild but so far nothing really seems to match up with how this game does it.

I wish there was a better way.

0

@Doomlazer
Copy link

AFAIK, that is the way all reverse engineering is done. It's a combination of research and mostly trial and error based on hunches. If it were easy, it would have already been done.

It's extremely satisfying once you crack it though. It's like finding the WOPR backdoor, only 100x better because you didn't just guess a password. Based on that last pic you are very close, though there might be more to learn about the other images in the resource.

I have a feeling you'll get it this weekend, which is very exciting!

@deckarep
Copy link
Author

Time for a celebration: 🎊🔥⚡️🍾🚀

Still left to do:

  • Try other sprites and hopefully eliminate any further edge cases
  • Work on the sub-sprites (rows/columns theory) to get them to render out
  • Upload to Github this code so it can be improved and shared
  • Primary goal is to extract the character sprites during LC gameplay
  • Secondary goals would be get all room backgrounds and GUI sprites, but I don't really need this for my poker game

LarryCasinoSpritesReversedBanner

I credited you because you helped get the scripts started and you were instrumental in bouncing ideas off of, so a big thank you @Doomlazer!

@Doomlazer
Copy link

Doomlazer commented Jul 20, 2024

Grats, that's awesome! I'm excited to see the RLE algorithm.

You have to list yourself first in the credits for finally breaking it.

@deckarep
Copy link
Author

Thanks, here's the not-so-secret-sauce: https://github.com/deckarep/laffer-casino-extractor

@deckarep
Copy link
Author

@Doomlazer - would you be okay with also getting your .wav/jokes extractor in this repo for completion?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment