diff --git a/src/map.c b/src/map.c index ac086487e4..f654935c4a 100644 --- a/src/map.c +++ b/src/map.c @@ -138,7 +138,9 @@ void map_update_tile_pointers() /** * Return the absolute height of an element, given its (x,y) coordinates - * + * ax: x + * cx: y + * dx: return * rct2: 0x00662783 */ int map_element_height(int x, int y) diff --git a/src/sprite.c b/src/sprite.c index c2c80cb5dd..96dbdc4596 100644 --- a/src/sprite.c +++ b/src/sprite.c @@ -104,4 +104,48 @@ void reset_0x69EBE4(){ spr->unknown.var_02 = ax; } } +} + +/* +* rct2: 0x0069EC6B +* bl: unclear what this does +*/ +rct_sprite *create_sprite(uint8 bl) +{ + int ecx = 0xA; + + if ((bl & 2 != 0)) + { + // 69EC96; + uint16 cx = 0x12C - RCT2_GLOBAL(0x13573CE, uint16); + if (cx >= RCT2_GLOBAL(0x13573C8, uint16)) + { + return NULL; + } + + ecx = 6; + } + else if (RCT2_GLOBAL(0x13573C8, uint16) <= 0) + { + return NULL; + } + + rct_unk_sprite *sprite = &g_sprite_list[RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_NEXT_INDEX, uint16)]; + + RCT2_CALLPROC_X(0x0069ED0B, 0, 0, ecx, 0, (int)sprite, 0, 0); + + sprite->x = SPRITE_LOCATION_NULL; + sprite->y = SPRITE_LOCATION_NULL; + sprite->z = 0; + sprite->name_string_idx = 0; + sprite->var_14 = 0x10; + sprite->pad_09 = 0x14; + sprite->var_15 = 0x8; + sprite->pad_0C[0] = 0x0; + sprite->var_16 = SPRITE_LOCATION_NULL; + + sprite->var_02 = RCT2_GLOBAL(0xF3EF60, uint16); + RCT2_GLOBAL(0xF3EF60, uint16) = sprite->sprite_index; + + return sprite; } \ No newline at end of file diff --git a/src/sprite.h b/src/sprite.h index 701d448cbc..81f6955956 100644 --- a/src/sprite.h +++ b/src/sprite.h @@ -49,12 +49,15 @@ typedef struct { sint16 x; // 0x0E sint16 y; // 0x10 sint16 z; // 0x12 - uint16 pad_14; + uint8 var_14; // 0x14 + uint8 var_15; // 0x15 sint16 var_16; //x related sint16 var_18; //y related sint16 var_1A; //x related sint16 var_1C; //y related - uint8 sprite_direction; //direction of sprite? + uint8 sprite_direction; //direction of sprite? 0x1e + uint8 pad_1F[3]; // 0x1f + uint16 name_string_idx; // 0x22 } rct_unk_sprite; typedef struct { @@ -86,6 +89,7 @@ typedef union { extern rct_sprite* g_sprite_list; void create_balloon(int x, int y, int z, int colour); +rct_sprite *create_sprite(uint8 bl); void reset_sprite_list(); void reset_0x69EBE4(); diff --git a/src/staff.c b/src/staff.c index 1e0bc041cb..4fe6e6eb68 100644 --- a/src/staff.c +++ b/src/staff.c @@ -111,14 +111,12 @@ void game_command_hire_new_staff_member(int* eax, int* ebx, int* ecx, int* edx, int newStaffId = i; - int _eax, _ebx, _ecx = _cx, _edx, _esi, _edi, _ebp; - _esi = 0; + int _eax, _ebx, _ecx = _cx, _edx, _edi, _ebp; _ebx = _bl; - RCT2_CALLFUNC_X(0x0069EC6B, &_eax, &_ebx, &_ecx, &_edx, &_esi, &_edi, &_ebp); - rct_peep* newPeep = (rct_peep*)_esi; - //if ((newPeep = create_peep_sprite(_bl)) == NULL) - if (_esi == 0) + rct_peep* newPeep = create_sprite(_bl); + + if (newPeep == NULL) { *ebx = 0x80000000; RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = STR_TOO_MANY_PEOPLE_IN_GAME; diff --git a/src/viewport.c b/src/viewport.c index e47bc4f653..d39bf92a8d 100644 --- a/src/viewport.c +++ b/src/viewport.c @@ -113,19 +113,19 @@ void center_2d_coordinates(int x, int y, int z, int* out_x, int* out_y, rct_view switch (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32)){ case 0: x = y - x; - y = y / 2 + start_x / 2 - z; + y = (y + start_x) / 2 - z; break; case 1: x = -y - x; - y = y / 2 - start_x / 2 - z; + y = (y - start_x) / 2 - z; break; case 2: x = -y + x; - y = -y / 2 - start_x / 2 - z; + y = (-y - start_x) / 2 - z; break; case 3: x = y + x; - y = -y / 2 + start_x / 2 - z; + y = (-y + start_x) / 2 - z; break; } @@ -221,8 +221,8 @@ void viewport_update_pointers() *vp = NULL; } -void sub_689174(sint16* x, sint16* y, uint8 curr_rotation){ - //RCT2_CALLFUNC_X(0x00689174, (int*)&x, (int*)&y, &ecx, &curr_rotation, (int*)&window, (int*)&viewport, &ebp); +void sub_689174(sint16* x, sint16* y, sint16 *z, uint8 curr_rotation){ + //RCT2_CALLFUNC_X(0x00689174, (int*)&x, (int*)&y, (int*)&z, &curr_rotation, (int*)&window, (int*)&viewport, &ebp); sint16 start_x = *x; sint16 start_y = *y; @@ -262,6 +262,7 @@ void sub_689174(sint16* x, sint16* y, uint8 curr_rotation){ } break; } + *z = height; } /** @@ -296,11 +297,12 @@ void viewport_update_position(rct_window *window) sint16 x = viewport->view_width / 2 + window->saved_view_x; sint16 y = viewport->view_height / 2 + window->saved_view_y; + sint16 z; int curr_rotation = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32); - sub_689174(&x, &y, curr_rotation); + sub_689174(&x, &y, &z, curr_rotation); - RCT2_CALLPROC_X(0x006E7A15, x, y, 0, 0, (int)window, (int)viewport, 0); + RCT2_CALLPROC_X(0x006E7A15, x, y, z, 0, (int)window, (int)viewport, 0); //Clamp to the map minimum value int at_map_edge = 0; diff --git a/src/viewport.h b/src/viewport.h index 9b709f8d03..dfbcfb8c5c 100644 --- a/src/viewport.h +++ b/src/viewport.h @@ -47,11 +47,14 @@ enum { extern rct_viewport* g_viewport_list; void viewport_init_all(); +void center_2d_coordinates(int x, int y, int z, int* out_x, int* out_y, rct_viewport* viewport); void viewport_create(rct_window *w, int x, int y, int width, int height, int zoom, int center_x, int center_y, int center_z, char flags, sint16 sprite); void viewport_update_pointers(); void viewport_update_position(rct_window *window); void viewport_render(rct_drawpixelinfo *dpi, rct_viewport *viewport, int left, int top, int right, int bottom); +void sub_689174(sint16* x, sint16* y, sint16 *z, uint8 curr_rotation); + void screen_pos_to_map_pos(short *x, short *y); void show_gridlines(); diff --git a/src/window.c b/src/window.c index 4351d90d1a..af22ebfc4a 100644 --- a/src/window.c +++ b/src/window.c @@ -21,7 +21,9 @@ #include #include "addresses.h" #include "audio.h" +#include "game.h" #include "gfx.h" +#include "map.h" #include "osinterface.h" #include "rct2.h" #include "widget.h" @@ -963,7 +965,49 @@ void window_scroll_to_location(rct_window *w, int x, int y, int z) */ void window_rotate_camera(rct_window *w) { - RCT2_CALLPROC_X(0x0068881A, 0, 0, 0, 0, (int)w, 0, 0); + //RCT2_CALLPROC_X(0x0068881A, 0, 0, 0, 0, (int)w, 0, 0); + + rct_viewport *viewport = w->viewport; + if (viewport == NULL) + return; + + sint16 x = (viewport->width >> 1) + viewport->x; + sint16 y = (viewport->height >> 1) + viewport->y; + sint16 z; + + uint8 rot = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint8); + + int ecx, edx, esi, edi = (int)viewport, ebp; + //has something to do with checking if middle of the viewport is obstructed + RCT2_CALLFUNC_X(0x00688972, (int*)&x, (int*)&y, &ecx, &edx, &esi, &edi, &ebp); + rct_viewport *other = (rct_viewport*)edi; + + // other != viewport probably triggers on viewports in ride or guest window? + // x is 0x8000 if middle of viewport is obstructed by another window? + if (x == (sint16)SPRITE_LOCATION_NULL || other != viewport){ + x = (viewport->view_width >> 1) + viewport->view_x; + y = (viewport->view_height >> 1) + viewport->view_y; + + sub_689174(&x, &y, &z, rot); + } else { + z = map_element_height(x, y); + } + + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32) = (rot + 1) % 4; + + int new_x, new_y; + center_2d_coordinates(x, y, z, &new_x, &new_y, viewport); + + w->saved_view_x = new_x; + w->saved_view_y = new_y; + viewport->view_x = new_x; + viewport->view_y = new_y; + + window_invalidate(w); + + RCT2_CALLPROC_EBPSAFE(0x00688956); + + sub_0x0069E9A7(); } /**