diff --git a/data/language/english_uk.txt b/data/language/english_uk.txt index 23535f2a06..a6b4cc889a 100644 --- a/data/language/english_uk.txt +++ b/data/language/english_uk.txt @@ -2526,6 +2526,7 @@ STR_2521 :Show staff list STR_2522 :Show recent messages STR_2523 :Show map STR_2524 :Screenshot +### The following need to be reordered to match SDL_keycode layout. STR_2525 :??? STR_2526 :??? STR_2527 :??? diff --git a/projects/openrct2.vcxproj b/projects/openrct2.vcxproj index 1abb35522e..1f0a9b9fb0 100644 --- a/projects/openrct2.vcxproj +++ b/projects/openrct2.vcxproj @@ -116,6 +116,8 @@ + + diff --git a/projects/openrct2.vcxproj.filters b/projects/openrct2.vcxproj.filters index 302dbb6407..f43a8744fd 100644 --- a/projects/openrct2.vcxproj.filters +++ b/projects/openrct2.vcxproj.filters @@ -358,10 +358,6 @@ - - Libraries\lodepng - - Libraries\libspeex @@ -375,6 +371,22 @@ Source\Windows + + + + Libraries\lodepng + + + + Libraries\libspeex + + + + Source\Windows + + + Source\Windows + diff --git a/src/audio/audio.h b/src/audio/audio.h index 39406d7cc7..292b22c5dd 100644 --- a/src/audio/audio.h +++ b/src/audio/audio.h @@ -31,7 +31,7 @@ typedef struct { extern int gAudioDeviceCount; extern audio_device *gAudioDevices; -#define AUDIO_MAX_VEHICLE_SOUNDS 50 +#define AUDIO_MAX_VEHICLE_SOUNDS 14 void audio_init(); void audio_quit(); diff --git a/src/audio/mixer.cpp b/src/audio/mixer.cpp index 65f8e7d76c..b98a4493db 100644 --- a/src/audio/mixer.cpp +++ b/src/audio/mixer.cpp @@ -272,6 +272,11 @@ void Mixer::Init(const char* device) void Mixer::Close() { + Lock(); + while (channels.begin() != channels.end()) { + Stop(*(*channels.begin())); + } + Unlock(); SDL_CloseAudioDevice(deviceid); delete[] effectbuffer; } @@ -329,7 +334,11 @@ void Mixer::MixChannel(Channel& channel, uint8* data, int length) int samplesize = format.channels * format.BytesPerSample(); int samples = length / samplesize; int samplesloaded = loaded / samplesize; - int samplestoread = (int)ceil((samples - samplesloaded) * channel.rate); + double rate = 1; + if (format.format == AUDIO_S16SYS) { + rate = channel.rate; + } + int samplestoread = (int)ceil((samples - samplesloaded) * rate); int lengthloaded = 0; if (channel.offset < channel.stream->Length()) { bool mustconvert = false; @@ -363,11 +372,10 @@ void Mixer::MixChannel(Channel& channel, uint8* data, int length) } bool effectbufferloaded = false; - - if (channel.rate != 1 && format.format == AUDIO_S16SYS) { + if (rate != 1 && format.format == AUDIO_S16SYS) { int in_len = (int)(ceil((double)lengthloaded / samplesize)); int out_len = samples + 20; // needs some extra, otherwise resampler sometimes doesn't process all the input samples - speex_resampler_set_rate(channel.resampler, format.freq, (int)(format.freq * (1 / channel.rate))); + speex_resampler_set_rate(channel.resampler, format.freq, (int)(format.freq * (1 / rate))); speex_resampler_process_interleaved_int(channel.resampler, (const spx_int16_t*)tomix, (spx_uint32_t*)&in_len, (spx_int16_t*)effectbuffer, (spx_uint32_t*)&out_len); effectbufferloaded = true; tomix = effectbuffer; @@ -386,7 +394,7 @@ void Mixer::MixChannel(Channel& channel, uint8* data, int length) break; case AUDIO_U8: EffectPanU8(channel, (uint8*)effectbuffer, lengthloaded / samplesize); - break; + break; } } @@ -493,15 +501,21 @@ void Mixer_Stop_Channel(void* channel) void Mixer_Channel_Volume(void* channel, int volume) { + gMixer.Lock(); ((Channel*)channel)->SetVolume(volume); + gMixer.Unlock(); } void Mixer_Channel_Pan(void* channel, float pan) { + gMixer.Lock(); ((Channel*)channel)->SetPan(pan); + gMixer.Unlock(); } void Mixer_Channel_Rate(void* channel, double rate) { + gMixer.Lock(); ((Channel*)channel)->SetRate(rate); + gMixer.Unlock(); } \ No newline at end of file diff --git a/src/config.h b/src/config.h index 8efcdd6e68..664d57eb58 100644 --- a/src/config.h +++ b/src/config.h @@ -153,6 +153,11 @@ static const struct { const char *key; int value; } _currencyLookupTable[] = { { "\xB5", CURRENCY_EUROS } }; +typedef struct shortcut_entry{ + uint8 key; + uint8 modifier; +}shortcut_entry; + //typedef struct hotkey_configuration{ //}; diff --git a/src/interface/window.h b/src/interface/window.h index f50202bb16..83adaa1489 100644 --- a/src/interface/window.h +++ b/src/interface/window.h @@ -476,6 +476,8 @@ void window_staff_list_open(); void window_guest_list_open(); void window_map_open(); void window_options_open(); +void window_shortcut_keys_open(); +void window_shortcut_change_open(int selected_key); void window_guest_open(rct_peep* peep); void window_staff_open(rct_peep* peep); void window_park_awards_open(); diff --git a/src/localisation/string_ids.h b/src/localisation/string_ids.h index 755918699f..ec9639b635 100644 --- a/src/localisation/string_ids.h +++ b/src/localisation/string_ids.h @@ -287,9 +287,9 @@ enum { STR_SLOPE_UP_TIP = 1188, STR_CONSTRUCT_THE_SELECTED_FOOTPATH_SECTION_TIP = 1189, STR_REMOVE_PREVIOUS_FOOTPATH_SECTION_TIP = 1190, - STR_COST = 1191, + STR_BLACK_STRING = 1191, STR_LOSS = 1192, - + STR_WINDOW_COLOUR_2_STRING = 1193, STR_CLOSED = 1194, STR_TEST_RUN = 1195, STR_OPEN = 1196, @@ -886,6 +886,15 @@ enum { STR_REAL_NAME_TIP = 2488, STR_HOTKEY = 2489, + STR_SHORTCUT_DESCRIPTION_0 = 2493, + + STR_SHORTCUT_DESCRIPTION_31 = 2524, + STR_INDIVIDUAL_KEYS_BASE = 2525, + + STR_SHORTCUT_ENTRY_FORMAT = 2781, + STR_SHIFT_PLUS = 2782, + STR_CTRL_PLUS = 2783, + STR_FINACNES_PARK_VALUE = 2787, STR_ENTER_NAME_INTO_SCENARIO_CHART = 2790, diff --git a/src/platform/osinterface.c b/src/platform/osinterface.c index 2e2c53a927..ed0090b4d4 100644 --- a/src/platform/osinterface.c +++ b/src/platform/osinterface.c @@ -69,6 +69,17 @@ void osinterface_init() // RCT2_CALLPROC(0x00404584); // dinput_init() } +int osinterface_scancode_to_rct_keycode(int sdl_key){ + char keycode = (char)SDL_GetKeyFromScancode((SDL_Scancode)sdl_key); + + // Until we reshufle the text files to use the new positions + // this will suffice to move the majority to the correct positions. + // Note any special buttons PgUp PgDwn are mapped wrong. + if (keycode >= 'a' && keycode <= 'z')keycode = toupper(keycode); + + return keycode; +} + /** * This is not quite the same as the below function as we don't want to * derfererence the cursor before the function. diff --git a/src/platform/osinterface.h b/src/platform/osinterface.h index be984b64d8..d88eead8bc 100644 --- a/src/platform/osinterface.h +++ b/src/platform/osinterface.h @@ -112,5 +112,6 @@ int osinterface_directory_exists(const char *path); int osinterface_ensure_directory_exists(const char *path); char osinterface_get_path_separator(); +int osinterface_scancode_to_rct_keycode(int sdl_key); #endif diff --git a/src/ride/vehicle.c b/src/ride/vehicle.c index b2ec9ccc47..fe7e9983fe 100644 --- a/src/ride/vehicle.c +++ b/src/ride/vehicle.c @@ -364,7 +364,7 @@ void vehicle_sounds_update() vehicle_sound->sound1_id = sprite->vehicle.sound1_id; #ifndef USE_MIXER RCT2_GLOBAL(0x014241BC, uint32) = 1; - sound_prepare(sprite->vehicle.var_BB, &vehicle_sound->sound1, 1, RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_SOUND_SW_BUFFER, uint32)); + sound_prepare(sprite->vehicle.sound1_id, &vehicle_sound->sound1, 1, RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_SOUND_SW_BUFFER, uint32)); RCT2_GLOBAL(0x014241BC, uint32) = 0; #endif vehicle_sound->sound1_pan = vehicle_sound_params->pan; @@ -461,7 +461,7 @@ void vehicle_sounds_update() vehicle_sound->sound2_id = sprite->vehicle.sound2_id; #ifndef USE_MIXER RCT2_GLOBAL(0x014241BC, uint32) = 1; - sound_prepare(sprite->vehicle.var_BD, &vehicle_sound->sound2, 1, RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_SOUND_SW_BUFFER, uint32)); + sound_prepare(sprite->vehicle.sound2_id, &vehicle_sound->sound2, 1, RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_SOUND_SW_BUFFER, uint32)); RCT2_GLOBAL(0x014241BC, uint32) = 0; #endif vehicle_sound->sound2_pan = vehicle_sound_params->pan; diff --git a/src/windows/options.c b/src/windows/options.c index 851f13cb7b..6676158173 100644 --- a/src/windows/options.c +++ b/src/windows/options.c @@ -285,7 +285,7 @@ static void window_options_mouseup() window_options_set_page(w, widgetIndex - WIDX_TAB_1); break; case WIDX_HOTKEY_DROPDOWN: - RCT2_CALLPROC_EBPSAFE(0x006E3884); + window_shortcut_keys_open(); break; case WIDX_SCREEN_EDGE_SCROLLING: RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_EDGE_SCROLLING, uint8) ^= 1; @@ -504,7 +504,11 @@ static void window_options_dropdown() case WIDX_SOUND_DROPDOWN: audio_init2(dropdownIndex); if (dropdownIndex < gAudioDeviceCount) { - Mixer_Init(gAudioDevices[dropdownIndex].name); + int devicenum = dropdownIndex; + if (devicenum == 0) { + devicenum = 1; + } + Mixer_Init(gAudioDevices[devicenum].name); } /*#ifdef _MSC_VER __asm movzx ax, dropdownIndex diff --git a/src/windows/ride.c b/src/windows/ride.c index 62e6be0746..6cec49b004 100644 --- a/src/windows/ride.c +++ b/src/windows/ride.c @@ -1891,7 +1891,7 @@ static rct_string_id window_ride_get_status_overall_view(rct_window *w, void *ar RCT2_GLOBAL((int)arguments + 2, uint32) = argument; stringId = STR_LOSS; if (formatSecondary != STR_BROKEN_DOWN && formatSecondary != STR_CRASHED) - stringId = STR_COST; + stringId = STR_BLACK_STRING; return stringId; } diff --git a/src/windows/shortcut_key_change.c b/src/windows/shortcut_key_change.c new file mode 100644 index 0000000000..fe735a7a6b --- /dev/null +++ b/src/windows/shortcut_key_change.c @@ -0,0 +1,128 @@ +/***************************************************************************** +* Copyright (c) 2014 Ted John, Duncan Frost +* OpenRCT2, an open source clone of Roller Coaster Tycoon 2. +* +* This file is part of OpenRCT2. +* +* OpenRCT2 is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. + +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. + +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*****************************************************************************/ + +#include "../addresses.h" +#include "../config.h" +#include "../interface/window.h" +#include "../interface/widget.h" +#include "../localisation/localisation.h" + +#define WW 250 +#define WH 60 + +enum WINDOW_SHORTCUT_CHANGE_WIDGET_IDX { + WIDX_BACKGROUND, + WIDX_TITLE, + WIDX_CLOSE, +}; + +// 0x9DE4E0 +static rct_widget window_shortcut_change_widgets[] = { + { WWT_FRAME, 0, 0, WW - 1, 0, WH - 1, STR_NONE, STR_NONE }, + { WWT_CAPTION, 0, 1, WW - 2, 1, 14, STR_OPTIONS, STR_WINDOW_TITLE_TIP }, + { WWT_CLOSEBOX, 0, WW-13, WW - 3, 2, 13, STR_CLOSE_X, STR_CLOSE_WINDOW_TIP }, + { WIDGETS_END } +}; + +static void window_shortcut_change_emptysub(){} +static void window_shortcut_change_mouseup(); +static void window_shortcut_change_paint(); + +//0x9A3F7C +static void* window_shortcut_change_events[] = { + window_shortcut_change_emptysub, + window_shortcut_change_mouseup, + window_shortcut_change_emptysub, + window_shortcut_change_emptysub, + window_shortcut_change_emptysub, + window_shortcut_change_emptysub, + window_shortcut_change_emptysub, + window_shortcut_change_emptysub, + window_shortcut_change_emptysub, + window_shortcut_change_emptysub, + window_shortcut_change_emptysub, + window_shortcut_change_emptysub, + window_shortcut_change_emptysub, + window_shortcut_change_emptysub, + window_shortcut_change_emptysub, + window_shortcut_change_emptysub, + window_shortcut_change_emptysub, + window_shortcut_change_emptysub, + window_shortcut_change_emptysub, + window_shortcut_change_emptysub, + window_shortcut_change_emptysub, + window_shortcut_change_emptysub, + window_shortcut_change_emptysub, + window_shortcut_change_emptysub, + window_shortcut_change_emptysub, + window_shortcut_change_emptysub, + window_shortcut_change_paint, + window_shortcut_change_emptysub +}; + +void window_shortcut_change_open(int selected_key){ + // Move this to window_shortcut_change_open + window_close_by_id(WC_CHANGE_KEYBOARD_SHORTCUT, 0); + // Save the item we are selecting for new window + RCT2_GLOBAL(0x9DE511, uint8) = selected_key; + rct_window* w = window_create_auto_pos(WW, WH, (uint32*)window_shortcut_change_events, WC_CHANGE_KEYBOARD_SHORTCUT, 0); + + w->widgets = window_shortcut_change_widgets; + w->enabled_widgets = (1 << 2); + window_init_scroll_widgets(w); + w->colours[0] = 7; + w->colours[1] = 7; + w->colours[2] = 7; +} + +/** +* +* rct2: 0x006E3AE0 +*/ +static void window_shortcut_change_mouseup(){ + short widgetIndex; + rct_window *w; + + window_widget_get_registers(w, widgetIndex); + + switch (widgetIndex){ + case WIDX_CLOSE: + window_close(w); + } +} + +/** +* +* rct2: 0x006E3A9F +*/ +static void window_shortcut_change_paint(){ + rct_window *w; + rct_drawpixelinfo *dpi; + + window_paint_get_registers(w, dpi); + + window_draw_widgets(w, dpi); + + int x = w->x + 125; + int y = w->y + 30; + + RCT2_GLOBAL(0x13CE952, uint16) = 2493 + RCT2_GLOBAL(0x9DE511, uint8); + gfx_draw_string_centred_wrapped(dpi, (void*)0x13CE952, x, y, 242, 2785, RCT2_GLOBAL(0x9DEB8D, uint8)); +} \ No newline at end of file diff --git a/src/windows/shortcut_keys.c b/src/windows/shortcut_keys.c new file mode 100644 index 0000000000..29d8be2032 --- /dev/null +++ b/src/windows/shortcut_keys.c @@ -0,0 +1,275 @@ +/***************************************************************************** +* Copyright (c) 2014 Ted John, Duncan Frost +* OpenRCT2, an open source clone of Roller Coaster Tycoon 2. +* +* This file is part of OpenRCT2. +* +* OpenRCT2 is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. + +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. + +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*****************************************************************************/ + +#include "../addresses.h" +#include "../config.h" +#include "../interface/window.h" +#include "../interface/widget.h" +#include "../localisation/localisation.h" +#include "../platform/osinterface.h" + +#define WW 340 +#define WH 240 + +enum WINDOW_SHORTCUT_WIDGET_IDX { + WIDX_BACKGROUND, + WIDX_TITLE, + WIDX_CLOSE, + WIDX_SCROLL, + WIDX_RESET +}; + +// 0x9DE48C +static rct_widget window_shortcut_widgets[] = { + { WWT_FRAME, 0, 0, WW - 1, 0, WH - 1, STR_NONE, STR_NONE }, + { WWT_CAPTION, 0, 1, WW - 2, 1, 14, STR_OPTIONS, STR_WINDOW_TITLE_TIP }, + { WWT_CLOSEBOX, 0, WW-13, WW - 3, 2, 13, STR_CLOSE_X, STR_CLOSE_WINDOW_TIP }, + { WWT_SCROLL, 0, 4, WW - 5, 18, WH - 18, 2, 2786 }, + { WWT_DROPDOWN_BUTTON, 0, 4, 153, WH-15, WH - 4, 2491, 2492 }, + { WIDGETS_END } +}; + +void window_shortcut_emptysub() { } +static void window_shortcut_mouseup(); +static void window_shortcut_paint(); +static void window_shortcut_tooltip(); +static void window_shortcut_scrollgetsize(); +static void window_shortcut_scrollmousedown(); +static void window_shortcut_scrollmouseover(); +static void window_shortcut_scrollpaint(); + +static void* window_shortcut_events[] = { + window_shortcut_emptysub, + window_shortcut_mouseup, + window_shortcut_emptysub, + window_shortcut_emptysub, + window_shortcut_emptysub, + window_shortcut_emptysub, + window_shortcut_emptysub, + window_shortcut_emptysub, + window_shortcut_emptysub, + window_shortcut_emptysub, + window_shortcut_emptysub, + window_shortcut_emptysub, + window_shortcut_emptysub, + window_shortcut_emptysub, + window_shortcut_emptysub, + window_shortcut_scrollgetsize, + window_shortcut_scrollmousedown, + window_shortcut_emptysub, + window_shortcut_scrollmouseover, + window_shortcut_emptysub, + window_shortcut_emptysub, + window_shortcut_emptysub, + window_shortcut_tooltip, + window_shortcut_emptysub, + window_shortcut_emptysub, + window_shortcut_emptysub, + window_shortcut_paint, + window_shortcut_scrollpaint +}; + +/** + * + * rct2: 0x006E3884 + */ +void window_shortcut_keys_open() +{ + rct_window* w; + + w = window_bring_to_front_by_id(WC_KEYBOARD_SHORTCUT_LIST, 0); + + if (w) return; + + w = window_create_auto_pos(WW, WH, (uint32*)window_shortcut_events, WC_KEYBOARD_SHORTCUT_LIST, 0); + + w->widgets = window_shortcut_widgets; + w->enabled_widgets = (1 << WIDX_CLOSE) | (1 << WIDX_RESET); + window_init_scroll_widgets(w); + + w->colours[0] = 7; + w->colours[1] = 7; + w->colours[2] = 7; + w->no_list_items = 32; + w->selected_list_item = -1; +} + +/** +* +* rct2: 0x006E39E4 +*/ +static void window_shortcut_mouseup() +{ + short widgetIndex; + rct_window *w; + + window_widget_get_registers(w, widgetIndex); + + switch (widgetIndex){ + case WIDX_CLOSE: + window_close(w); + break; + case WIDX_RESET: + config_reset_shortcut_keys(); + config_save(); + window_invalidate(w); + break; + } +} + +/** +* +* rct2: 0x006E38E0 +*/ +static void window_shortcut_paint() +{ + rct_window *w; + rct_drawpixelinfo *dpi; + + window_paint_get_registers(w, dpi); + + window_draw_widgets(w, dpi); +} + +/** +* +* rct2: 0x006E3A0C +*/ +static void window_shortcut_tooltip() +{ + RCT2_GLOBAL(0x013CE952, uint16) = STR_LIST; +} + +/** +* +* rct2: 0x006E3A07 +*/ +static void window_shortcut_scrollgetsize() +{ + int y; + rct_window *w; + window_get_register(w); + + y = 32 * 10; + +#ifdef _MSC_VER + __asm mov edx, y +#else + __asm__("mov edx, %[y] " : [y] "+m" (y)); +#endif +} + +/** +* +* rct2: 0x006E3A3E +*/ +static void window_shortcut_scrollmousedown() +{ + short x, y; + rct_window *w; + + window_scrollmouse_get_registers(w, x, y); + + int selected_item = y / 10; + + if (selected_item >= w->no_list_items)return; + + window_shortcut_change_open(selected_item); +} + +/** +* +* rct2: 0x006E3A16 +*/ +static void window_shortcut_scrollmouseover() +{ + short x, y; + rct_window *w; + + window_scrollmouse_get_registers(w, x, y); + + int selected_item = y / 10; + + if (selected_item >= w->no_list_items)return; + + w->selected_list_item = selected_item; + + window_invalidate(w); +} + +/** + * + * rct2: 0x006E38E6 + */ +static void window_shortcut_scrollpaint() +{ + rct_window *w; + rct_drawpixelinfo *dpi; + + window_paint_get_registers(w, dpi); + + gfx_fill_rect(dpi, dpi->x, dpi->y, dpi->x + dpi->width - 1, dpi->y + dpi->height - 1, RCT2_ADDRESS(0x0141FC48,uint8)[w->colours[1] * 8]); + + for (int i = 0; i < w->no_list_items; ++i){ + int y = i * 10; + if (y > dpi->y + dpi->height) { + break; + } + if (y + 10 < dpi->y)continue; + int format = STR_BLACK_STRING; + if (i == w->selected_list_item){ + format = STR_WINDOW_COLOUR_2_STRING; + gfx_fill_rect(dpi, 0, y, 800, y + 9, 0x2000031); + } + + RCT2_GLOBAL(0x13CE954, uint16) = i + STR_SHORTCUT_DESCRIPTION_0; + RCT2_GLOBAL(0x13CE956, uint16) = 0; + RCT2_GLOBAL(0x13CE958, uint16) = 0; + + // This is the original version that will not take into account remapped keys. + //shortcut_entry sc_entry = RCT2_ADDRESS(RCT2_ADDRESS_CONFIG_KEYBOARD_SHORTCUTS, shortcut_entry)[i]; + //if (sc_entry.key != 255){ + // RCT2_GLOBAL(0x13CE958, uint16) = sc_entry.key + 2525; + // if (sc_entry.modifier){ + // RCT2_GLOBAL(0x13CE956, uint16) = 2782; + // if (sc_entry.key != 1){ + // RCT2_GLOBAL(0x13CE956, uint16) = 2783; + // } + // } + //} + + uint16 shortcut_entry = gShortcutKeys[i]; + if (shortcut_entry != 0xFFFF){ + RCT2_GLOBAL(0x13CE958, uint16) = STR_INDIVIDUAL_KEYS_BASE + osinterface_scancode_to_rct_keycode(shortcut_entry & 0xFF); + //Display the modifer + if (shortcut_entry & 0x100){ + RCT2_GLOBAL(0x13CE956, uint16) = STR_SHIFT_PLUS; + } + else if (shortcut_entry & 0x200){ + RCT2_GLOBAL(0x13CE956, uint16) = STR_CTRL_PLUS; + } + } + + + RCT2_GLOBAL(0x13CE952, uint16) = STR_SHORTCUT_ENTRY_FORMAT; + + gfx_draw_string_left(dpi, format, (void*)0x13CE952, 0, 0, y - 1); + } +} \ No newline at end of file