WIP standardize mouse position translation

This commit is contained in:
2025-04-09 22:05:14 -05:00
parent 4041d0c1b2
commit a53650f737
7 changed files with 98 additions and 53 deletions

View File

@@ -1402,6 +1402,30 @@ void update_item_stats_area(bool& need_reprint) {
need_reprint = true;
}
location mouse_window_coords() {
location where_curs = sf::Mouse::getPosition(mainPtr());
where_curs = mainPtr().mapPixelToCoords(where_curs, mainView);
return where_curs;
}
bool mouse_to_terrain_coords(location& out_loc, bool relative) {
rectangle on_screen_terrain_area = win_to_rects[WINRECT_TERVIEW];
on_screen_terrain_area.inset(13, 13);
location where_curs = mouse_window_coords();
if(where_curs.in(on_screen_terrain_area)) {
out_loc.x = (where_curs.x - on_screen_terrain_area.left) / 28;
out_loc.y = (where_curs.y - on_screen_terrain_area.top) / 36;
if(!relative){
out_loc.x += center.x - 4;
out_loc.y += center.y - 4;
}
return true;
}
return false;
}
bool handle_action(const sf::Event& event, cFramerateLimiter& fps_limiter) {
long item_hit;
bool are_done = false;
@@ -1414,8 +1438,8 @@ bool handle_action(const sf::Event& event, cFramerateLimiter& fps_limiter) {
location point_in_area;
location the_point(event.mouseButton.x, event.mouseButton.y);
the_point = mainPtr().mapPixelToCoords(the_point, mainView);
location the_point = mouse_window_coords();
end_scenario = false;
// MARK: First, figure out where party is
@@ -1521,9 +1545,10 @@ bool handle_action(const sf::Event& event, cFramerateLimiter& fps_limiter) {
}
// MARK: Begin: click in terrain
if(the_point.in(world_screen) && (is_out() || is_town() || is_combat())){
int i = (the_point.x - 32) / 28;
int j = (the_point.y - 20) / 36;
location tile;
if(mouse_to_terrain_coords(tile, true) && (is_out() || is_town() || is_combat())){
int i = tile.x;
int j = tile.y;
location destination = cur_loc;
auto look_destination = [i, j, destination]() {
location look_dest = destination;
@@ -1543,7 +1568,7 @@ bool handle_action(const sf::Event& event, cFramerateLimiter& fps_limiter) {
else if(overall_mode == MODE_OUTDOORS || overall_mode == MODE_TOWN || overall_mode == MODE_COMBAT) {
if((i == 4) & (j == 4)) handle_pause(did_something, need_redraw);
else {
cur_direction = get_cur_direction(the_point);
cur_direction = get_cur_direction();
destination.x += cur_direction.x;
destination.y += cur_direction.y;
handle_move(destination, did_something, need_redraw, need_reprint);
@@ -3620,28 +3645,41 @@ void start_tutorial() {
// TODO start the tutorial scenario, which we need to design.
}
location get_cur_direction(location the_point) {
location store_dir;
location get_cur_direction() {
location mouse = mouse_window_coords();
sf::Vector2f mouseV(mouse.x, mouse.y);
rectangle on_screen_terrain_area = win_to_rects[WINRECT_TERVIEW];
on_screen_terrain_area.inset(13, 13);
location ter_screen_center = {(on_screen_terrain_area.left + on_screen_terrain_area.right) / 2, (on_screen_terrain_area.top + on_screen_terrain_area.bottom) / 2};
sf::Vector2f centerV(ter_screen_center.x, ter_screen_center.y);
sf::Vector2f offset = mouseV - centerV;
float angle = 22.5 + std::atan2(-offset.y, offset.x) * 180.0 / 3.14159;
if(angle < 0) angle += 360.0;
if(angle > 360) angle -= 360;
// This is a kludgy adjustment to adjust for the screen shifting between Exile I & II
the_point.x += 5;
the_point.y += 5;
if((the_point.x < 135) & (the_point.y >= ((the_point.x * 34) / 10) - 293)
& (the_point.y <= (-1 * ((the_point.x * 34) / 10) + 663)))
store_dir.x--;
if((the_point.x > 163) & (the_point.y <= ((the_point.x * 34) / 10) - 350)
& (the_point.y >= (-1 * ((the_point.x * 34) / 10) + 721)))
store_dir.x++;
if((the_point.y < 167) & (the_point.y <= (the_point.x / 2) + 102)
& (the_point.y <= (-1 * (the_point.x / 2) + 249)))
store_dir.y--;
if((the_point.y > 203) & (the_point.y >= (the_point.x / 2) + 123)
& (the_point.y >= (-1 * (the_point.x / 2) + 268)))
store_dir.y++;
return store_dir;
float unit = 45;
switch((int)(angle / unit)){
case 0:
return {1, 0};
case 1:
return {1, -1};
case 2:
return {0, -1};
case 3:
return {-1, -1};
case 4:
return {-1, 0};
case 5:
return {-1, 1};
case 6:
return {0, 1};
case 7:
return {1, 1};
case 8:
return {1, 0};
}
}
static eDirection find_waterfall(short x, short y, short mode){

View File

@@ -15,6 +15,10 @@ struct key_action_t {
};
void init_screen_locs();
location mouse_window_coords();
// If the mouse is in the terrain window, set the given location to the hovered tile.
// Return false if mouse is out of bounds.
bool mouse_to_terrain_coords(location& location, bool relative);
bool prime_time();
bool handle_action(const sf::Event& event, cFramerateLimiter& fps_limiter);
void advance_time(bool did_something, bool need_redraw, bool need_reprint);
@@ -38,7 +42,7 @@ void new_party();
void handle_death();
void start_new_game(bool force = false);
void start_tutorial();
location get_cur_direction(location the_point);
location get_cur_direction();
void outd_move_to_first_town_entrance(int town);
bool outd_move_party(location destination,bool forced);
bool town_move_party(location destination,short forced);

View File

@@ -77,6 +77,9 @@ extern std::string save_talk_str1, save_talk_str2;
extern cDrawableManager drawable_mgr;
extern void close_map(bool record = false);
extern location mouse_window_coords();
extern bool mouse_to_terrain_coords(location& out_loc, bool relative);
rectangle menuBarRect;
Region originalGrayRgn, newGrayRgn, underBarRgn;
sf::View mainView;
@@ -507,14 +510,12 @@ bool arrow_button_click(rectangle button_rect, cFramerateLimiter* fps_limiter) {
while(pollEvent(mainPtr(), e)){
if(e.type == sf::Event::MouseButtonReleased){
done = true;
location clickPos(e.mouseButton.x, e.mouseButton.y);
clickPos = mainPtr().mapPixelToCoords(clickPos);
location clickPos = mouse_window_coords();
clicked = button_rect.contains(clickPos);
depressed = false;
break;
} else if(e.type == sf::Event::MouseMoved){
location toPos(e.mouseMove.x, e.mouseMove.y);
toPos = mainPtr().mapPixelToCoords(toPos);
location toPos = mouse_window_coords();
depressed = button_rect.contains(toPos);
}
}
@@ -608,7 +609,7 @@ void redraw_screen(int refresh) {
draw_targets(center);
if(overall_mode != MODE_STARTUP) {
if(!is_out())
draw_targeting_line(sf::Mouse::getPosition(mainPtr()));
draw_targeting_line();
refresh_stat_areas(0);
}
done_btn->draw();
@@ -616,6 +617,8 @@ void redraw_screen(int refresh) {
drawable_mgr.draw_all();
extern location get_cur_direction();
get_cur_direction();
mainPtr().display();
}
@@ -1648,26 +1651,20 @@ void erase_spot(short i,short j) {
}
void draw_targeting_line(location where_curs) {
void draw_targeting_line() {
location which_space,store_loc;
rectangle target_rect;
location from_loc;
rectangle on_screen_terrain_area = win_to_rects[WINRECT_TERVIEW];
on_screen_terrain_area.inset(13, 13);
where_curs = mainPtr().mapPixelToCoords(where_curs, mainView);
location where_curs = mouse_window_coords();
if(overall_mode >= MODE_COMBAT)
from_loc = univ.current_pc().combat_pos;
else from_loc = univ.party.town_loc;
if((overall_mode == MODE_SPELL_TARGET) || (overall_mode == MODE_FIRING) || (overall_mode == MODE_THROWING) || (overall_mode == MODE_FANCY_TARGET)
|| ((overall_mode == MODE_TOWN_TARGET) && (current_pat[4][4] != 0))) {
if(where_curs.in(on_screen_terrain_area)) {
// && (point_onscreen(center,univ.party[current_pc].combat_pos))){
which_space.x = center.x + (where_curs.x - 37) / 28 - 4;
which_space.y = center.y + (where_curs.y - 25) / 36 - 4;
if(mouse_to_terrain_coords(which_space, false)) {
int xBound = (short) (from_loc.x - center.x + 4);
int yBound = (short) (from_loc.y - center.y + 4);
xBound = (xBound * 28) + 46;

View File

@@ -55,7 +55,7 @@ void redraw_terrain();
void draw_targets(location center);
void frame_space(location where,short mode,short width,short height);
void erase_spot(short i,short j);
void draw_targeting_line(location where_curs);
void draw_targeting_line();
void redraw_partial_terrain(rectangle redraw_rect);
bool is_nature(short i, short j, unsigned short ground_t);
void put_dialog_graphic(short graphic_num,short spec_g,rectangle draw_rect);

View File

@@ -1372,7 +1372,7 @@ void handle_one_event(const sf::Event& event, cFramerateLimiter& fps_limiter) {
check_window_moved(mainPtr(), last_window_x, last_window_y, "MainWindow");
main_window_gained_focus = true;
makeFrontWindow(mainPtr());
change_cursor({event.mouseMove.x, event.mouseMove.y});
change_cursor();
return;
case sf::Event::LostFocus:
@@ -1381,7 +1381,7 @@ void handle_one_event(const sf::Event& event, cFramerateLimiter& fps_limiter) {
case sf::Event::MouseMoved:
check_window_moved(mainPtr(), last_window_x, last_window_y, "MainWindow");
change_cursor({event.mouseMove.x, event.mouseMove.y});
change_cursor();
return;
// TODO: EVENT TYPE DEPRECATED IN SFML 2.5.1
@@ -1667,22 +1667,28 @@ static cursor_type get_mode_cursor(){
return sword_curs; // this should never be reached, though
}
void change_cursor(location where_curs) {
void change_cursor() {
cursor_type cursor_needed;
location where_curs = mouse_window_coords();
location cursor_direction;
extern enum_map(eGuiArea, rectangle) win_to_rects;
rectangle world_screen = win_to_rects[WINRECT_TERVIEW];
world_screen.inset(13, 13);
where_curs = mainPtr().mapPixelToCoords(where_curs, mainView);
if(!world_screen.contains(where_curs))
cursor_needed = sword_curs;
else cursor_needed = get_mode_cursor();
if((overall_mode == MODE_OUTDOORS || overall_mode == MODE_TOWN || overall_mode == MODE_COMBAT) && world_screen.contains(where_curs)){
cursor_direction = get_cur_direction(where_curs);
cursor_needed = arrow_curs[cursor_direction.y + 1][cursor_direction.x + 1];
location tile;
mouse_to_terrain_coords(tile, true);
if(tile.x != 4 || tile.y != 4){
cursor_direction = get_cur_direction();
LOG_VALUE(get_cur_direction());
cursor_needed = arrow_curs[cursor_direction.y + 1][cursor_direction.x + 1];
}else{
cursor_needed = wait_curs;
}
}
if(cursor_needed != Cursor::current)

View File

@@ -11,7 +11,7 @@ void redraw_everything();
eKeyMod current_key_mod();
void Mouse_Pressed(const sf::Event&, cFramerateLimiter& fps_limiter);
void close_program();
void change_cursor(location where_curs);
void change_cursor();
void set_up_apple_events();
void move_sound(ter_num_t ter,short step);
void incidental_noises(bool on_surface);

View File

@@ -119,7 +119,7 @@ void handle_startup_button_click(eStartButton btn, eKeyMod mods) {
// TODO: Always returns false, so make it void
bool handle_startup_press(location the_point) {
the_point = mainPtr().mapPixelToCoords(the_point, mainView);
the_point = mouse_window_coords();
for(auto btn : startup_button.keys()) {
if(btn == eStartButton::STARTBTN_SCROLL) continue;