The FM Project (Steely Dan Tribute Band)
📅 Date & Time
5/9/2025 at 20:00
📍 Venue
Beachland Ballroom
🎟️Tickets: ticketweb.com/event/the-fm-pro…#event #BeachlandBallroom #EastSide #Free #Cleveland #HelloCleveland #bot
Shit Show Karaoke
📅 Date & Time
4/30/2025 at 22:00
📍 Venue
B Side Lounge
Every wednesdayShitshow Karaoke - Every Wednesday at B Side Lounge with Wallace, Manny and Whip!Same Shit. Different Day.10pm-CloseFree | 21+Thank you for your continued support in these strange times.
🎟️Tickets: ticketweb.com/event/shit-show-…#event #BSideLounge #EastSide #Free #Cleveland #HelloCleveland #bot
Bug Moment / Garden Home / Skwerm / Bitch Fear
📅 Date & Time
4/6/2025 at 20:00
📍 Venue
Happy Dog
🎟️Tickets: app.opendate.io/e/bug-moment-g…#event #HappyDog #WestSide #Free #Cleveland #HelloCleveland #bot
Bug Moment / Garden Home / Skwerm / Bitch Fear
It's a night midwest punk, emo, and more featuring Milwaukee's Bug Moment and Garden Home, plus locals Skwerm and Bitch Fear!app.opendate.io
Alex Kumin
📅 Date & Time
4/19/2025 at 18:30
📍 Venue
Hilarities 4th Street Theater
Alex Kumin is an NYC based comedian by way of Chicago and Boston whose bold and whip smart standup delights crowds across the US. She can be seen performing nightly in New York City and is a favorite at The Comedy Cellar and New York Comedy Club. You...
🎟️Tickets: hilarities.com/shows/301473#event #Hilarities4thStreetTheater #Downtown #Cleveland #HelloCleveland #bot
DEVO: 50 Years of De-Evolution... continued!
📅 Date & Time
5/11/2025 at 20:00
📍 Venue
TempleLive Cleveland Masonic
The mezzanine and balcony are accessible only by stairs. All ages
🎟️Tickets: ticketmaster.com/devo-50-years…#event #TempleLiveClevelandMasonic #EastSide #Cleveland #HelloCleveland #bot
Alex Kumin
📅 Date & Time
4/18/2025 at 18:30
📍 Venue
Hilarities 4th Street Theater
Alex Kumin is an NYC based comedian by way of Chicago and Boston whose bold and whip smart standup delights crowds across the US. She can be seen performing nightly in New York City and is a favorite at The Comedy Cellar and New York Comedy Club. You...
🎟️Tickets: hilarities.com/shows/301471#event #Hilarities4thStreetTheater #Downtown #Cleveland #HelloCleveland #bot
NIIS
📅 Date & Time
4/26/2025 at 20:00
📍 Venue
No Class
NIISPollyanna TrussPretty Pretty Awfulâ128;148;â128;148;â128;148;Main Stage ShowDoors: 8pmCost: $15 ADV / $18 DOSAge Limit: All Ages (+$5 Under 21)PRESALE TICKETSRSVP ON FACEBOOK
🎟️Tickets: noclasscle.com/events/niis#event #NoClass #WestSide #Cleveland #HelloCleveland #bot
NIIS — NO CLASS
NIIS Pollyanna Truss Pretty Pretty Awful ——— Main Stage Show Doors: 8pm Cost: $15 ADV / $18 DOS Age Limit: All Ages (+$5 Under 21) PRESALE TICKETS RSVP ON FACEBOOKNO CLASS
Bill McRae Group @ BOP STOP
📅 Date & Time
4/13/2025 at 20:00
📍 Venue
BOP STOP
Join us for the return of the Bill McRae Group at BOP STOP! The performance includes songs by Lee Morgan, Hank Mobley, Don Grolnick, The Brecker Brothers, Steps Ahead, Bob...
🎟️Tickets: themusicsettlement.org/events/…#event #BOPSTOP #DownTown #Cleveland #HelloCleveland #bot
Overview | Bill McRae Group @ BOP STOP | Sunday, April 13, 2025 | The Music Settlement
Join us for the return of the Bill McRae Group at BOP STOP! The performance includes songs by Lee Mo...The Music Settlement
The Bouncing Souls
📅 Date & Time
4/26/2025 at 18:00
📍 Venue
The Agora
East Coast! F#ck You Tour
🎟️Tickets: axs.com/events/833125/the-boun…#event #TheAgora #EastSide #Cleveland #HelloCleveland #bot
Easter Brunch with Marys Lane
📅 Date & Time
4/20/2025 at 12:00
📍 Venue
Music Box
Marys Lane is rock, and reel, but most of all, the good times roll. Their Cleveland Rock roots are evident, but they are knee deep in the ghosts of Ireland – not maudlin mind you, but in the typical Kitchen Party made so famous by the Irish &nd...
🎟️Tickets: etix.com/ticket/p/46320041/eas…#event #MusicBox #Downtown #Cleveland #HelloCleveland #bot
NON-MONOGAMY MIXER + TRIVIA
📅 Date & Time
4/6/2025 at 14:00
📍 Venue
No Class
Come test your knowledge, make new connections, and enjoy an afternoon of fun at our Non-Monogamy Social Trivia Event! This is the perfect space to celebrate and explore non-monogamous relationships in a laid-back setting, queer friendly setting.What...
🎟️Tickets: noclasscle.com/events/non-mono…#event #NoClass #WestSide #Free #Cleveland #HelloCleveland #bot
Amigo the Devil (Solo)
📅 Date & Time
5/10/2025 at 20:30
📍 Venue
Beachland Ballroom
AT BEACHLAND BALLROOMGrog Shop Presents: Amigo The Devil (Solo) LIVE at Beachland Ballroom with Tele Novella and David TalleySaturday, May 10thDoors 7:30pm / Show 8:30pmAll Ages$27.50 advance / $32 day of showAmigo The DevilIn the vast realm of moder...
🎟️Tickets: ticketweb.com/event/amigo-the-…#event #BeachlandBallroom #EastSide #Cleveland #HelloCleveland #bot
THE SAMMY DELEON AND JACKIE WARREN QUARTET, WITH KIP REED & CHRIS BURGE
📅 Date & Time
4/6/2025 at 19:30
📍 Venue
B Side Lounge
The Sammy Deleon and Jackie Warren Quartet, featuring: Kip Reed and Chris Burge Live at the B Side Lounge7:00 doors / 7:30 show21+$10 SAMMY DELEONSammy DeLeon is one of the most recognized timbales players in Northeast Ohio and a fixture in the regio...
🎟️Tickets: ticketweb.com/event/the-sammy-…#event #BSideLounge #EastSide #Cleveland #HelloCleveland #bot
Lyrical Rhythms
📅 Date & Time
4/8/2025 at 20:00
📍 Venue
B Side Lounge
Open Mic & ChillEvery Tuesday at B-Side Liquor LoungeDOORS: 7:00 | COMEDY: 8:00 | OPEN MIC: 10:00P$5 ADV/Until 9P | $10 at the doorCheck out 2 DRINKS & A JOKE with your host, Ant Morrow from 8:00-10:00.Sections available for larger groups.Thank you f...
🎟️Tickets: ticketweb.com/event/lyrical-rh…#event #BSideLounge #EastSide #Cleveland #HelloCleveland #bot
Lachlan MacKinnon Annual Memorial Show, Wrong Places, OONGOW!!!, Whatever..., Strange Notes, Public Squares
📅 Date & Time
4/25/2025 at 20:00
📍 Venue
Beachland Ballroom
To Benefit Jeff Deasy's Daughter Larkins' Schooling
🎟️Tickets: ticketweb.com/event/lachlan-ma…#event #BeachlandBallroom #EastSide #Free #Cleveland #HelloCleveland #bot
"You wasn't There" A 2000's Musical!
📅 Date & Time
4/5/2025 at 22:00
📍 Venue
B Side Lounge
10:00 PM - 2:00AM21+A 2000s Dance Party Experience brought to you by Brent Roach Events and The King Lou Experience! Prepare to dance all night long as we take you on a music journey through the 2000s
🎟️Tickets: ticketweb.com/event/you-wasnt-…#event #BSideLounge #EastSide #Cleveland #HelloCleveland #bot
Circuit Des Yeux, LEYA
📅 Date & Time
4/18/2025 at 20:00
📍 Venue
Beachland Tavern
🎟️Tickets: ticketweb.com/event/circuit-de…#event #BeachlandTavern #EastSide #Free #Cleveland #HelloCleveland #bot
Infusion: Blending Jazz and Indian Classical Music @ BOP STOP
📅 Date & Time
5/8/2025 at 20:00
📍 Venue
BOP STOP
Join us for an evening of celebrating a collaboration between Indian classical musicians and area jazz musicians. Led by pianist, Leo Coach, Infusion brings together voices from Northeast Ohio and...
🎟️Tickets: themusicsettlement.org/events/…#event #BOPSTOP #DownTown #Cleveland #HelloCleveland #bot
Overview | Infusion: Blending Jazz and Indian Classical Music @ BOP STOP | Thursday, May 08, 2025 | The Music Settlement
Join us for an evening of celebrating a collaboration between Indian classical musicians and area ja...The Music Settlement
Ricky Exton's Octo-Jazz @ BOP STOP
📅 Date & Time
4/6/2025 at 20:00
📍 Venue
BOP STOP
Ricky Exton's OctoÂ-Jazz is a fun yet sophisticated group of 8 musician's paying homage to some of the great Jazz arrangers including but not limited to the "West Coast" or...
🎟️Tickets: themusicsettlement.org/events/…#event #BOPSTOP #DownTown #Cleveland #HelloCleveland #bot
Overview | Ricky Exton's Octo-Jazz @ BOP STOP | Sunday, April 06, 2025 | The Music Settlement
Ricky Exton's Octo-Jazz is a fun yet sophisticated group of 8 musician's paying homage to some ...The Music Settlement
Make Em Laugh Mondays Hosted By Kevin Ford
📅 Date & Time
4/7/2025 at 20:00
📍 Venue
Grog Shop
Doors 7:30 PM | Showtime 8 PM18+Make Em Laugh Mondays hosted by Kevin Ford Full line-up TBAGet tickets in advance for $5 or at the door for $10facebook.com/MakeEmLaughMonday…
🎟️Tickets: ticketweb.com/event/make-em-la…#event #GrogShop #EastSide #Cleveland #HelloCleveland #bot
Make Em Laugh Mondays at Grog Shop
Make Em Laugh Mondays at Grog Shop. 422 likes. Comedy clubwww.facebook.com
R.A.P. Ferreira, Blax
📅 Date & Time
4/17/2025 at 20:00
📍 Venue
Beachland Tavern
🎟️Tickets: ticketweb.com/event/rap-ferrei…#event #BeachlandTavern #EastSide #Free #Cleveland #HelloCleveland #bot
The Brian Papesh Party Band-Dyngus Day Celebration: 2025 Collinwood Jazz Festival
📅 Date & Time
4/21/2025 at 19:00
📍 Venue
Treelawn Music Hall
The Brian Papesh Party Band has performed at many private parties, weddings, dances, and community events throughout greater Cleveland and the surrounding area since the 80s. This seasoned group of professional musicians plays a great mix of party mu...
🎟️Tickets: ticketweb.com/event/the-brian-…#event #TreelawnMusicHall #EastSide #Free #Cleveland #HelloCleveland #bot
90's Rockfest Featuring Lounge Fly (Stone Temple Pilots Tribute) & Evil Empire (Rage Against The Machine Tribute)
📅 Date & Time
5/3/2025 at 20:00
📍 Venue
The Winchester
90s Rockfest - Featuring Lounge Fly (Stone Temple Pilots Tribute) & Evil Emprire (Rage Against The Machine Tribute)Saturday, May 3rd, 2025Doors 7pm / Show 8pm$20 ADV / $25 DOS
🎟️Tickets: ticketweb.com/event/90s-rockfe…#event #TheWinchester #WestSide #Cleveland #HelloCleveland #bot
Octave Cat, YAM YAM
📅 Date & Time
4/18/2025 at 20:00
📍 Venue
Beachland Ballroom
🎟️Tickets: ticketweb.com/event/octave-cat…#event #BeachlandBallroom #EastSide #Free #Cleveland #HelloCleveland #bot
United We Dance: The Ultimate Rave Experience
📅 Date & Time
4/25/2025 at 21:00
📍 Venue
House of Blues Cleveland
This event is age restricted to 18+, valid ID required. Doors open at 9:00pm. Music begins at 9:30pm. This event is general admission, standing room only. Immerse yourself in the Ultimate Rave Experience; an electrifying night of EDM hits, immersive ...
🎟️Tickets: concerts.livenation.com/united…#event #HouseofBluesCleveland #EastSide #Cleveland #HelloCleveland #bot
2 FAST 2 FIESTA: A 2000s LATIN NIGHT
📅 Date & Time
4/12/2025 at 21:00
📍 Venue
B Side Lounge
NDVST presents: 2 FAST 2 FIESTA: A 2000s LATIN NIGHT at B Side!Rev your engines for a Y2K party thats bumpin the biggest 2000s Latin hits from OGs like Pitbull and Daddy Yankee to our queens Shakira and Nelly Furtado! B-Side Lounge - Cleveland Saturd...
🎟️Tickets: ticketweb.com/event/2-fast-2-f…#event #BSideLounge #EastSide #Cleveland #HelloCleveland #bot
Shit Show Karaoke
📅 Date & Time
4/9/2025 at 22:00
📍 Venue
B Side Lounge
Every wednesdayShitshow Karaoke - Every Wednesday at B Side Lounge with Wallace, Manny and Whip!Same Shit. Different Day.10pm-CloseFree | 21+Thank you for your continued support in these strange times.
🎟️Tickets: ticketweb.com/event/shit-show-…#event #BSideLounge #EastSide #Free #Cleveland #HelloCleveland #bot
Anvil w/ Don Jamieson & Midnite Hellion
📅 Date & Time
5/8/2025 at 19:00
📍 Venue
The Winchester
Anvil wsg/ Don Jamieson & Midnite HellionThursday, May 8th, 2025Doors 6pm / Show 7pm $20 ADV / $25 DOS
🎟️Tickets: ticketweb.com/event/anvil-w-do…#event #TheWinchester #WestSide #Cleveland #HelloCleveland #bot
Read about the best things to see and do here. How do you like Nikko? backpackandsnorkel.com/Nikko/
Travel Guide for Nikko - Japan Purple Travel Guide
Nikko is a popular tourist destination in the mountains north of Tokyo. We show you the best things to see in Nikko and, as always, we provide lots of photos so you can decide where you want to go.Backpack and Snorkel Travel Guides - The Home of the Purple Travel Guides
The good thing about not having an active security clearance is that there is no king that can take it away from you.
youtube.com/watch?v=B4YMdS2fPF…
Judiciary Goes NUCLEAR After Trump’s Savage Attack on Top Law Firm
Harry reports on outrage following Trump's intense attack on a top law firm–TALKING FEDS PODCAST is a roundtable discussion that brings together prominent fo...YouTube
Remember when the fascists running our government told us they would only go after "dangerous" people?
This 10 year old recovering from brain cancer, on their way to a medical appointment, wants a word.
nbcnews.com/news/latino/us-cit…
U.S. citizen child recovering from brain cancer deported to Mexico with undocumented parents
The Texas family was on their way to an emergency medical checkup, they said, when they were detained at an immigration checkpoint.Nicole Acevedo (NBC News)
[05:18] Hamas welcomes apparent US retreat on Gazan expulsions
Hamas spokesperson Hazem Qassem welcomed US President Donald Trump's apparent retreat from his proposal for a permanent displacement of Palestinians from Gaza, urging him to refrain from aligning with the vision of the "extreme Zionist right".
rte.ie/news/world/2025/0313/15…
#Hamas #HazemQassem #US #DonaldTrump #Palestinians #Gaza #Zionist
Hamas welcomes apparent US retreat on Gazan expulsions
Hamas spokesperson Hazem Qassem welcomed US President Donald Trump's apparent retreat from his proposal for a permanent displacement of Palestinians from Gaza, urging him to refrain from aligning with the vision of the "extreme Zionist right".RTÉ News (RTÉ)
[05:04] Donald Trump nods along as Taoiseach passes the US test
Both the US and Irish sides played their parts in yesterday's proceedings, but US President Donald Trump did seem to have a genuine soft spot for the Irish. Time will tell what that means for Ireland's future.
rte.ie/news/us/2025/0313/15017…
#US #Irish #yesterday #DonaldTrump #Ireland
Donald Trump nods along as Taoiseach passes the US test
Both the US and Irish sides played their parts in yesterday's proceedings, but US President Donald Trump did seem to have a genuine soft spot for the Irish. Time will tell what that means for Ireland's future.Sean Whelan (RTÉ)
I made a thing.
In deep into finishing up the survival guide for Adventure! The Quack of Dawn. In the manual I have included images of characters from the demo game for the tutorial, and other things.
I am not an artist. However, I can manipulate images. So, as I don’t have a budget for art, I’m rolling my own combining public domain images and filters in Gimp. I briefly considered using generated images but believe it’s an abuse of fair use.
Here’s an image I created. It’s a lot of effort.
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Funny fact: I was trying to get an online assembler to spit out the machine code for "int 1a" but couldn't get it to, so I just went "fuck it, I can probably just do that in my head!"
Turns out I can. My brain is weird.
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •PRONOUNS DETECTED: THIS GAME IS WOKE
sadly they don't have they/them on here. What about the non-binary criminals, huh?
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •I think I might be able to do the hack I want by changing one byte.
I'm trying to change it so it has "daily challenges", and I think I can fix that by just switching a INT 1A from subfunction 00 to 04, making it seed the random function with the date instead of the ticks-since-midnight
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •NORMAL CODE
random(*(byte *)*(undefined2 *)
(*(int *)(*(int *)0x39a6 * 0xe + local_c * 2 + 0x1d02) * 2 +
*(int *)(local_c * 2 + 0x24b)) - 1);
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •male: 0
female: 4
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •why? because they have strings like:
char* HE="He\0\0She\0"
char* HIS="His\0Hers\0";
char* HIM="Him\0Her\0";
so they can do like:
printf("Follow %s to %s lair, and capture %s alive!", badguy->name, HIS+badguy->gender, HIM+badguy->gender);
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Player's don't have genders. Only thieves have genders.
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •why does ghidra's "search by instruction pattern" default to BINARY?
what kind of a freak remembers the machine code for INT 21 on x86 in BINARY?
it's CD21h, not 1100110100100001!
what are you, some kind of nerd?
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •I love reversing a string and it's:
void printString(char* str, int length);
and I go look what calls it, reverse that function, and it's:
void printStringSimple(char *str){
printString(str, strlen(str));
}
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •it's like "aww, did someone have second thoughts about making PRINT always take a length, and got tired of having to manually calculate lengths so you just wrapped it?
and your compiler didn't inline SHIT?
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •0-31: where the shit was stolen from
0-2: which item it is from that location
0-8: whodunnit
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •For the second one, it's:
0: mask of Priam
1: Achilles's heel
2: sibyl's secret.
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •It's got 1 added to it so you won't get Carmen Sandiego, as a rookie at least.
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •so the game uses a pattern like this:
char * RANKS="Rookie\0Sleuth\0Private Eye\0Investigator\0Ace Detective\0"
and then latter they do:
char* your_rank = select_string(RANKS, player->rank);
and select_string is a confusing function to reverse engineer, but knowing the name I gave it gives it away: it advances through the list until it's on the nth string and returns it
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Ghidra is officially sexist. It'll automatically detect the word "Female" and mark it as a string, but not the word "Male"!
Why? SEXISM!
or the fact the default minimum length for strings is 5 characters, so "female" is long enough but "male" isn't.
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •they have invented a Pronoun Markup Language.
It's \x80 for He/She
It's \x81 for he/she
It's \x82 for his/her
so a string will be "\x80 mentioned \x81 liked seafood and offered me a ride in \x82 motorcycle"
and it'll fill it out based on the pronouns of the suspect
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •in trying to hack myself into the game, it glitched and said I had "Hobby: Male"
no... I haven't done that in ages!
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •so in addition to the 5 listed attributes (and their name), the game tracks one hidden attribute:
food preference.
There are only two options:
00=Mexican
01=Seafood
what an odd binary
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •You could always do, like, "Where in Middle Earth is Carmen Sandiego?"
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •so when the game starts, it loads:
ACME.DAT
CARMEN.DAT
MIDISND.DAT
DIGISND.DAT
CITIES.DAT
Interestingly, it uses the same code to load the last three, suggesting they're some kind of basic container format
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •this blit function seems to take a useless first argument, a second argument that's the height, a third argument that's the width, and a fourth argument that doesn't seem to do anything.
notice anything missing? like... a lot of things?
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •this game uses a fun text encoding method: both-ended null terminated!
It stores city names with a nul at the beginning because it reads them backwards. For some fucking reason.
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •they seek to position X
read 1 byte
read 99 more bytes
then seek to position X+100
now if you know how both math and random access files work, you'll realize something the programmers of Where in the World is Carmen Sandiego? Enhanced (1990, DOS) did not:
THEY'RE SEEKING TO THE POSITION THEY'RE ALREADY AT
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •the way this game does the investigations is interesting.
so the basic gameplay is that you're in location X, you get 3 hints, which lead you to location Y, where the whole process repeats.
But if you savescum to experience the same pursuit again, they'll always go through the same places... but if you don't get the hints, they won't be there.
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Hah! the game apparently calculates some info ahead of time, but only a few steps. I changed who the suspect was by memory editing, and it didn't take effect... until I got to the third location.
Since I went from a robbery by Fast Eddie B to one by Merey LaRoc, it means the pronouns changed when I got to London.
Congrats on coming out as a trans woman, Merey.
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •ahh good. it's always fun to find code that looks like:
do{
while(variable!=0);
some one has a custom tick handler that's permutating a global!
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •looking at interrupts, and I think I found a bug.
they set handlers for various CPU errors, but they accidentally set 10 (COPROCESSOR ERROR) twice, instead of the 05 (BOUND check)/10 (COPRPOCESSOR) interrupts they save
someone copy-pasted and missed a bit
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •I finally found the two helper functions they use to get and set vectors!
all the 30 other places I've seen them set/get vectors, they do it manually, but hey, maybe they use the helpers too
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •presumably it's each song and then some config info?
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •cities.dat is very interesting. There's 30 cities in total, but 491 entries in it!
So they must be doing something odd there, that doesn't divide equally. Maybe one city-chunk gives IDs of the others?
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •darn. turns out you can't just renumber the chunks, because they have to be in increasing order.
so maybe I just need to leave the chunk indexes as is, and instead of moving the entries around, I move where they're pointing?
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Bingo! I'm in Athens, but I'm seeing the image for Baghdad, and apparently with the Baghdad palette?
So one of these other chunks must be the palette for a city. Or it selects from a selection of palettes? Maybe they've just got a couple defined.
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •okay I figured out the cities.dat IDs:
They're all 1XXYY (in decimal):
XX is the city number (0-29), YY is the sub-chunk-id.
So like:
YY=0: City name
YY=2: City image.
They go between 00 and 22, and not all numbers need to be present.
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •hmm, reading a buffer and then summing all the values of the bytes in it.
suspicious behavior.
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •I can't make the math work but I'm reasonably sure that's what it is
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Instant Video display.
I don't know exactly how DOSBox-X is doing it, but while single-stepping the debugger, the display never updates. I can dump the ram at A000:0000 and see what updated, but not on the screen in DOSBox
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •found a suspicious array, which goes:
[
(-1,0),
(-1,1),
(0,1),
(1,1),
(1,0),
(1,-1),
(0, -1),
(-1,-1),
(0,0)
]
POP QUIZ: why does the font renderer need this array? how are they being "lazy" with this array?
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Sensitive content
there's also this code in the for-loop that steps through this array:
if index==8:
color=white
else:
color=black
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Sensitive content
@dividuum got it:
they're drawing the font 9 times, offset in each of the 8 directions, and in black. then they draw it in white, with no offset.
It's a pixel-outliner! By drawing their pixel font offset in each direction, they get a black outline on their font.
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •The Answer to the DRM questions for Where in the world is Carmen Sandiego? Enhanced (DOS, 1990) are, in no particular order:
23
Kent
dragon
calcium
1796
Warren
revenue
1792
Willard
1937
Crater
Tanzania
Hartford
Duluth
London
Gem
Silent
squeaker
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •if ((0x80 >> ((byte)local_4 & 7) &
(int)(char)*(byte *)((int)((int *)param_1 + 1) + (local_4 >> 3))) != 0) {
COULD YOU USE SOME MORE CASTS MAYBE?
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •oh it's because ghidra's near/far pointer support is shit.
I had param2 defined as a byte*32 and it was casting it to a byte* before using it
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •well I found the decompression method.
as always, I hate it. decompression routines are probably my least favorite thing to reverse engineer
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •it looks like this chunk has length 256, which means 253 usable bytes, and it expands to 374 bytes.
Not the greatest compression. a little better than just doing 6-bit ASCII.
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •it's some kind of shifting bit mask but it starts at encoding values in 4 bits, then it can increase (or decrease, I guess) based on the input stream.
then it has an output filter, where if the number specified wasn't 8 bits, it's actually an index into a predefined text table
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •aetonisrdlhugfcwypbmk,vSA.T'PMxBCIRGDWHqE-zNFKL0j:51YJ8\U?73Q;2!469
\r\nOVXZ()*+"#$%&<=>/@[]^_`
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •"\x03Lima is Peru's capital and largest city. A well-known landmark is the Archbishop's Palace, a reminder of Peru's colonial past\x00Peru is slightly smaller than Alaska and is bordered by Ecuador, Colombia, Brazil, Bolivia and Chile\x00Peru, once the center of the mighty Incan Empire, is a rugged land dominated by the Andes Mountains. Forests and jungles cover half its land area\x00"
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •it was a trivial off-by-one error.
I was doing saved_byte=input
[3]but while I needed the 3rd byte, that's at input[2]
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •yess!
C:\DOSBox-X\drive_c\carmen\py>python datfile.py cities.dat --dump=12803 --decompress
"\x03Sydney, with a population of more than 3.3 million people, is Australia's largest city. A well-known sight is Sydney's distinctively designed Opera House\x00An island continent, Australia is nearly as large as the United States but has only one-fifteenth the population\x00The capital of Australia is Canberra, located in the southeast corner of the country between Sydney and Melbourne\x00"
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •okay now that I can decode the chunks (well, most of them) I can identify a lot more of them:
00 Name and (some other info)
01 ???
02 Image
03 City descriptions
04 Items to steal
10 ???
11&up: Hints leading here
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •So like, the 12 chunk for Tokyo says:
b'\x05asked about the exchange rate for yen\x00was practicing Japanese characters\x00said\x81planned to take photographs of Mount Fuji\x00asked about tours of the Imperial Palace\x00was interested in visiting Shinto shrines\x00'
So it picks from one of those 5 options
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •b'\x02asked questions about Shinto rituals\x00said\x81was researching an archipelago\x00'
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •a "live" version of binxelview, so I can step through the DOSBox-x debugger and see how memory is changing in real time, as an image.
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •That's odd, because it means it had to rewrite the image in memory, the image it's about to unload.
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •I hit a breakpoint in the debugger, I turn it on, set another breakpoint, and hit go.
between those two breakpoints, every time a CALL instruction is hit, it dumps my selected memory region. If it's identical to the last dump, it's ignored.
At the end, each dump is rendered as an image, and the combined set are an animation I can scroll through.
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •it's in a function I already found, temporarily named "blit_related".
I guess they don't decode the image until RIGHT before it needs to go up on the screen!
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Strange!
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •write the byte 04 every 69 bytes
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •oh sweet jesus, that's the left two pixels of the image.
it's loading the image vertically!
at least it's top to bottom.
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •yeah, doom did that too, but Doom was a 2.5D image that had to do pseudo-raycasting.
THIS GAME DOES NOT
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •it allocates a 1024 byte buffer, then makes a pointer to the end of it, minus -0x42?
why would you need a link to the end of a new, freshly cleared buffer, minus 62?
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •unless it's an odd number, in which case it's a free block. and pointer to the previous block, once you make it even again
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •You see this little About dialog box? Guess how many times the DrawText function is called?
Once! and just to draw "Where in the World is Carmen Sandiego?".
The rest of the text is draw elsewhere, and I have no idea why.
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •The game loads the BoldFont first, then the SmallFont, then the NormalFont.
Annoyingly this isn't how they're laid out in memory:
It's SmallFont, then BoldFont, then NormalFont
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •font_alloc = malloc(local_a);
if (font_alloc == (void *)0x0) {
font_alloc = (void *)0x0;
}
Ahh yes. remember, if you get a null pointer back from malloc(), make sure to set that variable to NULL so it won't be left as... NULL?
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •man, running on 4 hours of sleep is killing me.
I can't even remember the MS-DOS interrupt to open a file!
I know reading it is int 21 ah=3f, closing it is int 21 ah=3d, and I'll never forget that seeking is int 21 ah=42, but how do you open a file?
I mean, not the int 21 ax=6c00 way, that one is only for DOS 4.0+, and obviously a game released in 1990 isn't gonna use that.
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •ahh, now that I've looked it up, it seems I was wrong!
closing isn't 3D, that's 3E! 3D is open!
no wonder I couldn't remember it, I had it confused with another call
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •what the fuck do you mean that carmen.dat is opened on the first call to finish_draw_maybe()?
like, I know there's a "maybe" in that name, but it's not THAT big of a maybe.
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •it actually LoadDatFile, which makes a HELL of a lot more sense
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •maybe do it for everything MS-DOS.
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •I think I failed to load the cursor, which caused it to corrupt the mouse cursor catastrophically
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •I did a little looking into the contents of MIDISND.DAT
It's got 12 small tracks, and each of them is a valid MIDI file if you remove the first byte.
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •heh. I was checking different near-death animations by overriding the randomness, so I had to tell my debugger to set AX to 0
guess which animation that is? The one with the AXe.
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •why do they store the day of the week as a 16bit int?
future proofing in case the calendar gets updated and has more than 256 days in the week?
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •They're in Rome and they've just slept through about two months of nothing
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •I finally figured out how it calculates travel times.
It's the difference in X coordinate between the two cities, plus the difference between the Y coordinate, plus one.
that quantity divided by 40, then has 2 added. if the result is over 7, it's set to 7.
Weird! that's not how you measure distance, Carmen.
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •also, it's the 90s, I can afford a sqrt().
I should fix it up for my version.
or use a squared lookup table. you could do this REAL easy by making it a table search: there's only 6 possible results: 2,3,4,5,6,7. each entry in the lookup table contains the maximum squared distance that can generate that number of hours
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •here's all 30 city locations:gist.github.com/foone/09925178…
it's currently way too 6am to do more calculations, though. I'll do that tomorrow
Carmen Sandiego city locations
GistFoone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Good news: @modulusshift did the calculations for me!
digipres.club/@modulusshift/11…
~ (@modulusshift@digipres.club)
digipres.clubFoone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •PUSH ES
PUSH AX
RETF
why must you hurt me, carmen sandiego?
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •So the GraphicsMode enum goes:
0: MCGA
1: CGA
2: Hercules
3: EGA
4: Tandy
5: VGA
6: ???
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •I find-replaced the background from palette entry 0 to palette entry C:
Now I can confirm how big this image is. Previously it was set into a black background, which made it harder
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •worst thing that could happen just happened:
I just realized the portable Where in the World is Carmen Sandiego? is based on the same version I'm hacking, meaning it's in-scope for me to get this, dump the ROM, and compare.
That just increased the cost and complexity of this project by bunch
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •WAIT HOLD ALL THE PHONES.
Here's a photo from a MS-DOS version. It does that thing some companies (like Sierra) did back in the day, and included both 3.5" and 5.25" disks in the package.
BUT WHY ARE THERE SO MANY DISKS?
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •ARG, they mislabeled this.
Admittedly, this isn't really their fault, this is confusing shit.
This is the 1992 Where in the World Is Carmen Sandiego? Deluxe, not the 1990 Where in the World Is Carmen Sandiego? Enhanced.
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •okay I finally found a boxed copy of the Enhanced 1990 DOS edition. (confusingly labeled the 1993 edition)
It comes on two 5.25" disks: presumably double-density, so that's 720kb in total.
Floppy Disk Pop Quiz: What's weird about these floppies, specifically given that this is MS-DOS version?
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •I happened to look at mobygames, and noticed two interesting things.
First, the Mac version is very similar to the DOS version, other than the expected changes you'd get from it being on a monochrome system with a GUI.
But wow, that's a completely different font! Is that built into macs or something? (EDIT: @amr confirms it is)
(also, the dialogue box is top-aligned. DOS bottom-aligns them)
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •The PC has basically always been double-sided, so they only need one notch, on the top/a side.
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Broderbund was releasing games on a bunch of other systems that DID have single-sided drives. For simplicity they just bought Xty-thousand double-notched disks
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •is it gonna matter? not in the slightest (assuming there's no format-mismatching, which their shouldn't be: these are all the same density of disks, I think).
The PC doesn't check for a notch there, so it won't notice either.
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •It's just funny because this is, like, technically wrong?. These aren't PC disks, but the difference doesn't matter, so why not?
It probably saved them a decent amount of money because of bulk discounts and inventory simplicity.
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •I am currently, as in this very thread, reverse engineering Carmen Sandiego Enhanced (1990, DOS)!
I've seen the code that asks for you to put in the other disk! And it only asks for DISK1 and DISK2!
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •just looking at the files, not the code (and not having seen original disk images yet that I can recall), I bet the answer is that they put CITIES.DAT on DISK2.
the whole game - cities.dat is ~300kb, with cities.dat being 168kb.
They could do the whole game - carmen.dat and cities.dat in only 200kb, which'd give them 160kb (luxury!) for a fancy installer.
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •I should just check. I'm sure disk images can be tracked down in places.
the video and audio detection seems to be excellent, by the way. it just silently figures it out, without asking questions or requiring special arguments or configuration.
Perfect for a game aimed at the little childrens.
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •I found two different copies of the disk images, in different places.
both are imaged off a 3.5" disk version, which of course comes on only one (double density, 720kb) disk!
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •So I've got code at 17DA:08AA, which is E8 5D F7. DOSBox decodes that as CALL 000A.
Manually decoding it myself, it should be a relative jump, and it's a jump to $-0x8a3. following the jump it ends up at 17DA:000A.
BUT GHIDRA thinks this code is at 1fb7:08aa, and it decodes it as call SUB_2000_fb7a, which doesn't exist.
I'm not sure how (0x08aa+3)-0x8a3 = 2000:fb7a. Something weird is going on. Why is the number BIGGER?
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •eww. They're using the NEAR version of CALL to call a FAR procedure.
You might say "wait, won't that break when it tries to do RETF?" and yes, it would, unless they manually do PUSH CS before they call it!
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •a call FAR absolute would be 5 bytes for the call, whereas push CS + call NEAR is 3+1 bytes
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Anyway it seems it doesn't have a VideoDetect function, it's a DriverDetect function, since it's used for sound too.
First it goes through the video drivers in the following order:
VGA, TGA, EGA, HGA, HERC, and CGA.
Then it goes into the audio drivers:
stdsnd, adlib, covox, gblast, ibmg, sblast, tandy.
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •stdsnd is pc speaker,
adlib is adlib, covox is the speech thing, gblast is game blaster, most likely, ibmg is... I'm not sure. The PS-1 Audio card?
sblash is soundblaster and tandy is tandy 3-voice
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •I'm an idiot, this isn't a driver check... it's an argv check!
you can pass "ega" or "vga" or whatever to carmen.exe to select those types.
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •the other argument you can pass is ROSTER=$FILENAME
This lets you reset which file it uses for the list of registered players, setting it to something other than the default ACME.DAT
Not mentioned in the manual, but I can see how that might be useful for schools and such
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •The problem is that ghidra gets confused when the relative addresses are too big.
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •so the first one is at 1000:0000 and the second was at 1fb7:0009. I moved it to 5000:7000, and the second segment seems to be working fine now.
the problem is that I was only able to do that because the segment is only 82a7h long. the first segment, the 1000:0000 one, is FB79 long. So I can't just move it so it's in the middle of a segment, since it'll end up spanning into the next 64k chunk, which is where ghidra fucks up
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •9000:8006 9a d7 05 b7 1f CALLF SUB_2000_0147
Hey ghidra I can read the machine code. That's CALL FAR 1fb7:05d7, not CALL FAR 2000:0147! WHY ARE YOU CONFUSED BY THIS?
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •so now I can just manually thunk every cross-segment call, by creating the 2000:0000 segment that ghidra is imagining exists
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •I was extracting the portraits of the people you talk to, and it turns out they're number 1-36. naturally I checked all 256 possible options.
but it turns out every thing above 37 either:
1. crashes
2. shows nothing
3. shows pixel gibberish.
EXCEPT 238. 238 renders a bellhop perfectly, just like 5 does
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •it has been zero days since Ghidra has done something I can't understand and seems to be obviously wrong.
I've got B8 B0 26: this decodes to mov ax, 0x26b0. a 16bit immediate, moving into a 16bit register.
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •ghidra disassembles this as:
b8 b0 26 MOV uVar1 ,0x26b0
uVar is defined as a ushort: a 16bit type.
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •all makes sense, right? 16bit to 16bit!
so ghidra decompiles it as uVar1._0_1_ = 0xb0;
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •the most annoying thing?
this is picking between two strings to display, and those strings are "he" and "she".
EVEN IN 35 YEAR OLD COMPUTER GAMES I CANNOT ESCAPE GENDER PROBLEMS!
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •unfortunately due to an oversight it believes those 65536 genders are allocated as:
0: He/he/Him/him
1-65535: She/she/Her/her
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Since it's no longer 1990, I think I can safely bump that up a bit? I won't need more than another 64 KB, which means I'll just bump the game up to 496 KB memory required. Completely doable in any 640 KB or more machine!
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •the applyPronouns function lets you adjust how it's encoded dynamically. Fancy!
So how it works is you do something like this:
applyPronouns("\80 was bald", 0x80, "he\0him")
and it'll return "he was bald", right? But it's more than just a simple find-replace...
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Because you can do:
applyPronouns("I saw \81. \80 was bald!", 0x80, "he\0him")
and it'll return "I saw him. he was bald!".
See, you can specify multiple replacements at once, by using \x80, \x81, \x82 and so on.
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •I got my floppy copy in the mail, I just need to image it.
Fun fact from the box: It has a letter from the player character to their cousin, and I believe this is the only place in the game and associated media that they name your character.
It's Dale.
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •They're laid out like this:
Disk 1:
CARMEN.EXE
CARMEN.DAT
Disk 2:
CITIES.DAT
MIDISND.DAT
DIGISND.DAT
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Finally, we know the answer to the age-old question of Where in the World is Carmen Sandiego?
The answer is "My floppy drive"
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •well my "ignore the problem" solution of using bochscpu to embed a 16bit x86 emulator has failed. it's somehow broken and it's broken in the rust library or C core, not the python, and I really don't want to have to deal with debugging this.
time to switch to a completely different x86 emulator? PROBABLY!
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •unicorn has great documentation.
at least I assume it would be great, if it existed
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •x86 16bit segmentation and regular expressions:
BECAUSE FUCK IT
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •I'm implementing unicorn as an x86 emulator to do the decompression, but I'm single-stepping the processor and I'm aiding debugging by showing what instruction I'm on.
but instead of having to set up an x86 disassembly engine, I'm just parsing a plain text ghidra dump of the disassembly. I'm parsing it with regexes
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •my latest bad idea: DUMBPATCH.
to avoid the complexity of generating functions and mapping them into the address space of the emulated PC, I instead designed a simple syntax:
a 16bit segmented address plus a number. that function is emulated as if it returned that number in AX. There are no other options. I suspect I'll be able to emulate up to 80% of complex subfunctions with this one bit of functionality
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •I need this because the decompression routine I'm emulating isn't entirely standalone: it calls malloc() at the beginning and free() at the end
so I'm replacing malloc() with a static value and free() with a return value no one will check
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •ideally I should be able to patch arbitrary python in there and do some kind of interop to return values to python
but that's hard. and way easier unflexible thing this is 80% of what I need that for
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •back on hacking Enhanced, DOS, 1990.
My best guess is that this game has between 4-6 compression algorithms, depending on how you count them. Possibly more are hidden in the bowels of this program.
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •This code mallocs 65516 bytes in a loop until malloc returns zero.
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •totally normal part of starting program: allocate all the RAM in the system.
I mean, it's DOS. There's nothing else running that could possibly call malloc. So why not?
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •There's just not that much memory in the system that this can touch, since it's not supporting any of the endless varieties of breaking the 640k barrier
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •there's a story on Old New Thing somewhere about Windows 95 accidentally breaking a DOS game, because it did this same trick of allocating all the memory, but since Win95 was running as the DPMS, it meant it had access to all of windows 95's virtual memory. including the swap.
So instead of mallocing all 8mb or whatever your 486 had, it malloced all that and then tried to use up YOUR ENTIRE HARD DRIVE, slowly.
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •this game runs mostly in a 16 color mode, with some high-end modes being basically 16-colors within 64 or 256 colors, right?
SO WHY DOES IT USE 16-BIT INTEGERS FOR COLOR INDICES?
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •note to self: patch out the Romani slur in one of the hints for Budapest
EDIT: both of them
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •The description of Hungary says it's bordered by Czechoslovakia, Austria, Yugoslavia, Romania, and the Soviet Union.
Two of those are still right!
Foone🏳️⚧️
in reply to Foone🏳️⚧️ • • •so I fly into Reykjavík, and immediately sleep for 8 hours. In the morning, I can go to either the airport or the hotel, but it'll take 3 hours to get to either.
Question: where am I right now, if I'm not at the hotel or the airport?
Z̈oé ⛵
in reply to Foone🏳️⚧️ • • •yomimono, still on earth
in reply to Foone🏳️⚧️ • • •Crystal Huff (they/them)
in reply to Foone🏳️⚧️ • • •Aatheus
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Aatheus • • •Aatheus
in reply to Foone🏳️⚧️ • • •Graham Sutherland / Polynomial
in reply to Foone🏳️⚧️ • • •Large Print Edition (Delia~!)
in reply to Foone🏳️⚧️ • • •Kevin Boyd (he/him) 🇨🇦
in reply to Foone🏳️⚧️ • • •~
in reply to Foone🏳️⚧️ • • •Pxl Phile
in reply to Foone🏳️⚧️ • • •Ben A L Jemmett
in reply to Foone🏳️⚧️ • • •C.
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to C. • • •Spindel
in reply to Foone🏳️⚧️ • • •Krutonium
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Krutonium • • •Ingo
in reply to Foone🏳️⚧️ • • •Foone🏳️⚧️
in reply to Ingo • • •