diff --git a/src/audio.c b/src/audio.c
index 20925d1a25..ca3f86f604 100644
--- a/src/audio.c
+++ b/src/audio.c
@@ -18,10 +18,53 @@
* along with this program. If not, see .
*****************************************************************************/
+#include
#include "audio.h"
#include "addresses.h"
#include "rct2.h"
+int gAudioDeviceCount;
+audio_device *gAudioDevices = NULL;
+
+void audio_init(int i)
+{
+ if (SDL_Init(SDL_INIT_AUDIO) < 0) {
+ RCT2_ERROR("SDL_Init %s", SDL_GetError());
+ exit(-1);
+ }
+}
+
+void audio_quit()
+{
+ SDL_QuitSubSystem(SDL_INIT_AUDIO);
+}
+
+/**
+ * Populates audio devices.
+ */
+void audio_get_devices()
+{
+ int i;
+
+ if (gAudioDevices != NULL)
+ free(gAudioDevices);
+
+ gAudioDeviceCount = SDL_GetNumAudioDevices(SDL_FALSE);
+ if (gAudioDeviceCount > 0) {
+ gAudioDeviceCount++;
+ gAudioDevices = malloc(gAudioDeviceCount * sizeof(audio_device));
+
+ strcpy(gAudioDevices[0].name, "Default sound device");
+ for (i = 1; i < gAudioDeviceCount; i++) {
+ const char *utf8_name = SDL_GetAudioDeviceName(i - 1, SDL_FALSE);
+ if (utf8_name == NULL)
+ utf8_name = "(UNKNOWN)";
+
+ strcpy(gAudioDevices[i].name, utf8_name);
+ }
+ }
+}
+
void get_dsound_devices()
{
RCT2_CALLPROC(0x0040502E);
diff --git a/src/audio.h b/src/audio.h
index 2f5f9981ae..52a51c2cee 100644
--- a/src/audio.h
+++ b/src/audio.h
@@ -21,6 +21,18 @@
#ifndef _AUDIO_H_
#define _AUDIO_H_
+typedef struct {
+ char name[256];
+} audio_device;
+
+extern int gAudioDeviceCount;
+extern audio_device *gAudioDevices;
+
+void audio_init();
+void audio_quit();
+void audio_get_devices();
+
+
#include
/**
diff --git a/src/date.h b/src/date.h
index 23eae8cdc9..0fef3dde69 100644
--- a/src/date.h
+++ b/src/date.h
@@ -39,6 +39,7 @@ enum {
extern const sint16 days_in_month[MONTH_COUNT];
int date_get_month(int months);
+int date_get_year(int months);
int date_get_total_months(int month, int year);
void date_reset();
diff --git a/src/rct2.c b/src/rct2.c
index 0fb90244b0..a8ab8ea254 100644
--- a/src/rct2.c
+++ b/src/rct2.c
@@ -29,6 +29,7 @@
#include
#include
#include "addresses.h"
+#include "audio.h"
#include "climate.h"
#include "config.h"
#include "date.h"
@@ -76,6 +77,9 @@ __declspec(dllexport) int StartOpenRCT(HINSTANCE hInstance, HINSTANCE hPrevInsta
RCT2_GLOBAL(0x01423A08, HINSTANCE) = hInstance;
RCT2_GLOBAL(RCT2_ADDRESS_CMDLINE, LPSTR) = lpCmdLine;
get_system_info();
+
+ audio_init();
+ audio_get_devices();
RCT2_CALLPROC(0x0040502E); // get_dsound_devices()
config_init();
diff --git a/src/string_ids.c b/src/string_ids.c
index 331bb7537b..78c380760f 100644
--- a/src/string_ids.c
+++ b/src/string_ids.c
@@ -19,9 +19,1363 @@
*****************************************************************************/
#include
+#include
#include "addresses.h"
+#include "date.h"
#include "rct2.h"
#include "string_ids.h"
+#include "util.h"
+
+// TODO Store real names in a data file.
+#pragma region Real names
+
+const char *real_names[] = {
+ "Aaron",
+ "Abdul",
+ "Abraham",
+ "Abu",
+ "Adam",
+ "Adrian",
+ "Adriane",
+ "Aileen",
+ "Aisha",
+ "Akiko",
+ "Akira",
+ "Al",
+ "Ali",
+ "Alan",
+ "Alana",
+ "Albert",
+ "Alberta",
+ "Alec",
+ "Alesia",
+ "Alex",
+ "Alexa",
+ "Alexander",
+ "Alexandra",
+ "Alexis",
+ "Alf",
+ "Alfonso",
+ "Alfred",
+ "Alice",
+ "Alicia",
+ "Alison",
+ "Alistair",
+ "Allan",
+ "Allen",
+ "Allison",
+ "Allister",
+ "Alma",
+ "Alvin",
+ "Alyson",
+ "Amanda",
+ "Amber",
+ "Amilio",
+ "Amos",
+ "Amy",
+ "Ana",
+ "Anabel",
+ "Anastasia",
+ "Andie",
+ "Andrea",
+ "Andres",
+ "Andrew",
+ "Andy",
+ "Angel",
+ "Angela",
+ "Angelica",
+ "Angie",
+ "Angus",
+ "Anika",
+ "Ann",
+ "Anna",
+ "Anne",
+ "Annette",
+ "Annie",
+ "Annika",
+ "Anthony",
+ "Anton",
+ "Antonio",
+ "April",
+ "Archer",
+ "Archie",
+ "Arlene",
+ "Arnie",
+ "Arnold",
+ "Art",
+ "Arthur",
+ "Asaf",
+ "Ashley",
+ "Astrid",
+ "Aubrey",
+ "Austin",
+ "Austine",
+ "Avon",
+ "Avril",
+ "Axel",
+ "Aziz",
+ "Bailey",
+ "Barbara",
+ "Barney",
+ "Barry",
+ "Bart",
+ "Barton",
+ "Baxter",
+ "Beck",
+ "Becket",
+ "Becky",
+ "Belinda",
+ "Bella",
+ "Belle",
+ "Ben",
+ "Benjamin",
+ "Benny",
+ "Bernadette",
+ "Bernard",
+ "Bernice",
+ "Bess",
+ "Beth",
+ "Bethany",
+ "Bette",
+ "Betty",
+ "Bernard",
+ "Bernardette",
+ "Bernice",
+ "Berty",
+ "Bev",
+ "Beverly",
+ "Beverley",
+ "Bianca",
+ "Bill",
+ "Billie",
+ "Billy",
+ "Bjorn",
+ "Blaire",
+ "Blake",
+ "Blanche",
+ "Bo",
+ "Bob",
+ "Bobbie",
+ "Bobby",
+ "Bonnie",
+ "Boris",
+ "Brad",
+ "Bradley",
+ "Brady",
+ "Brandi",
+ "Brandon",
+ "Brandy",
+ "Brenda",
+ "Brendan",
+ "Brendon",
+ "Brent",
+ "Brett",
+ "Brian",
+ "Bridgit",
+ "Brigitte",
+ "Britney",
+ "Bruce",
+ "Bruno",
+ "Brutus",
+ "Bryan",
+ "Buck",
+ "Bucky",
+ "Bug",
+ "Burton",
+ "Byron",
+ "Cailin",
+ "Caitlyn",
+ "Cal",
+ "Caley",
+ "Callum",
+ "Calvin",
+ "Cameron",
+ "Camille",
+ "Campbell",
+ "Candy",
+ "Carl",
+ "Carla",
+ "Carlene",
+ "Carlos",
+ "Carmela",
+ "Carmen",
+ "Carol",
+ "Carole",
+ "Caroline",
+ "Carolyn",
+ "Carrie",
+ "Casey",
+ "Cassandra",
+ "Cassey",
+ "Cassie",
+ "Catherina",
+ "Catherine",
+ "Cathy",
+ "Caz",
+ "Cecelia",
+ "Cecil",
+ "Cecille",
+ "Ceilidh",
+ "Celeste",
+ "Chad",
+ "Charlene",
+ "Charles",
+ "Charlie",
+ "Charlotte",
+ "Chelsea",
+ "Cher",
+ "Cheri",
+ "Cheryll",
+ "Chip",
+ "Chloe",
+ "Chris",
+ "Christel",
+ "Christian",
+ "Christie",
+ "Christina",
+ "Christine",
+ "Christopher",
+ "Chuck",
+ "Cindy",
+ "Clark",
+ "Clair",
+ "Claire",
+ "Clara",
+ "Clarabell",
+ "Claude",
+ "Claudette",
+ "Claudia",
+ "Clayton",
+ "Cliff",
+ "Clifford",
+ "Clint",
+ "Clive",
+ "Clyde",
+ "Codey",
+ "Cody",
+ "Colin",
+ "Colleen",
+ "Connie",
+ "Coral",
+ "Corina",
+ "Craig",
+ "Curtis",
+ "Cynthia",
+ "Cyril",
+ "Darby",
+ "Daisy",
+ "Dale",
+ "Damien",
+ "Damon",
+ "Dan",
+ "Dana",
+ "Daniel",
+ "Danielle",
+ "Danni",
+ "Danny",
+ "Daphne",
+ "Darla",
+ "Darlene",
+ "Darrell",
+ "Darren",
+ "Darryl",
+ "Dave",
+ "David",
+ "Davie",
+ "Davis",
+ "Dawn",
+ "Dean",
+ "Debbie",
+ "Debby",
+ "Deborah",
+ "Debra",
+ "Debs",
+ "Deidre",
+ "Delores",
+ "Denise",
+ "Dennis",
+ "Denzel",
+ "Derek",
+ "Desmond",
+ "Diana",
+ "Diane",
+ "Dianna",
+ "Dick",
+ "Dillon",
+ "Dina",
+ "Dominic",
+ "Dominik",
+ "Don",
+ "Donald",
+ "Donna",
+ "Donovan",
+ "Doreen",
+ "Doris",
+ "Dorothy",
+ "Doug",
+ "Dougal",
+ "Douglas",
+ "Doyle",
+ "Drew",
+ "Duane",
+ "Dudley",
+ "Duncan",
+ "Dwight",
+ "Dylan",
+ "Earl",
+ "Ed",
+ "Eddie",
+ "Edgar",
+ "Edith",
+ "Edmond",
+ "Edward",
+ "Edwin",
+ "Edwina",
+ "Eileen",
+ "Elaine",
+ "Elina",
+ "Elisa",
+ "Elisabeth",
+ "Eliza",
+ "Elizabeth",
+ "Ella",
+ "Ellen",
+ "Elmer",
+ "Elsie",
+ "Emile",
+ "Emilio",
+ "Emily",
+ "Emma",
+ "Emmett",
+ "Enrique",
+ "Eric",
+ "Erica",
+ "Ericka",
+ "Erik",
+ "Erika",
+ "Erin",
+ "Erinn",
+ "Ernest",
+ "Esmeralda",
+ "Esta",
+ "Estella",
+ "Esther",
+ "Ethan",
+ "Eugene",
+ "Eva",
+ "Evan",
+ "Eve",
+ "Evelyn",
+ "Everett",
+ "Felix",
+ "Fabio",
+ "Falicia",
+ "Farah",
+ "Felicity",
+ "Fernando",
+ "Fergus",
+ "Fidelia",
+ "Finlay",
+ "Fiona",
+ "Fletcher",
+ "Flora",
+ "Florence",
+ "Floyd",
+ "Fly",
+ "Frances",
+ "Francesca",
+ "Francis",
+ "Francisco",
+ "Frank",
+ "Franklin",
+ "Franky",
+ "Fraser",
+ "Fred",
+ "Freda",
+ "Freddy",
+ "Fuzz",
+ "Gabriel",
+ "Gabriela",
+ "Gail",
+ "Garrett",
+ "Garth",
+ "Gary",
+ "Gavin",
+ "Gayle",
+ "Gene",
+ "Genevieve",
+ "Geoff",
+ "Geoffrey",
+ "George",
+ "Gerald",
+ "Geraldine",
+ "Gerard",
+ "Geri",
+ "Gerry",
+ "Gilbert",
+ "Gillian",
+ "Gina",
+ "Ginger",
+ "Giuseppe",
+ "Gladys",
+ "Glen",
+ "Glenda",
+ "Glenn",
+ "Gloria",
+ "Glyne",
+ "Goldie",
+ "Gordon",
+ "Grace",
+ "Graeme",
+ "Graham",
+ "Grant",
+ "Grayson",
+ "Greg",
+ "Gregor",
+ "Gregory",
+ "Gretchen",
+ "Gus",
+ "Guy",
+ "Gwen",
+ "Gwendoline",
+ "Hadrian",
+ "Hamish",
+ "Hank",
+ "Hannah",
+ "Hans",
+ "Harley",
+ "Harold",
+ "Harry",
+ "Harvey",
+ "Haseem",
+ "Hayley",
+ "Hazel",
+ "Heather",
+ "Hector",
+ "Heidi",
+ "Helen",
+ "Helena",
+ "Henri",
+ "Henry",
+ "Herbert",
+ "Herbie",
+ "Hermann",
+ "Hilda",
+ "Hollie",
+ "Holly",
+ "Homer",
+ "Horace",
+ "Howard",
+ "Hugh",
+ "Hugo",
+ "Iain",
+ "Ian",
+ "Imani",
+ "Imelda",
+ "Imran",
+ "Ingrid",
+ "Irene",
+ "Irma",
+ "Irving",
+ "Isaac",
+ "Isabella",
+ "Isabelle",
+ "Ishan",
+ "Isla",
+ "Ivan",
+ "Ivanna",
+ "Ivy",
+ "Izola",
+ "Jack",
+ "Jacque",
+ "Jacqueline",
+ "Jacqui",
+ "Jake",
+ "Jakob",
+ "James",
+ "Jacob",
+ "Jan",
+ "Janet",
+ "Jane",
+ "Janice",
+ "Jason",
+ "Jasper",
+ "Jay",
+ "Jayne",
+ "Jean",
+ "Jeanette",
+ "Jeff",
+ "Jeffrey",
+ "Jennifer",
+ "Jenny",
+ "Jeremy",
+ "Jerry",
+ "Jesse",
+ "Jessica",
+ "Jessie",
+ "Jessy",
+ "Jill",
+ "Jillian",
+ "Jim",
+ "Jimbo",
+ "Jimmy",
+ "Jo",
+ "Joan",
+ "Joann",
+ "Joanne",
+ "Jock",
+ "Jodi",
+ "Joe",
+ "Joel",
+ "Joelyn",
+ "Joey",
+ "Johan",
+ "John",
+ "Johnathan",
+ "Johnnie",
+ "Johnny",
+ "Jolynn",
+ "Jon",
+ "Jonah",
+ "Jonas",
+ "Jonathan",
+ "Joni",
+ "Jonny",
+ "Jordan",
+ "Jorge",
+ "Jose",
+ "Joseph",
+ "Josephine",
+ "Josh",
+ "Joshua",
+ "Joyce",
+ "Juan",
+ "Juana",
+ "Juanita",
+ "Judge",
+ "Judie",
+ "Judith",
+ "Judy",
+ "Julia",
+ "Julian",
+ "Julie",
+ "Juliette",
+ "Julio",
+ "Julius",
+ "June",
+ "Justin",
+ "Kaley",
+ "Kaitlyn",
+ "Kandice",
+ "Kara",
+ "Kareen",
+ "Karen",
+ "Karl",
+ "Karolyne",
+ "Karri",
+ "Kate",
+ "Katelyn",
+ "Katey",
+ "Kathy",
+ "Katherine",
+ "Kathie",
+ "Kathleen",
+ "Kathryn",
+ "Katie",
+ "Katrina",
+ "Katy",
+ "Katya",
+ "Kay",
+ "Keiko",
+ "Keith",
+ "Kelly",
+ "Kelsey",
+ "Ken",
+ "Kenneth",
+ "Kenny",
+ "Kerry",
+ "Kev",
+ "Kevin",
+ "Kieran",
+ "Kim",
+ "Kimberly",
+ "Kiriaki",
+ "Kirk",
+ "Klaus",
+ "Kris",
+ "Krista",
+ "Kristian",
+ "Kristy",
+ "Kurt",
+ "Kurtis",
+ "Kyle",
+ "Kylie",
+ "Laila",
+ "Lana",
+ "Lance",
+ "Larry",
+ "Lasse",
+ "Latisha",
+ "Laura",
+ "Lauren",
+ "Lauryn",
+ "Laurie",
+ "Lawrence",
+ "Leah",
+ "Lee",
+ "Leigh",
+ "Len",
+ "Lena",
+ "Lenore",
+ "Leo",
+ "Leon",
+ "Leonard",
+ "Leonardo",
+ "Leone",
+ "Leroy",
+ "Les",
+ "Leslie",
+ "Lesley",
+ "Lester",
+ "Lewis",
+ "Liam",
+ "Lillian",
+ "Lilly",
+ "Lily",
+ "Linda",
+ "Lindsay",
+ "Lindsey",
+ "Lisa",
+ "Lita",
+ "Logan",
+ "Lone",
+ "Loren",
+ "Loretta",
+ "Lori",
+ "Lorraine",
+ "Lottie",
+ "Louis",
+ "Louise",
+ "Lowell",
+ "Lucas",
+ "Lucy",
+ "Luis",
+ "Luke",
+ "Luther",
+ "Lydia",
+ "Lynn",
+ "Lynne",
+ "Lyssa",
+ "Mabel",
+ "Madeline",
+ "Maggie",
+ "Magnus",
+ "Mahamed",
+ "Malcolm",
+ "Mandy",
+ "Manuel",
+ "Marc",
+ "Marcela",
+ "Marci",
+ "Marcia",
+ "Marco",
+ "Marcus",
+ "Marcy",
+ "Margaret",
+ "Margarita",
+ "Maria",
+ "Mariah",
+ "Marian",
+ "Marianna",
+ "Marie",
+ "Marilyn",
+ "Marina",
+ "Marion",
+ "Marisa",
+ "Marissa",
+ "Marjorie",
+ "Mark",
+ "Markus",
+ "Marlene",
+ "Marlin",
+ "Marlon",
+ "Marshall",
+ "Martha",
+ "Martin",
+ "Martyn",
+ "Marvin",
+ "Mary",
+ "Mathew",
+ "Matt",
+ "Matthew",
+ "Maude",
+ "Maureen",
+ "Maurice",
+ "Mauricio",
+ "Mavis",
+ "Max",
+ "Maxine",
+ "May",
+ "Megan",
+ "Meghan",
+ "Mel",
+ "Melanie",
+ "Melany",
+ "Melinda",
+ "Melissa",
+ "Melody",
+ "Melvin",
+ "Mervin",
+ "Mhairi",
+ "Mia",
+ "Michael",
+ "Michelle",
+ "Mick",
+ "Mickey",
+ "Miguel",
+ "Mikael",
+ "Mike",
+ "Mikey",
+ "Miki",
+ "Mikko",
+ "Mildred",
+ "Millie",
+ "Milly",
+ "Milton",
+ "Miranda",
+ "Miriam",
+ "Mirriam",
+ "Mitchell",
+ "Mo",
+ "Molly",
+ "Monica",
+ "Monique",
+ "Monty",
+ "Morgan",
+ "Morten",
+ "Moses",
+ "Morris",
+ "Muriel",
+ "Murphy",
+ "Murray",
+ "Mustafa",
+ "Myles",
+ "Myrissa",
+ "Myrtle",
+ "Nadine",
+ "Nancy",
+ "Nanette",
+ "Naomi",
+ "Natalia",
+ "Natalie",
+ "Natasha",
+ "Nathan",
+ "Nathaniel",
+ "Neil",
+ "Nellie",
+ "Nelly",
+ "Nelson",
+ "Neville",
+ "Nicholas",
+ "Nichole",
+ "Nick",
+ "Nico",
+ "Nicola",
+ "Nicolas",
+ "Nicole",
+ "Nigel",
+ "Nikia",
+ "Nikki",
+ "Nina",
+ "Noah",
+ "Noel",
+ "Norma",
+ "Norman",
+ "Norris",
+ "Norvall",
+ "Olga",
+ "Olive",
+ "Oliver",
+ "Ollie",
+ "Omar",
+ "Oona",
+ "Orve",
+ "Orville",
+ "Oscar",
+ "Otto",
+ "Owen",
+ "Paisley",
+ "Pam",
+ "Pamela",
+ "Pandora",
+ "Pat",
+ "Patricia",
+ "Patrick",
+ "Patty",
+ "Paul",
+ "Paula",
+ "Pauline",
+ "Pedro",
+ "Peggy",
+ "Penelope",
+ "Penny",
+ "Perry",
+ "Pete",
+ "Peter",
+ "Phil",
+ "Philip",
+ "Phillip",
+ "Phyllis",
+ "Polly",
+ "Preston",
+ "Qasim",
+ "Quentin",
+ "Quinn",
+ "Rachel",
+ "Rae",
+ "Rafael",
+ "Raj",
+ "Raja",
+ "Ralph",
+ "Ramon",
+ "Randal",
+ "Rashid",
+ "Raquel",
+ "Raul",
+ "Ray",
+ "Raymond",
+ "Raymondo",
+ "Rebecca",
+ "Reg",
+ "Regina",
+ "Reginald",
+ "Reinhold",
+ "Rene",
+ "Reuben",
+ "Rex",
+ "Rhonda",
+ "Richard",
+ "Rick",
+ "Ricky",
+ "Rita",
+ "Robb",
+ "Robert",
+ "Roberta",
+ "Robin",
+ "Robina",
+ "Robyn",
+ "Robynne",
+ "Rock",
+ "Rockie",
+ "Rod",
+ "Rodney",
+ "Rodrigo",
+ "Roland",
+ "Rolf",
+ "Romeo",
+ "Ronald",
+ "Ronan",
+ "Ronnie",
+ "Roger",
+ "Rosalind",
+ "Rosanna",
+ "Rosanned",
+ "Rose",
+ "Rosemary",
+ "Rosetta",
+ "Rosie",
+ "Ross",
+ "Roxanne",
+ "Roy",
+ "Russell",
+ "Rosty",
+ "Ruben",
+ "Ruby",
+ "Ruth",
+ "Ryan",
+ "Sabrina",
+ "Sadie",
+ "Sally",
+ "Sam",
+ "Samantha",
+ "Sammy",
+ "Samuel",
+ "Sandra",
+ "Sandy",
+ "Sara",
+ "Sarah",
+ "Sasha",
+ "Saul",
+ "Scot",
+ "Scott",
+ "Sean",
+ "Sebastian",
+ "Sergio",
+ "Shakira",
+ "Shannon",
+ "Shari",
+ "Sharnell",
+ "Sharon",
+ "Sharyn",
+ "Shawn",
+ "Shelby",
+ "Shelley",
+ "Sherene",
+ "Sheri",
+ "Sherman",
+ "Sherry",
+ "Shirley",
+ "Sheryl",
+ "Shivani",
+ "Shona",
+ "Sian",
+ "Sid",
+ "Sidney",
+ "Simon",
+ "Sindy",
+ "Sinead",
+ "Sofia",
+ "Sonny",
+ "Sonja",
+ "Sonya",
+ "Sophia",
+ "Sophie",
+ "Spencer",
+ "Stacey",
+ "Stan",
+ "Stanley",
+ "Stefan",
+ "Stephen",
+ "Stephanie",
+ "Steve",
+ "Steven",
+ "Stewart",
+ "Stuart",
+ "Sue",
+ "Suki",
+ "Susan",
+ "Susana",
+ "Susanne",
+ "Susie",
+ "Suzanne",
+ "Sven",
+ "Sylvester",
+ "Sylvia",
+ "Tabatha",
+ "Tamara",
+ "Tammie",
+ "Tamsin",
+ "Tania",
+ "Tanya",
+ "Tara",
+ "Taylor",
+ "Ted",
+ "Teresa",
+ "Terrance",
+ "Terry",
+ "Tess",
+ "Tessa",
+ "Tex",
+ "Thelma",
+ "Theodore",
+ "Theresa",
+ "Thomas",
+ "Tiffany",
+ "Tiger",
+ "Tiko",
+ "Tillie",
+ "Tim",
+ "Timmy",
+ "Timothy",
+ "Tina",
+ "Toby",
+ "Todd",
+ "Tom",
+ "Tomaki",
+ "Tommy",
+ "Tonia",
+ "Tonie",
+ "Tony",
+ "Tracy",
+ "Travis",
+ "Trevor",
+ "Tricia",
+ "Trixie",
+ "Troy",
+ "Tucker",
+ "Tyler",
+ "Tyson",
+ "Ulysses",
+ "Uri",
+ "Val",
+ "Valerie",
+ "Vanessa",
+ "Vani",
+ "Vaughn",
+ "Velma",
+ "Vernon",
+ "Veronica",
+ "Vicki",
+ "Vicky",
+ "Victor",
+ "Victoria",
+ "Vijay",
+ "Vince",
+ "Vincent",
+ "Vinnie",
+ "Virginia",
+ "Viv",
+ "Vivian",
+ "Viviene",
+ "Wally",
+ "Walt",
+ "Walter",
+ "Walton",
+ "Wanda",
+ "Warren",
+ "Wayne",
+ "Wendell",
+ "Wendy",
+ "Wes",
+ "Wesley",
+ "Whitney",
+ "Will",
+ "William",
+ "Willie",
+ "Willis",
+ "Wilson",
+ "Winston",
+ "Wyatt",
+ "Xavier",
+ "Yasmin",
+ "Yogi",
+ "Ysabel",
+ "Yvonne",
+ "Zachary",
+ "Zachery",
+ "Zola"
+};
+
+#pragma endregion
+
+char real_name_initials[] = {
+ 'B', 'C', 'D', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'R', 'S', 'T', 'W'
+};
+
+void format_string_part_from_raw(char **dest, const char *src, char **args);
+void format_string_part(char **dest, rct_string_id format, char **args);
+
+const char *get_string(rct_string_id id)
+{
+ return RCT2_ADDRESS(0x009BF2D4, const char*)[id];
+}
+
+void format_integer(char **dest, int value)
+{
+ int digit;
+ char *dst = *dest;
+ char *finish;
+ char tmp;
+
+ // Negative sign
+ if (value < 0) {
+ *dst++ = '-';
+ value = -value;
+ }
+
+ *dest = dst;
+
+ // Right to left
+ while (value > 0) {
+ digit = value % 10;
+ value /= 10;
+
+ *dst++ = '0' + digit;
+ }
+ finish = dst;
+
+ // Reverse string
+ dst--;
+ while (*dest < dst) {
+ tmp = **dest;
+ **dest = *dst;
+ *dst = tmp;
+ (*dest)++;
+ dst--;
+ }
+ *dest = finish;
+}
+
+void format_comma_seperated_integer(char **dest, int value)
+{
+ int digit, groupIndex;
+ char *dst = *dest;
+ char *finish;
+ char tmp;
+
+ // Negative sign
+ if (value < 0) {
+ *dst++ = '-';
+ value = -value;
+ }
+
+ *dest = dst;
+
+ // Groups of three digits, right to left
+ groupIndex = 0;
+ while (value > 0) {
+ // Append group seperator
+ if (groupIndex == 3) {
+ groupIndex = 0;
+ *dst++ = ',';
+ }
+
+ digit = value % 10;
+ value /= 10;
+
+ *dst++ = '0' + digit;
+ groupIndex++;
+ }
+ finish = dst;
+
+ // Reverse string
+ dst--;
+ while (*dest < dst) {
+ tmp = **dest;
+ **dest = *dst;
+ *dst = tmp;
+ (*dest)++;
+ dst--;
+ }
+ *dest = finish;
+}
+
+void format_string_code(unsigned char format_code, char **dest, char **args)
+{
+ int value;
+
+ switch (format_code) {
+ case FORMAT_COMMA32:
+ // Pop argument
+ value = *((sint32*)*args);
+ *args += 4;
+
+ format_comma_seperated_integer(dest, value);
+ break;
+ case FORMAT_INT32:
+ // Pop argument
+ value = *((sint32*)*args);
+ *args += 4;
+
+ format_integer(dest, value);
+ break;
+ case FORMAT_COMMA2DP32:
+ // Pop argument
+ value = *((sint32*)*args);
+ *args += 4;
+
+ // TODO
+ printf("TODO: FORMAT_COMMA2DP32\n");
+ break;
+ case FORMAT_COMMA16:
+ // Pop argument
+ value = *((sint16*)*args);
+ *args += 2;
+
+ format_comma_seperated_integer(dest, value);
+ break;
+ case FORMAT_UINT16:
+ // Pop argument
+ value = *((uint16*)*args);
+ *args += 2;
+
+ format_integer(dest, value);
+ break;
+ case FORMAT_CURRENCY2DP:
+ // Pop argument
+ value = *((sint32*)*args);
+ *args += 4;
+
+ // TODO
+ printf("TODO: FORMAT_CURRENCY2DP\n");
+ break;
+ case FORMAT_CURRENCY:
+ // Pop argument
+ value = *((sint32*)*args);
+ *args += 4;
+
+ // TODO
+ printf("TODO: FORMAT_CURRENCY\n");
+ break;
+ case FORMAT_STRINGID:
+ case FORMAT_STRINGID2:
+ // Pop argument
+ value = *((uint16*)*args);
+ *args += 2;
+
+ format_string_part(dest, value, args);
+ break;
+ case FORMAT_STRING:
+ // Pop argument
+ value = *((uint32*)*args);
+ *args += 4;
+
+ strcpy(*dest, (char*)value);
+ *dest += strlen(*dest);
+ break;
+ case FORMAT_MONTHYEAR:
+ // Pop argument
+ value = *((uint16*)*args);
+ *args += 2;
+
+ uint16 dateArgs[] = { date_get_year(value), date_get_month(value) };
+ char formatString[] = "?, Year ?";
+ formatString[0] = FORMAT_MONTH;
+ formatString[8] = FORMAT_COMMA16;
+ format_string_part_from_raw(dest, formatString, (char**)&dateArgs);
+ break;
+ case FORMAT_MONTH:
+ // Pop argument
+ value = *((uint16*)*args);
+ *args += 2;
+
+ strcpy(*dest, get_string(STR_MONTH_MARCH + date_get_month(value)));
+ *dest += strlen(*dest);
+ break;
+ case FORMAT_VELOCITY:
+ // Pop argument
+ value = *((sint16*)*args);
+ *args += 2;
+
+ if (RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_METRIC, uint8)) {
+ format_comma_seperated_integer(dest, mph_to_kmph(value));
+ strcat(*dest, "kmh");
+ *dest += strlen(*dest);
+ } else {
+ format_comma_seperated_integer(dest, value);
+ strcat(*dest, "mph");
+ *dest += strlen(*dest);
+ }
+ break;
+ case FORMAT_POP16:
+ *args += 2;
+ break;
+ case FORMAT_PUSH16:
+ *args -= 2;
+ break;
+ case FORMAT_DURATION:
+ // Pop argument
+ value = *((uint16*)*args);
+ *args += 2;
+
+ if (value / 60 > 0) {
+ format_integer(dest, value / 60);
+ strcpy(*dest, value / 60 == 1 ? "min:" : "mins:");
+ *dest += strlen(*dest);
+ }
+
+ format_integer(dest, value % 60);
+ strcpy(*dest, value % 60 == 1 ? "sec:" : "secs:");
+ *dest += strlen(*dest);
+ break;
+ case FORMAT_REALTIME:
+ // Pop argument
+ value = *((uint16*)*args);
+ *args += 2;
+
+ if (value / 60 > 0) {
+ format_integer(dest, value / 60);
+ strcpy(*dest, value / 60 == 1 ? "hour:" : "hours:");
+ *dest += strlen(*dest);
+ }
+
+ format_integer(dest, value % 60);
+ strcpy(*dest, value % 60 == 1 ? "min:" : "mins:");
+ *dest += strlen(*dest);
+ break;
+ case FORMAT_LENGTH:
+ // Pop argument
+ value = *((sint16*)*args);
+ *args += 2;
+
+ if (RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_METRIC, uint8)) {
+ format_comma_seperated_integer(dest, value);
+ strcat(*dest, "m");
+ *dest += strlen(*dest);
+ } else {
+ format_comma_seperated_integer(dest, metres_to_feet(value));
+ strcat(*dest, "ft");
+ *dest += strlen(*dest);
+ }
+ break;
+ case FORMAT_SPRITE:
+ // Pop argument
+ value = *((uint32*)*args);
+ *args += 4;
+
+ *(*dest)++ = 23;
+ *((uint32*)(*dest)) = value;
+ *dest += 4;
+ break;
+ }
+}
+
+void format_string_part_from_raw(char **dest, const char *src, char **args)
+{
+ unsigned char code;
+ while (1) {
+ code = *src++;
+ if (code < ' ') {
+ if (code == 0) {
+ *(*dest)++ = code;
+ break;
+ } else if (code <= 4) {
+ *(*dest)++ = code;
+ *(*dest)++ = *src++;
+ } else if (code <= 16) {
+ *(*dest)++ = code;
+ } else if (code <= 22) {
+ *(*dest)++ = code;
+ *(*dest)++ = *src++;
+ *(*dest)++ = *src++;
+ *(*dest)++ = *src++;
+ *(*dest)++ = *src++;
+ } else {
+ *(*dest)++ = code;
+ }
+ } else if (code <= 'z') {
+ *(*dest)++ = code;
+ } else if (code < 142) {
+ format_string_code(code, dest, args);
+ } else {
+ *(*dest)++ = code;
+ }
+ }
+}
+
+void format_string_part(char **dest, rct_string_id format, char **args)
+{
+ if (format < 0x8000) {
+ // Language string
+ format_string_part_from_raw(dest, get_string(format), args);
+ } else if (format < 0x9000) {
+ // Custom string
+ format -= 0x8000;
+ // args += (format & 0xC00) >> 9;
+ format &= ~0xC00;
+ strcpy(*dest, RCT2_ADDRESS(0x135A8F4 + (format * 32), char));
+ } else if (format < 0xE000) {
+ // Real name
+ format -= -0xA000;
+ sprintf(*dest, "%s %c.",
+ real_names[format % countof(real_names)],
+ real_name_initials[(format >> 10) % countof(real_name_initials)]
+ );
+ } else {
+ // ?
+ RCT2_CALLPROC_EBPSAFE(RCT2_ADDRESS(0x0095AFB8, uint32)[format]);
+ }
+}
/**
* Writes a formatted string to a buffer.
@@ -32,7 +1386,8 @@
*/
void format_string(char *dest, rct_string_id format, void *args)
{
- RCT2_CALLPROC_X(0x006C2555, format, 0, (int)args, 0, 0, (int)dest, 0);
+ // RCT2_CALLPROC_X(0x006C2555, format, 0, (int)args, 0, 0, (int)dest, 0);
+ format_string_part(&dest, format, (char**)&args);
}
void generate_string_file()
@@ -61,14 +1416,24 @@ void generate_string_file()
case 11: fputs("{OUTLINE}", f); break;
case 34: fputs("{ENDQUOTES}", f); break;
+
case 123: fputs("{COMMA32}", f); break;
+ case 124: fputs("{INT32}", f); break;
case 125: fputs("{COMMA2DP32}", f); break;
case 126: fputs("{COMMA16}", f); break;
+ case 127: fputs("{UINT16}", f); break;
case 128: fputs("{CURRENCY2DP}", f); break;
case 129: fputs("{CURRENCY}", f); break;
- case 130: fputs("{STRING}", f); break;
+ case 130: fputs("{STRINGID}", f); break;
+ case 131: fputs("{STRINGID2}", f); break;
+ case 132: fputs("{STRING}", f); break;
case 133: fputs("{MONTHYEAR}", f); break;
+ case 134: fputs("{MONTH}", f); break;
case 135: fputs("{VELOCITY}", f); break;
+ case 136: fputs("{POP16}", f); break;
+ case 137: fputs("{PUSH16}", f); break;
+ case 138: fputs("{DURATION}", f); break;
+ case 139: fputs("{REALTIME}", f); break;
case 140: fputs("{LENGTH}", f); break;
case 141: fputs("{SPRITE}", f); break;
diff --git a/src/string_ids.h b/src/string_ids.h
index 76ce106940..928f7024dd 100644
--- a/src/string_ids.h
+++ b/src/string_ids.h
@@ -28,6 +28,7 @@ void generate_string_file();
void reset_saved_strings();
enum {
+ // Font format codes
FORMAT_TINYFONT = 7,
FORMAT_BIGFONT,
FORMAT_MEDIUMFONT,
@@ -35,19 +36,31 @@ enum {
FORMAT_OUTLINE,
+ // Non ascii-characters
FORMAT_ENDQUOTES = 34,
+ // Argument format codes
FORMAT_COMMA32 = 123,
- FORMAT_COMMA2DP32 = 125,
+ FORMAT_INT32,
+ FORMAT_COMMA2DP32,
FORMAT_COMMA16,
- FORMAT_CURRENCY2DP = 128,
+ FORMAT_UINT16,
+ FORMAT_CURRENCY2DP,
FORMAT_CURRENCY,
+ FORMAT_STRINGID,
+ FORMAT_STRINGID2,
FORMAT_STRING,
- FORMAT_MONTHYEAR = 133,
- FORMAT_VELOCITY = 135,
- FORMAT_LENGTH = 140,
- FORMAT_SPRITE = 141,
+ FORMAT_MONTHYEAR,
+ FORMAT_MONTH,
+ FORMAT_VELOCITY,
+ FORMAT_POP16,
+ FORMAT_PUSH16,
+ FORMAT_DURATION,
+ FORMAT_REALTIME,
+ FORMAT_LENGTH,
+ FORMAT_SPRITE,
+ // Colour format codes
FORMAT_BLACK = 142,
FORMAT_GREY,
FORMAT_WHITE,
@@ -63,6 +76,7 @@ enum {
FORMAT_PEARLAQUA,
FORMAT_PALESILVER,
+ // Extra non-ascii characters
FORMAT_AMINUSCULE = 159,
FORMAT_UP,
FORMAT_POUND = 163,
diff --git a/src/util.c b/src/util.c
index f330745a4d..6a151248c8 100644
--- a/src/util.c
+++ b/src/util.c
@@ -23,6 +23,20 @@
int squaredmetres_to_squaredfeet(int squaredMetres)
{
// 1 metre squared = 10.7639104 feet squared
- // how it is done in RCT2
+ // RCT2 approximates as 11
return squaredMetres * 11;
}
+
+int metres_to_feet(int metres)
+{
+ // 1 metre = 3.2808399 feet
+ // RCT2 approximates as 3.28125
+ return (metres * 840) / 256;
+}
+
+int mph_to_kmph(int mph)
+{
+ // 1 mph = 1.60934 kmph
+ // RCT2 approximates as 1.609375
+ return (mph * 1648) / 1024;
+}
\ No newline at end of file
diff --git a/src/util.h b/src/util.h
index e2c230ebdb..c93ac1cc69 100644
--- a/src/util.h
+++ b/src/util.h
@@ -22,5 +22,7 @@
#define _UTIL_H_
int squaredmetres_to_squaredfeet(int squaredMetres);
+int metres_to_feet(int metres);
+int mph_to_kmph(int mph);
#endif
diff --git a/src/window_options.c b/src/window_options.c
index 8206d69532..fbb9897940 100644
--- a/src/window_options.c
+++ b/src/window_options.c
@@ -283,7 +283,6 @@ static void window_options_mouseup()
static void window_options_mousedown()
{
int num_items, i;
- sint64 device;
short widgetIndex;
rct_window *w;
rct_widget *widget;
@@ -305,22 +304,14 @@ static void window_options_mousedown()
switch (widgetIndex) {
case WIDX_SOUND_DROPDOWN:
- num_items = RCT2_GLOBAL(RCT2_ADDRESS_NUM_DSOUND_DEVICES, uint32);
- if (num_items == 0)
- break;
-
- window_options_draw_dropdown_box(w, widget, num_items);
+ window_options_draw_dropdown_box(w, widget, gAudioDeviceCount);
// populate the list with the sound devices
- device = RCT2_GLOBAL(RCT2_ADDRESS_DSOUND_DEVICES, sint32) + 0x10;
-
- for (i = 0; i < num_items; i++) {
+ for (i = 0; i < gAudioDeviceCount; i++) {
gDropdownItemsFormat[i] = 1142;
- gDropdownItemsArgs[i] = 1170 | (device << 16);
- device += 0x210;
+ gDropdownItemsArgs[i] = 1170 | ((uint64)gAudioDevices[i].name << 16);
}
gDropdownItemsChecked |= (1 << RCT2_GLOBAL(0x9AF280, uint32));
-
break;
case WIDX_HEIGHT_LABELS_DROPDOWN:
window_options_draw_dropdown_box(w, widget, 2);
@@ -380,7 +371,7 @@ static void window_options_mousedown()
break;
case WIDX_RESOLUTION_DROPDOWN:
- RCT2_CALLPROC_EBPSAFE(0x006BB2AF);
+ // RCT2_CALLPROC_EBPSAFE(0x006BB2AF);
break;
case WIDX_TEMPERATURE_DROPDOWN:
window_options_draw_dropdown_box(w, widget, 2);
@@ -522,25 +513,19 @@ static void window_options_update(rct_window *w)
__asm__ ( "mov %[w], esi " : [w] "+m" (w) );
#endif
-
- sint32 format_args = RCT2_GLOBAL(0x009AF280, sint32);
+ sint32 currentSoundDevice = RCT2_GLOBAL(0x009AF280, sint32);
// sound devices
- if (format_args == -1 || RCT2_GLOBAL(RCT2_ADDRESS_NUM_DSOUND_DEVICES, sint32) == 0) {
+ if (currentSoundDevice == -1 || gAudioDeviceCount == 0) {
RCT2_GLOBAL(0x013CE952, uint16) = STR_SOUND_NONE;
} else {
- format_args = RCT2_GLOBAL(RCT2_ADDRESS_DSOUND_DEVICES, uint32) + format_args * 0x210 + 16;
RCT2_GLOBAL(0x013CE952, uint16) = 1170;
- RCT2_GLOBAL(0x013CE952 + 2, uint32) = format_args;
+ RCT2_GLOBAL(0x013CE952 + 2, uint32) = (uint32)gAudioDevices[currentSoundDevice].name;
}
// height: units/real values
- if ((RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) & CONFIG_FLAG_SHOW_HEIGHT_AS_UNITS))
- format_args = STR_UNITS;
- else
- format_args = STR_REAL_VALUES;
-
- RCT2_GLOBAL(0x013CE952 + 6, uint16) = (uint16)format_args;
+ RCT2_GLOBAL(0x013CE952 + 6, uint16) = ((RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) & CONFIG_FLAG_SHOW_HEIGHT_AS_UNITS)) ?
+ STR_UNITS : STR_REAL_VALUES;
// music: on/off
RCT2_GLOBAL(0x013CE952 + 8, uint16) = STR_OFF +