3 Commits 7fdaceb623 ... 0de23ce367

Author SHA1 Message Date
  Clément Wolf 0de23ce367 Add ability to get spectated 4 months ago
  Clément Wolf de850d54c3 Make osu a global, as it should be 4 months ago
  Clément Wolf 633a8ed263 Remove multi-instance code 4 months ago
100 changed files with 2158 additions and 2706 deletions
  1. 1 0
      Makefile
  2. 3 4
      src/App/Osu/BackgroundStarCacheLoader.cpp
  3. 75 66
      src/App/Osu/Bancho.cpp
  4. 2 2
      src/App/Osu/Bancho.h
  5. 4 5
      src/App/Osu/BanchoLeaderboard.cpp
  6. 17 21
      src/App/Osu/BanchoNetworking.cpp
  7. 34 0
      src/App/Osu/BanchoProtocol.cpp
  8. 52 0
      src/App/Osu/BanchoProtocol.h
  9. 211 194
      src/App/Osu/Beatmap.cpp
  10. 10 6
      src/App/Osu/Beatmap.h
  11. 8 7
      src/App/Osu/Changelog.cpp
  12. 1 1
      src/App/Osu/Changelog.h
  13. 24 24
      src/App/Osu/Chat.cpp
  14. 1 1
      src/App/Osu/Chat.h
  15. 11 18
      src/App/Osu/Circle.cpp
  16. 16 17
      src/App/Osu/Database.cpp
  17. 1 3
      src/App/Osu/Database.h
  18. 11 22
      src/App/Osu/DatabaseBeatmap.cpp
  19. 2 7
      src/App/Osu/DatabaseBeatmap.h
  20. 1 1
      src/App/Osu/DifficultyCalculator.cpp
  21. 3 15
      src/App/Osu/DifficultyCalculator.h
  22. 22 35
      src/App/Osu/GameRules.h
  23. 222 211
      src/App/Osu/HUD.cpp
  24. 2 14
      src/App/Osu/HUD.h
  25. 10 12
      src/App/Osu/HitObject.cpp
  26. 12 12
      src/App/Osu/Lobby.cpp
  27. 1 1
      src/App/Osu/Lobby.h
  28. 74 73
      src/App/Osu/MainMenu.cpp
  29. 2 16
      src/App/Osu/MainMenu.h
  30. 22 32
      src/App/Osu/ModFPoSu.cpp
  31. 2 17
      src/App/Osu/ModFPoSu.h
  32. 147 160
      src/App/Osu/ModSelector.cpp
  33. 2 14
      src/App/Osu/ModSelector.h
  34. 7 14
      src/App/Osu/NotificationOverlay.cpp
  35. 2 15
      src/App/Osu/NotificationOverlay.h
  36. 113 137
      src/App/Osu/OptionsMenu.cpp
  37. 2 16
      src/App/Osu/OptionsMenu.h
  38. 76 161
      src/App/Osu/Osu.cpp
  39. 43 55
      src/App/Osu/Osu.h
  40. 2 19
      src/App/Osu/OsuScreen.h
  41. 66 52
      src/App/Osu/PauseMenu.cpp
  42. 2 14
      src/App/Osu/PauseMenu.h
  43. 4 4
      src/App/Osu/PromptScreen.cpp
  44. 1 2
      src/App/Osu/PromptScreen.h
  45. 113 114
      src/App/Osu/RankingScreen.cpp
  46. 1 1
      src/App/Osu/RankingScreen.h
  47. 8 8
      src/App/Osu/Replay.cpp
  48. 22 29
      src/App/Osu/RichPresence.cpp
  49. 7 20
      src/App/Osu/RichPresence.h
  50. 110 112
      src/App/Osu/RoomScreen.cpp
  51. 1 1
      src/App/Osu/RoomScreen.h
  52. 8 8
      src/App/Osu/ScoreboardSlot.cpp
  53. 3 3
      src/App/Osu/ScreenBackable.cpp
  54. 2 15
      src/App/Osu/ScreenBackable.h
  55. 26 35
      src/App/Osu/Skin.cpp
  56. 2 16
      src/App/Osu/Skin.h
  57. 1 3
      src/App/Osu/SkinImage.cpp
  58. 39 59
      src/App/Osu/Slider.cpp
  59. 18 18
      src/App/Osu/SliderRenderer.cpp
  60. 13 28
      src/App/Osu/SliderRenderer.h
  61. 12 13
      src/App/Osu/SongBrowser/Button.cpp
  62. 2 4
      src/App/Osu/SongBrowser/Button.h
  63. 8 8
      src/App/Osu/SongBrowser/CollectionButton.cpp
  64. 2 2
      src/App/Osu/SongBrowser/CollectionButton.h
  65. 45 48
      src/App/Osu/SongBrowser/InfoLabel.cpp
  66. 1 3
      src/App/Osu/SongBrowser/InfoLabel.h
  67. 22 24
      src/App/Osu/SongBrowser/ScoreButton.cpp
  68. 2 4
      src/App/Osu/SongBrowser/ScoreButton.h
  69. 165 181
      src/App/Osu/SongBrowser/SongBrowser.cpp
  70. 2 4
      src/App/Osu/SongBrowser/SongBrowser.h
  71. 19 19
      src/App/Osu/SongBrowser/SongButton.cpp
  72. 2 2
      src/App/Osu/SongBrowser/SongButton.h
  73. 10 10
      src/App/Osu/SongBrowser/SongDifficultyButton.cpp
  74. 2 2
      src/App/Osu/SongBrowser/SongDifficultyButton.h
  75. 7 9
      src/App/Osu/SongBrowser/UserButton.cpp
  76. 1 4
      src/App/Osu/SongBrowser/UserButton.h
  77. 13 15
      src/App/Osu/Spinner.cpp
  78. 6 6
      src/App/Osu/TooltipOverlay.cpp
  79. 2 15
      src/App/Osu/TooltipOverlay.h
  80. 3 3
      src/App/Osu/UIAvatar.cpp
  81. 6 14
      src/App/Osu/UIBackButton.cpp
  82. 2 15
      src/App/Osu/UIBackButton.h
  83. 11 22
      src/App/Osu/UIButton.cpp
  84. 2 17
      src/App/Osu/UIButton.h
  85. 4 13
      src/App/Osu/UICheckbox.cpp
  86. 2 16
      src/App/Osu/UICheckbox.h
  87. 21 31
      src/App/Osu/UIContextMenu.cpp
  88. 3 20
      src/App/Osu/UIContextMenu.h
  89. 12 20
      src/App/Osu/UIModSelectorModButton.cpp
  90. 2 16
      src/App/Osu/UIModSelectorModButton.h
  91. 3 11
      src/App/Osu/UIPauseMenuButton.cpp
  92. 2 17
      src/App/Osu/UIPauseMenuButton.h
  93. 2 11
      src/App/Osu/UIRankingScreenInfoLabel.cpp
  94. 2 15
      src/App/Osu/UIRankingScreenInfoLabel.h
  95. 50 61
      src/App/Osu/UIRankingScreenRankingPanel.cpp
  96. 1 4
      src/App/Osu/UIRankingScreenRankingPanel.h
  97. 2 11
      src/App/Osu/UISearchOverlay.cpp
  98. 2 17
      src/App/Osu/UISearchOverlay.h
  99. 3 11
      src/App/Osu/UISlider.cpp
  100. 2 18
      src/App/Osu/UISlider.h

+ 1 - 0
Makefile

@@ -9,6 +9,7 @@ CXXFLAGS = -std=c++17 -fmessage-length=0 -Wno-sign-compare -Wno-unused-local-typ
 CXXFLAGS += `pkgconf --static --cflags $(LIBS)` `curl-config --cflags`
 CXXFLAGS += `pkgconf --static --cflags $(LIBS)` `curl-config --cflags`
 CXXFLAGS += -Isrc/App -Isrc/App/Osu -Isrc/Engine -Isrc/GUI -Isrc/GUI/Windows -Isrc/GUI/Windows/VinylScratcher -Isrc/Engine/Input -Isrc/Engine/Platform -Isrc/Engine/Main -Isrc/Engine/Renderer -Isrc/Util
 CXXFLAGS += -Isrc/App -Isrc/App/Osu -Isrc/Engine -Isrc/GUI -Isrc/GUI/Windows -Isrc/GUI/Windows/VinylScratcher -Isrc/Engine/Input -Isrc/Engine/Platform -Isrc/Engine/Main -Isrc/Engine/Renderer -Isrc/Util
 CXXFLAGS += -Ilibraries/bass/include -Ilibraries/bassasio/include -Ilibraries/bassfx/include -Ilibraries/bassmix/include -Ilibraries/basswasapi/include -Ilibraries/bassloud/include
 CXXFLAGS += -Ilibraries/bass/include -Ilibraries/bassasio/include -Ilibraries/bassfx/include -Ilibraries/bassmix/include -Ilibraries/basswasapi/include -Ilibraries/bassloud/include
+CXXFLAGS += -O2
 CXXFLAGS += -g3 -fsanitize=address
 CXXFLAGS += -g3 -fsanitize=address
 
 
 LDFLAGS = -ldiscord-rpc -lbass -lbassmix -lbass_fx -lbassloud -lpthread -lstdc++
 LDFLAGS = -ldiscord-rpc -lbass -lbassmix -lbass_fx -lbassloud -lpthread -lstdc++

+ 3 - 4
src/App/Osu/BackgroundStarCacheLoader.cpp

@@ -41,10 +41,9 @@ void BackgroundStarCacheLoader::initAsync() {
         const float AR = m_beatmap->getAR();
         const float AR = m_beatmap->getAR();
         const float CS = m_beatmap->getCS();
         const float CS = m_beatmap->getCS();
         const float OD = m_beatmap->getOD();
         const float OD = m_beatmap->getOD();
-        const float speedMultiplier =
-            m_beatmap->getOsu()->getSpeedMultiplier();  // NOTE: not beatmap->getSpeedMultiplier()!
-        const bool relax = m_beatmap->getOsu()->getModRelax();
-        const bool touchDevice = m_beatmap->getOsu()->getModTD();
+        const float speedMultiplier = osu->getSpeedMultiplier();  // NOTE: not beatmap->getSpeedMultiplier()!
+        const bool relax = osu->getModRelax();
+        const bool touchDevice = osu->getModTD();
 
 
         DatabaseBeatmap::LOAD_DIFFOBJ_RESULT diffres =
         DatabaseBeatmap::LOAD_DIFFOBJ_RESULT diffres =
             DatabaseBeatmap::loadDifficultyHitObjects(osuFilePath, AR, CS, speedMultiplier, false, m_bDead);
             DatabaseBeatmap::loadDifficultyHitObjects(osuFilePath, AR, CS, speedMultiplier, false, m_bDead);

+ 75 - 66
src/App/Osu/Bancho.cpp

@@ -59,7 +59,7 @@ void update_channel(UString name, UString topic, i32 nb_members) {
         chat_channels[name_str] = chan;
         chat_channels[name_str] = chan;
 
 
         if(print_new_channels) {
         if(print_new_channels) {
-            bancho.osu->m_chat->addMessage(
+            osu->m_chat->addMessage(
                 "#osu", ChatMessage{
                 "#osu", ChatMessage{
                             .tms = time(NULL),
                             .tms = time(NULL),
                             .author_id = 0,
                             .author_id = 0,
@@ -194,9 +194,9 @@ void handle_packet(Packet *packet) {
         bancho.user_id = read<u32>(packet);
         bancho.user_id = read<u32>(packet);
         if(bancho.user_id > 0) {
         if(bancho.user_id > 0) {
             debugLog("Logged in as user #%d.\n", bancho.user_id);
             debugLog("Logged in as user #%d.\n", bancho.user_id);
-            bancho.osu->m_optionsMenu->logInButton->setText("Disconnect");
-            bancho.osu->m_optionsMenu->logInButton->setColor(0xffff0000);
-            bancho.osu->m_optionsMenu->logInButton->is_loading = false;
+            osu->m_optionsMenu->logInButton->setText("Disconnect");
+            osu->m_optionsMenu->logInButton->setColor(0xffff0000);
+            osu->m_optionsMenu->logInButton->is_loading = false;
             convar->getConVarByName("mp_autologin")->setValue(true);
             convar->getConVarByName("mp_autologin")->setValue(true);
             print_new_channels = true;
             print_new_channels = true;
 
 
@@ -217,17 +217,17 @@ void handle_packet(Packet *packet) {
             }
             }
 
 
             // close your eyes
             // close your eyes
-            SAFE_DELETE(bancho.osu->m_songBrowser2->m_userButton->m_avatar);
-            bancho.osu->m_songBrowser2->m_userButton->m_avatar = new UIAvatar(bancho.user_id, 0.f, 0.f, 0.f, 0.f);
-            bancho.osu->m_songBrowser2->m_userButton->m_avatar->on_screen = true;
+            SAFE_DELETE(osu->m_songBrowser2->m_userButton->m_avatar);
+            osu->m_songBrowser2->m_userButton->m_avatar = new UIAvatar(bancho.user_id, 0.f, 0.f, 0.f, 0.f);
+            osu->m_songBrowser2->m_userButton->m_avatar->on_screen = true;
 
 
             // XXX: We should toggle between "offline" sorting options and "online" ones
             // XXX: We should toggle between "offline" sorting options and "online" ones
             //      Online ones would be "Local scores", "Global", "Country", "Selected mods" etc
             //      Online ones would be "Local scores", "Global", "Country", "Selected mods" etc
             //      While offline ones would be "By score", "By pp", etc
             //      While offline ones would be "By score", "By pp", etc
-            bancho.osu->m_songBrowser2->onSortScoresChange(UString("Online Leaderboard"), 0);
+            osu->m_songBrowser2->onSortScoresChange(UString("Online Leaderboard"), 0);
 
 
             // If server sent a score submission policy, update options menu to hide the checkbox
             // If server sent a score submission policy, update options menu to hide the checkbox
-            bancho.osu->m_optionsMenu->updateLayout();
+            osu->m_optionsMenu->updateLayout();
 
 
             APIRequest request;
             APIRequest request;
             request.type = GET_NEOSU_SETTINGS;
             request.type = GET_NEOSU_SETTINGS;
@@ -237,9 +237,9 @@ void handle_packet(Packet *packet) {
             send_api_request(request);
             send_api_request(request);
         } else {
         } else {
             convar->getConVarByName("mp_autologin")->setValue(false);
             convar->getConVarByName("mp_autologin")->setValue(false);
-            bancho.osu->m_optionsMenu->logInButton->setText("Log in");
-            bancho.osu->m_optionsMenu->logInButton->setColor(0xff00ff00);
-            bancho.osu->m_optionsMenu->logInButton->is_loading = false;
+            osu->m_optionsMenu->logInButton->setText("Log in");
+            osu->m_optionsMenu->logInButton->setColor(0xff00ff00);
+            osu->m_optionsMenu->logInButton->is_loading = false;
 
 
             debugLog("Failed to log in, server returned code %d.\n", bancho.user_id);
             debugLog("Failed to log in, server returned code %d.\n", bancho.user_id);
             UString errmsg = UString::format("Failed to log in: %s (code %d)\n", cho_token.toUtf8(), bancho.user_id);
             UString errmsg = UString::format("Failed to log in: %s (code %d)\n", cho_token.toUtf8(), bancho.user_id);
@@ -266,7 +266,7 @@ void handle_packet(Packet *packet) {
                     errmsg = "Please contact an administrator of the server.";
                     errmsg = "Please contact an administrator of the server.";
                 }
                 }
             }
             }
-            bancho.osu->getNotificationOverlay()->addNotification(errmsg);
+            osu->getNotificationOverlay()->addNotification(errmsg);
         }
         }
     } else if(packet->id == RECV_MESSAGE) {
     } else if(packet->id == RECV_MESSAGE) {
         UString sender = read_string(packet);
         UString sender = read_string(packet);
@@ -274,12 +274,12 @@ void handle_packet(Packet *packet) {
         UString recipient = read_string(packet);
         UString recipient = read_string(packet);
         i32 sender_id = read<u32>(packet);
         i32 sender_id = read<u32>(packet);
 
 
-        bancho.osu->m_chat->addMessage(recipient, ChatMessage{
-                                                      .tms = time(NULL),
-                                                      .author_id = sender_id,
-                                                      .author_name = sender,
-                                                      .text = text,
-                                                  });
+        osu->m_chat->addMessage(recipient, ChatMessage{
+                                               .tms = time(NULL),
+                                               .author_id = sender_id,
+                                               .author_name = sender,
+                                               .text = text,
+                                           });
     } else if(packet->id == PONG) {
     } else if(packet->id == PONG) {
         // (nothing to do)
         // (nothing to do)
     } else if(packet->id == USER_STATS) {
     } else if(packet->id == USER_STATS) {
@@ -301,7 +301,7 @@ void handle_packet(Packet *packet) {
         user->pp = read<u16>(packet);
         user->pp = read<u16>(packet);
 
 
         if(stats_user_id == bancho.user_id) {
         if(stats_user_id == bancho.user_id) {
-            bancho.osu->m_songBrowser2->m_userButton->updateUserStats();
+            osu->m_songBrowser2->m_userButton->updateUserStats();
         }
         }
     } else if(packet->id == USER_LOGOUT) {
     } else if(packet->id == USER_LOGOUT) {
         i32 logged_out_id = read<u32>(packet);
         i32 logged_out_id = read<u32>(packet);
@@ -312,74 +312,82 @@ void handle_packet(Packet *packet) {
         }
         }
     } else if(packet->id == SPECTATOR_JOINED) {
     } else if(packet->id == SPECTATOR_JOINED) {
         i32 spectator_id = read<u32>(packet);
         i32 spectator_id = read<u32>(packet);
+        bancho.spectators.push_back(spectator_id);
         debugLog("Spectator joined: user id %d\n", spectator_id);
         debugLog("Spectator joined: user id %d\n", spectator_id);
     } else if(packet->id == SPECTATOR_LEFT) {
     } else if(packet->id == SPECTATOR_LEFT) {
         i32 spectator_id = read<u32>(packet);
         i32 spectator_id = read<u32>(packet);
+        auto it = std::find(bancho.spectators.begin(), bancho.spectators.end(), spectator_id);
+        if(it != bancho.spectators.end()) {
+            bancho.spectators.erase(it);
+        }
         debugLog("Spectator left: user id %d\n", spectator_id);
         debugLog("Spectator left: user id %d\n", spectator_id);
-    } else if(packet->id == VERSION_UPDATE) {
-        // (nothing to do)
     } else if(packet->id == SPECTATOR_CANT_SPECTATE) {
     } else if(packet->id == SPECTATOR_CANT_SPECTATE) {
         i32 spectator_id = read<u32>(packet);
         i32 spectator_id = read<u32>(packet);
         debugLog("Spectator can't spectate: user id %d\n", spectator_id);
         debugLog("Spectator can't spectate: user id %d\n", spectator_id);
+    } else if(packet->id == FELLOW_SPECTATOR_JOINED) {
+        i32 spectator_id = read<u32>(packet);
+        bancho.fellow_spectators.push_back(spectator_id);
+        debugLog("Fellow spectator joined: user id %d\n", spectator_id);
+    } else if(packet->id == FELLOW_SPECTATOR_LEFT) {
+        i32 spectator_id = read<u32>(packet);
+        auto it = std::find(bancho.fellow_spectators.begin(), bancho.fellow_spectators.end(), spectator_id);
+        if(it != bancho.fellow_spectators.end()) {
+            bancho.fellow_spectators.erase(it);
+        }
+        debugLog("Fellow spectator left: user id %d\n", spectator_id);
     } else if(packet->id == GET_ATTENTION) {
     } else if(packet->id == GET_ATTENTION) {
         // (nothing to do)
         // (nothing to do)
     } else if(packet->id == NOTIFICATION) {
     } else if(packet->id == NOTIFICATION) {
         UString notification = read_string(packet);
         UString notification = read_string(packet);
-        bancho.osu->getNotificationOverlay()->addNotification(notification);
+        osu->getNotificationOverlay()->addNotification(notification);
         // XXX: don't do McOsu style notifications, since:
         // XXX: don't do McOsu style notifications, since:
         // 1) they can't do multiline text
         // 1) they can't do multiline text
         // 2) they don't stack, if the server sends >1 you only see the latest
         // 2) they don't stack, if the server sends >1 you only see the latest
         // Maybe log them in the chat + display in bottom right like ppy client?
         // Maybe log them in the chat + display in bottom right like ppy client?
     } else if(packet->id == ROOM_UPDATED) {
     } else if(packet->id == ROOM_UPDATED) {
         auto room = Room(packet);
         auto room = Room(packet);
-        if(bancho.osu->m_lobby->isVisible()) {
-            bancho.osu->m_lobby->updateRoom(room);
+        if(osu->m_lobby->isVisible()) {
+            osu->m_lobby->updateRoom(room);
         } else if(room.id == bancho.room.id) {
         } else if(room.id == bancho.room.id) {
-            bancho.osu->m_room->on_room_updated(room);
+            osu->m_room->on_room_updated(room);
         }
         }
     } else if(packet->id == ROOM_CREATED) {
     } else if(packet->id == ROOM_CREATED) {
         auto room = new Room(packet);
         auto room = new Room(packet);
-        bancho.osu->m_lobby->addRoom(room);
+        osu->m_lobby->addRoom(room);
     } else if(packet->id == ROOM_CLOSED) {
     } else if(packet->id == ROOM_CLOSED) {
         i32 room_id = read<u32>(packet);
         i32 room_id = read<u32>(packet);
-        bancho.osu->m_lobby->removeRoom(room_id);
+        osu->m_lobby->removeRoom(room_id);
     } else if(packet->id == ROOM_JOIN_SUCCESS) {
     } else if(packet->id == ROOM_JOIN_SUCCESS) {
         auto room = Room(packet);
         auto room = Room(packet);
-        bancho.osu->m_room->on_room_joined(room);
+        osu->m_room->on_room_joined(room);
     } else if(packet->id == ROOM_JOIN_FAIL) {
     } else if(packet->id == ROOM_JOIN_FAIL) {
-        bancho.osu->getNotificationOverlay()->addNotification("Failed to join room.");
-        bancho.osu->m_lobby->on_room_join_failed();
-    } else if(packet->id == FELLOW_SPECTATOR_JOINED) {
-        u32 spectator_id = read<u32>(packet);
-        (void)spectator_id;  // (spectating not implemented; nothing to do)
-    } else if(packet->id == FELLOW_SPECTATOR_LEFT) {
-        u32 spectator_id = read<u32>(packet);
-        (void)spectator_id;  // (spectating not implemented; nothing to do)
+        osu->getNotificationOverlay()->addNotification("Failed to join room.");
+        osu->m_lobby->on_room_join_failed();
     } else if(packet->id == MATCH_STARTED) {
     } else if(packet->id == MATCH_STARTED) {
         auto room = Room(packet);
         auto room = Room(packet);
-        bancho.osu->m_room->on_match_started(room);
+        osu->m_room->on_match_started(room);
     } else if(packet->id == UPDATE_MATCH_SCORE || packet->id == MATCH_SCORE_UPDATED) {
     } else if(packet->id == UPDATE_MATCH_SCORE || packet->id == MATCH_SCORE_UPDATED) {
-        bancho.osu->m_room->on_match_score_updated(packet);
+        osu->m_room->on_match_score_updated(packet);
     } else if(packet->id == HOST_CHANGED) {
     } else if(packet->id == HOST_CHANGED) {
         // (nothing to do)
         // (nothing to do)
     } else if(packet->id == MATCH_ALL_PLAYERS_LOADED) {
     } else if(packet->id == MATCH_ALL_PLAYERS_LOADED) {
-        bancho.osu->m_room->on_all_players_loaded();
+        osu->m_room->on_all_players_loaded();
     } else if(packet->id == MATCH_PLAYER_FAILED) {
     } else if(packet->id == MATCH_PLAYER_FAILED) {
         i32 slot_id = read<u32>(packet);
         i32 slot_id = read<u32>(packet);
-        bancho.osu->m_room->on_player_failed(slot_id);
+        osu->m_room->on_player_failed(slot_id);
     } else if(packet->id == MATCH_FINISHED) {
     } else if(packet->id == MATCH_FINISHED) {
-        bancho.osu->m_room->on_match_finished();
+        osu->m_room->on_match_finished();
     } else if(packet->id == MATCH_SKIP) {
     } else if(packet->id == MATCH_SKIP) {
-        bancho.osu->m_room->on_all_players_skipped();
+        osu->m_room->on_all_players_skipped();
     } else if(packet->id == CHANNEL_JOIN_SUCCESS) {
     } else if(packet->id == CHANNEL_JOIN_SUCCESS) {
         UString name = read_string(packet);
         UString name = read_string(packet);
-        bancho.osu->m_chat->addChannel(name);
-        bancho.osu->m_chat->addMessage(name, ChatMessage{
-                                                 .tms = time(NULL),
-                                                 .author_id = 0,
-                                                 .author_name = UString(""),
-                                                 .text = UString("Joined channel."),
-                                             });
+        osu->m_chat->addChannel(name);
+        osu->m_chat->addMessage(name, ChatMessage{
+                                          .tms = time(NULL),
+                                          .author_id = 0,
+                                          .author_name = UString(""),
+                                          .text = UString("Joined channel."),
+                                      });
     } else if(packet->id == CHANNEL_INFO) {
     } else if(packet->id == CHANNEL_INFO) {
         UString channel_name = read_string(packet);
         UString channel_name = read_string(packet);
         UString channel_topic = read_string(packet);
         UString channel_topic = read_string(packet);
@@ -387,7 +395,7 @@ void handle_packet(Packet *packet) {
         update_channel(channel_name, channel_topic, nb_members);
         update_channel(channel_name, channel_topic, nb_members);
     } else if(packet->id == LEFT_CHANNEL) {
     } else if(packet->id == LEFT_CHANNEL) {
         UString name = read_string(packet);
         UString name = read_string(packet);
-        bancho.osu->m_chat->removeChannel(name);
+        osu->m_chat->removeChannel(name);
     } else if(packet->id == CHANNEL_AUTO_JOIN) {
     } else if(packet->id == CHANNEL_AUTO_JOIN) {
         UString channel_name = read_string(packet);
         UString channel_name = read_string(packet);
         UString channel_topic = read_string(packet);
         UString channel_topic = read_string(packet);
@@ -407,8 +415,7 @@ void handle_packet(Packet *packet) {
     } else if(packet->id == PROTOCOL_VERSION) {
     } else if(packet->id == PROTOCOL_VERSION) {
         int protocol_version = read<u32>(packet);
         int protocol_version = read<u32>(packet);
         if(protocol_version != 19) {
         if(protocol_version != 19) {
-            bancho.osu->getNotificationOverlay()->addNotification(
-                "This server may use an unsupported protocol version.");
+            osu->getNotificationOverlay()->addNotification("This server may use an unsupported protocol version.");
         }
         }
     } else if(packet->id == MAIN_MENU_ICON) {
     } else if(packet->id == MAIN_MENU_ICON) {
         UString icon = read_string(packet);
         UString icon = read_string(packet);
@@ -418,7 +425,7 @@ void handle_packet(Packet *packet) {
         }
         }
     } else if(packet->id == MATCH_PLAYER_SKIPPED) {
     } else if(packet->id == MATCH_PLAYER_SKIPPED) {
         i32 user_id = read<u32>(packet);
         i32 user_id = read<u32>(packet);
-        bancho.osu->m_room->on_player_skip(user_id);
+        osu->m_room->on_player_skip(user_id);
 
 
         // I'm not sure the server ever sends MATCH_SKIP... So, double-checking here.
         // I'm not sure the server ever sends MATCH_SKIP... So, double-checking here.
         bool all_players_skipped = true;
         bool all_players_skipped = true;
@@ -430,7 +437,7 @@ void handle_packet(Packet *packet) {
             }
             }
         }
         }
         if(all_players_skipped) {
         if(all_players_skipped) {
-            bancho.osu->m_room->on_all_players_skipped();
+            osu->m_room->on_all_players_skipped();
         }
         }
     } else if(packet->id == USER_PRESENCE) {
     } else if(packet->id == USER_PRESENCE) {
         i32 presence_user_id = read<u32>(packet);
         i32 presence_user_id = read<u32>(packet);
@@ -460,16 +467,16 @@ void handle_packet(Packet *packet) {
         UString recipient = read_string(packet);
         UString recipient = read_string(packet);
         (void)recipient;
         (void)recipient;
         i32 sender_id = read<u32>(packet);
         i32 sender_id = read<u32>(packet);
-        bancho.osu->m_chat->addMessage(recipient, ChatMessage{
-                                                      .tms = time(NULL),
-                                                      .author_id = sender_id,
-                                                      .author_name = sender,
-                                                      .text = text,
-                                                  });
+        osu->m_chat->addMessage(recipient, ChatMessage{
+                                               .tms = time(NULL),
+                                               .author_id = sender_id,
+                                               .author_name = sender,
+                                               .text = text,
+                                           });
     } else if(packet->id == CHANNEL_INFO_END) {
     } else if(packet->id == CHANNEL_INFO_END) {
         print_new_channels = false;
         print_new_channels = false;
-        bancho.osu->m_chat->join("#announce");
-        bancho.osu->m_chat->join("#osu");
+        osu->m_chat->join("#announce");
+        osu->m_chat->join("#osu");
     } else if(packet->id == ROOM_PASSWORD_CHANGED) {
     } else if(packet->id == ROOM_PASSWORD_CHANGED) {
         UString new_password = read_string(packet);
         UString new_password = read_string(packet);
         debugLog("Room changed password to %s\n", new_password.toUtf8());
         debugLog("Room changed password to %s\n", new_password.toUtf8());
@@ -493,14 +500,16 @@ void handle_packet(Packet *packet) {
         UString blocked = read_string(packet);
         UString blocked = read_string(packet);
         read<u32>(packet);
         read<u32>(packet);
         debugLog("Silenced %s.\n", blocked.toUtf8());
         debugLog("Silenced %s.\n", blocked.toUtf8());
+    } else if(packet->id == VERSION_UPDATE) {
+        // (nothing to do)
     } else if(packet->id == VERSION_UPDATE_FORCED) {
     } else if(packet->id == VERSION_UPDATE_FORCED) {
         disconnect();
         disconnect();
-        bancho.osu->getNotificationOverlay()->addNotification("This server requires a newer client version.");
+        osu->getNotificationOverlay()->addNotification("This server requires a newer client version.");
     } else if(packet->id == ACCOUNT_RESTRICTED) {
     } else if(packet->id == ACCOUNT_RESTRICTED) {
-        bancho.osu->getNotificationOverlay()->addNotification("Account restricted.");
+        osu->getNotificationOverlay()->addNotification("Account restricted.");
         disconnect();
         disconnect();
     } else if(packet->id == MATCH_ABORT) {
     } else if(packet->id == MATCH_ABORT) {
-        bancho.osu->m_room->on_match_aborted();
+        osu->m_room->on_match_aborted();
     } else if(packet->id == OVERRIDE_NEOSU_CONVARS) {
     } else if(packet->id == OVERRIDE_NEOSU_CONVARS) {
         process_neosu_settings(*packet);
         process_neosu_settings(*packet);
     } else {
     } else {

+ 2 - 2
src/App/Osu/Bancho.h

@@ -4,7 +4,6 @@
 #include "BanchoProtocol.h"
 #include "BanchoProtocol.h"
 #include "UString.h"
 #include "UString.h"
 
 
-class Osu;
 class Image;
 class Image;
 
 
 enum class ServerPolicy {
 enum class ServerPolicy {
@@ -16,12 +15,13 @@ enum class ServerPolicy {
 struct Bancho {
 struct Bancho {
     UString neosu_version;
     UString neosu_version;
 
 
-    Osu *osu = nullptr;
     UString endpoint;
     UString endpoint;
     i32 user_id = 0;
     i32 user_id = 0;
     UString username;
     UString username;
     MD5Hash pw_md5;
     MD5Hash pw_md5;
     Room room;
     Room room;
+    std::vector<u32> spectators;
+    std::vector<u32> fellow_spectators;
 
 
     UString server_icon_url;
     UString server_icon_url;
     Image *server_icon = nullptr;
     Image *server_icon = nullptr;

+ 4 - 5
src/App/Osu/BanchoLeaderboard.cpp

@@ -119,8 +119,7 @@ void fetch_online_scores(DatabaseBeatmap *beatmap) {
     curl_free(encoded_filename);
     curl_free(encoded_filename);
     curl_easy_cleanup(curl);
     curl_easy_cleanup(curl);
     path.append(UString::format("&m=0&i=%d&mods=%d&h=&a=0&us=%s&ha=%s", beatmap->getSetID(),
     path.append(UString::format("&m=0&i=%d&mods=%d&h=&a=0&us=%s&ha=%s", beatmap->getSetID(),
-                                bancho.osu->m_modSelector->getModFlags(), bancho.username.toUtf8(),
-                                bancho.pw_md5.toUtf8())
+                                osu->m_modSelector->getModFlags(), bancho.username.toUtf8(), bancho.pw_md5.toUtf8())
                     .toUtf8());
                     .toUtf8());
 
 
     APIRequest request;
     APIRequest request;
@@ -148,7 +147,7 @@ char *strtok_x(char d, char **str) {
 
 
 void process_leaderboard_response(Packet response) {
 void process_leaderboard_response(Packet response) {
     // Don't update the leaderboard while playing, that's weird
     // Don't update the leaderboard while playing, that's weird
-    if(bancho.osu->isInPlayMode()) return;
+    if(osu->isInPlayMode()) return;
 
 
     // NOTE: We're not doing anything with the "info" struct.
     // NOTE: We're not doing anything with the "info" struct.
     //       Server can return partial responses in some cases, so make sure
     //       Server can return partial responses in some cases, so make sure
@@ -202,6 +201,6 @@ void process_leaderboard_response(Packet response) {
     // XXX: We should also separately display either the "personal best" the server sent us,
     // XXX: We should also separately display either the "personal best" the server sent us,
     //      or the local best, depending on which score is better.
     //      or the local best, depending on which score is better.
     debugLog("Received online leaderbord for Beatmap ID %d\n", info.beatmap_id);
     debugLog("Received online leaderbord for Beatmap ID %d\n", info.beatmap_id);
-    bancho.osu->getSongBrowser()->getDatabase()->m_online_scores[beatmap_hash] = std::move(scores);
-    bancho.osu->getSongBrowser()->rebuildScoreButtons();
+    osu->getSongBrowser()->getDatabase()->m_online_scores[beatmap_hash] = std::move(scores);
+    osu->getSongBrowser()->rebuildScoreButtons();
 }
 }

+ 17 - 21
src/App/Osu/BanchoNetworking.cpp

@@ -90,7 +90,10 @@ void disconnect() {
     auth_header = "";
     auth_header = "";
     free(outgoing.memory);
     free(outgoing.memory);
     outgoing = Packet();
     outgoing = Packet();
+
     bancho.user_id = 0;
     bancho.user_id = 0;
+    bancho.spectators.clear();
+    bancho.fellow_spectators.clear();
     bancho.server_icon_url = "";
     bancho.server_icon_url = "";
     if(bancho.server_icon != nullptr) {
     if(bancho.server_icon != nullptr) {
         engine->getResourceManager()->destroyResource(bancho.server_icon);
         engine->getResourceManager()->destroyResource(bancho.server_icon);
@@ -105,11 +108,11 @@ void disconnect() {
     bancho.score_submission_policy = ServerPolicy::NO_PREFERENCE;
     bancho.score_submission_policy = ServerPolicy::NO_PREFERENCE;
     bancho.set_fposu_flag = false;
     bancho.set_fposu_flag = false;
     bancho.set_mirror_flag = false;
     bancho.set_mirror_flag = false;
-    bancho.osu->m_optionsMenu->updateLayout();
+    osu->m_optionsMenu->updateLayout();
 
 
-    bancho.osu->m_optionsMenu->logInButton->setText("Log in");
-    bancho.osu->m_optionsMenu->logInButton->setColor(0xff00ff00);
-    bancho.osu->m_optionsMenu->logInButton->is_loading = false;
+    osu->m_optionsMenu->logInButton->setText("Log in");
+    osu->m_optionsMenu->logInButton->setColor(0xff00ff00);
+    osu->m_optionsMenu->logInButton->is_loading = false;
 
 
     for(auto pair : online_users) {
     for(auto pair : online_users) {
         delete pair.second;
         delete pair.second;
@@ -117,12 +120,12 @@ void disconnect() {
     online_users.clear();
     online_users.clear();
     friends.clear();
     friends.clear();
 
 
-    bancho.osu->m_chat->onDisconnect();
+    osu->m_chat->onDisconnect();
 
 
     // XXX: We should toggle between "offline" sorting options and "online" ones
     // XXX: We should toggle between "offline" sorting options and "online" ones
     //      Online ones would be "Local scores", "Global", "Country", "Selected mods" etc
     //      Online ones would be "Local scores", "Global", "Country", "Selected mods" etc
     //      While offline ones would be "By score", "By pp", etc
     //      While offline ones would be "By score", "By pp", etc
-    bancho.osu->m_songBrowser2->onSortScoresChange(UString("Sort By Score"), 0);
+    osu->m_songBrowser2->onSortScoresChange(UString("Sort By Score"), 0);
 
 
     abort_downloads();
     abort_downloads();
 
 
@@ -130,13 +133,6 @@ void disconnect() {
 }
 }
 
 
 void reconnect() {
 void reconnect() {
-    if(bancho.osu->m_iInstanceID > 0) {
-        // XXX: To handle multiple instances you would have to do some complex IPC
-        //      Would be great to be able to use neosu as tournament spectator client...
-        //      But that's not in scope right now.
-        return;
-    }
-
     disconnect();
     disconnect();
 
 
     // Disable autologin, in case there's an error while logging in
     // Disable autologin, in case there's an error while logging in
@@ -155,7 +151,7 @@ void reconnect() {
     bancho.username = convar->getConVarByName("name")->getString();
     bancho.username = convar->getConVarByName("name")->getString();
     bancho.endpoint = convar->getConVarByName("mp_server")->getString();
     bancho.endpoint = convar->getConVarByName("mp_server")->getString();
 
 
-    bancho.osu->m_optionsMenu->logInButton->is_loading = true;
+    osu->m_optionsMenu->logInButton->is_loading = true;
     Packet new_login_packet = build_login_packet();
     Packet new_login_packet = build_login_packet();
 
 
     pthread_mutex_lock(&outgoing_mutex);
     pthread_mutex_lock(&outgoing_mutex);
@@ -258,7 +254,7 @@ static void send_bancho_packet(CURL *curl, Packet outgoing) {
         if(auth_header.empty()) {
         if(auth_header.empty()) {
             // XXX: Not thread safe, playing with fire here
             // XXX: Not thread safe, playing with fire here
             auto errmsg = UString::format("Failed to log in: %s", curl_easy_strerror(res));
             auto errmsg = UString::format("Failed to log in: %s", curl_easy_strerror(res));
-            bancho.osu->getNotificationOverlay()->addNotification(errmsg);
+            osu->getNotificationOverlay()->addNotification(errmsg);
         }
         }
         goto end;
         goto end;
     }
     }
@@ -331,7 +327,7 @@ static void *do_networking(void *data) {
         return NULL;
         return NULL;
     }
     }
 
 
-    while(bancho.osu != nullptr) {
+    while(osu != nullptr) {
         pthread_mutex_lock(&api_requests_mutex);
         pthread_mutex_lock(&api_requests_mutex);
         if(api_request_queue.empty()) {
         if(api_request_queue.empty()) {
             pthread_mutex_unlock(&api_requests_mutex);
             pthread_mutex_unlock(&api_requests_mutex);
@@ -343,7 +339,7 @@ static void *do_networking(void *data) {
             send_api_request(curl, api_out);
             send_api_request(curl, api_out);
         }
         }
 
 
-        if(bancho.osu && bancho.osu->m_lobby->isVisible()) seconds_between_pings = 1;
+        if(osu && osu->m_lobby->isVisible()) seconds_between_pings = 1;
         if(bancho.is_in_a_multi_room() && seconds_between_pings > 3) seconds_between_pings = 3;
         if(bancho.is_in_a_multi_room() && seconds_between_pings > 3) seconds_between_pings = 3;
         bool should_ping = difftime(time(NULL), last_packet_tms) > seconds_between_pings;
         bool should_ping = difftime(time(NULL), last_packet_tms) > seconds_between_pings;
         if(bancho.user_id <= 0) should_ping = false;
         if(bancho.user_id <= 0) should_ping = false;
@@ -413,7 +409,7 @@ static void handle_api_response(Packet packet) {
         case GET_REPLAY: {
         case GET_REPLAY: {
             if(packet.size == 0) {
             if(packet.size == 0) {
                 // Most likely, 404
                 // Most likely, 404
-                bancho.osu->m_notificationOverlay->addNotification("Failed to download replay");
+                osu->m_notificationOverlay->addNotification("Failed to download replay");
                 break;
                 break;
             }
             }
 
 
@@ -426,7 +422,7 @@ static void handle_api_response(Packet packet) {
             auto replay_path_str = replay_path.str();
             auto replay_path_str = replay_path.str();
             FILE *replay_file = fopen(replay_path_str.c_str(), "wb");
             FILE *replay_file = fopen(replay_path_str.c_str(), "wb");
             if(replay_file == NULL) {
             if(replay_file == NULL) {
-                bancho.osu->m_notificationOverlay->addNotification("Failed to save replay");
+                osu->m_notificationOverlay->addNotification("Failed to save replay");
                 break;
                 break;
             }
             }
 
 
@@ -446,8 +442,8 @@ static void handle_api_response(Packet packet) {
             debugLog("Score submit result: %s\n", packet.memory);
             debugLog("Score submit result: %s\n", packet.memory);
 
 
             // Reset leaderboards so new score will appear
             // Reset leaderboards so new score will appear
-            bancho.osu->getSongBrowser()->m_db->m_online_scores.clear();
-            bancho.osu->getSongBrowser()->rebuildScoreButtons();
+            osu->getSongBrowser()->m_db->m_online_scores.clear();
+            osu->getSongBrowser()->rebuildScoreButtons();
             break;
             break;
         }
         }
 
 

+ 34 - 0
src/App/Osu/BanchoProtocol.cpp

@@ -4,6 +4,8 @@
 #include <string.h>
 #include <string.h>
 
 
 #include "Bancho.h"
 #include "Bancho.h"
+#include "Beatmap.h"
+#include "Osu.h"
 
 
 // Null array for returning empty structures when trying to read more data out of a Packet than expected.
 // Null array for returning empty structures when trying to read more data out of a Packet than expected.
 u8 NULL_ARRAY[NULL_ARRAY_SIZE] = {0};
 u8 NULL_ARRAY[NULL_ARRAY_SIZE] = {0};
@@ -231,3 +233,35 @@ void write_hash(Packet *packet, MD5Hash hash) {
     write<u8>(packet, 0x20);
     write<u8>(packet, 0x20);
     write_bytes(packet, (u8 *)hash.hash, 32);
     write_bytes(packet, (u8 *)hash.hash, 32);
 }
 }
+
+ScoreFrame ScoreFrame::get() {
+    u8 slot_id = 0;
+    for(u8 i = 0; i < 16; i++) {
+        if(bancho.room.slots[i].player_id == bancho.user_id) {
+            slot_id = i;
+            break;
+        }
+    }
+
+    auto score = osu->getScore();
+    auto perfect = (score->getNumSliderBreaks() == 0 && score->getNumMisses() == 0 && score->getNum50s() == 0 &&
+                    score->getNum100s() == 0);
+
+    return ScoreFrame{
+        .time = (i32)osu->getSelectedBeatmap()->getCurMusicPos(),  // NOTE: might be incorrect
+        .slot_id = slot_id,
+        .num300 = (u16)score->getNum300s(),
+        .num100 = (u16)score->getNum100s(),
+        .num50 = (u16)score->getNum50s(),
+        .num_geki = (u16)score->getNum300gs(),
+        .num_katu = (u16)score->getNum100ks(),
+        .num_miss = (u16)score->getNumMisses(),
+        .total_score = (i32)score->getScore(),
+        .max_combo = (u16)score->getComboMax(),
+        .current_combo = (u16)score->getCombo(),
+        .is_perfect = perfect,
+        .current_hp = (u8)(osu->getSelectedBeatmap()->getHealth() * 200.0),
+        .tag = 0,         // tag gamemode currently not supported
+        .is_scorev2 = 0,  // scorev2 currently not supported
+    };
+}

+ 52 - 0
src/App/Osu/BanchoProtocol.h

@@ -248,6 +248,58 @@ class Room {
     void pack(Packet *packet);
     void pack(Packet *packet);
 };
 };
 
 
+#pragma pack(push, 1)
+struct ScoreFrame {
+    i32 time;
+    u8 slot_id;
+    u16 num300;
+    u16 num100;
+    u16 num50;
+    u16 num_geki;
+    u16 num_katu;
+    u16 num_miss;
+    i32 total_score;
+    u16 max_combo;
+    u16 current_combo;
+    u8 is_perfect;
+    u8 current_hp;
+    u8 tag;
+    u8 is_scorev2;
+
+    static ScoreFrame get();
+};
+#pragma pack(pop)
+
+#pragma pack(push, 1)
+struct LiveReplayFrame {
+    u8 key_flags;
+    u8 padding;  // was used in very old versions of the game
+    f32 mouse_x;
+    f32 mouse_y;
+    i32 time;
+};
+#pragma pack(pop)
+
+struct LiveReplayBundle {
+    enum Action {
+        NONE = 0,
+        NEW_SONG = 1,
+        SKIP = 2,
+        COMPLETION = 3,
+        FAIL = 4,
+        PAUSE = 5,
+        UNPAUSE = 6,
+        SONG_SELECT = 7,
+        WATCHING_OTHER = 8,
+    };
+
+    Action action;
+    u16 nb_frames;
+    LiveReplayFrame *frames;
+    ScoreFrame score;
+    u16 sequence;
+};
+
 void read_bytes(Packet *packet, u8 *bytes, size_t n);
 void read_bytes(Packet *packet, u8 *bytes, size_t n);
 u32 read_uleb128(Packet *packet);
 u32 read_uleb128(Packet *packet);
 UString read_string(Packet *packet);
 UString read_string(Packet *packet);

File diff suppressed because it is too large
+ 211 - 194
src/App/Osu/Beatmap.cpp


+ 10 - 6
src/App/Osu/Beatmap.h

@@ -9,7 +9,6 @@
 class Sound;
 class Sound;
 class ConVar;
 class ConVar;
 
 
-class Osu;
 class Skin;
 class Skin;
 class HitObject;
 class HitObject;
 
 
@@ -28,7 +27,7 @@ class Beatmap {
     friend class BackgroundStarCacheLoader;
     friend class BackgroundStarCacheLoader;
     friend class BackgroundStarCalcHandler;
     friend class BackgroundStarCalcHandler;
 
 
-    Beatmap(Osu *osu);
+    Beatmap();
     ~Beatmap();
     ~Beatmap();
 
 
     void draw(Graphics *g);
     void draw(Graphics *g);
@@ -109,8 +108,9 @@ class Beatmap {
                     // clicking on a beatmap)
                     // clicking on a beatmap)
     void selectDifficulty2(DatabaseBeatmap *difficulty2);
     void selectDifficulty2(DatabaseBeatmap *difficulty2);
     void deselect();  // stops + unloads the currently loaded music and deletes all hitobjects
     void deselect();  // stops + unloads the currently loaded music and deletes all hitobjects
-    bool watch(FinishedScore score, double start_percent);
     bool play();
     bool play();
+    bool watch(FinishedScore score, double start_percent);
+    bool start();
     void restart(bool quick = false);
     void restart(bool quick = false);
     void pause(bool quitIfWaiting = true);
     void pause(bool quitIfWaiting = true);
     void pausePreviewMusic(bool toggle = true);
     void pausePreviewMusic(bool toggle = true);
@@ -198,8 +198,14 @@ class Beatmap {
     bool m_bIsWatchingReplay = false;
     bool m_bIsWatchingReplay = false;
     long current_frame_idx = 0;
     long current_frame_idx = 0;
 
 
+    // spectating
+    void broadcast_spectator_frames();
+    std::vector<LiveReplayFrame> frame_batch;
+    double last_spectator_broadcast = 0;
+    u16 spectator_sequence = 0;
+    bool is_spectating = false;
+
     // used by HitObject children and ModSelector
     // used by HitObject children and ModSelector
-    inline Osu *getOsu() const { return m_osu; }
     Skin *getSkin() const;  // maybe use this for beatmap skins, maybe
     Skin *getSkin() const;  // maybe use this for beatmap skins, maybe
     inline int getRandomSeed() const { return m_iRandomSeed; }
     inline int getRandomSeed() const { return m_iRandomSeed; }
 
 
@@ -276,8 +282,6 @@ class Beatmap {
 
 
     unsigned long getMusicPositionMSInterpolated();
     unsigned long getMusicPositionMSInterpolated();
 
 
-    Osu *m_osu;
-
     // beatmap state
     // beatmap state
     bool m_bIsPlaying;
     bool m_bIsPlaying;
     bool m_bIsPaused;
     bool m_bIsPaused;

+ 8 - 7
src/App/Osu/Changelog.cpp

@@ -14,7 +14,7 @@
 #include "Skin.h"
 #include "Skin.h"
 #include "SoundEngine.h"
 #include "SoundEngine.h"
 
 
-Changelog::Changelog(Osu *osu) : ScreenBackable(osu) {
+Changelog::Changelog() : ScreenBackable() {
     setPos(-1, -1);
     setPos(-1, -1);
     m_scrollView = new CBaseUIScrollView(-1, -1, 0, 0, "");
     m_scrollView = new CBaseUIScrollView(-1, -1, 0, 0, "");
     m_scrollView->setVerticalScrolling(true);
     m_scrollView->setVerticalScrolling(true);
@@ -29,6 +29,7 @@ Changelog::Changelog(Osu *osu) : ScreenBackable(osu) {
     CHANGELOG latest;
     CHANGELOG latest;
     latest.title =
     latest.title =
         UString::format("%.2f (%s, %s)", convar->getConVarByName("osu_version")->getFloat(), __DATE__, __TIME__);
         UString::format("%.2f (%s, %s)", convar->getConVarByName("osu_version")->getFloat(), __DATE__, __TIME__);
+    latest.changes.push_back("- Added ability to get spectated");
     latest.changes.push_back("- Added option for servers to override convars using neosu.json");
     latest.changes.push_back("- Added option for servers to override convars using neosu.json");
     latest.changes.push_back("- Added option for servers to override convars using a custom bancho packet");
     latest.changes.push_back("- Added option for servers to override convars using a custom bancho packet");
     latest.changes.push_back("- Hid password cvar from console command list");
     latest.changes.push_back("- Hid password cvar from console command list");
@@ -257,10 +258,10 @@ CBaseUIContainer *Changelog::setVisible(bool visible) {
 void Changelog::updateLayout() {
 void Changelog::updateLayout() {
     ScreenBackable::updateLayout();
     ScreenBackable::updateLayout();
 
 
-    const float dpiScale = Osu::getUIScale(m_osu);
+    const float dpiScale = Osu::getUIScale();
 
 
-    setSize(m_osu->getScreenSize() + Vector2(2, 2));
-    m_scrollView->setSize(m_osu->getScreenSize() + Vector2(2, 2));
+    setSize(osu->getScreenSize() + Vector2(2, 2));
+    m_scrollView->setSize(osu->getScreenSize() + Vector2(2, 2));
 
 
     float yCounter = 0;
     float yCounter = 0;
     for(const CHANGELOG_UI &changelog : m_changelogs) {
     for(const CHANGELOG_UI &changelog : m_changelogs) {
@@ -287,9 +288,9 @@ void Changelog::updateLayout() {
 }
 }
 
 
 void Changelog::onBack() {
 void Changelog::onBack() {
-    engine->getSound()->play(m_osu->getSkin()->getMenuClick());
+    engine->getSound()->play(osu->getSkin()->getMenuClick());
 
 
-    m_osu->toggleChangelog();
+    osu->toggleChangelog();
 }
 }
 
 
 void Changelog::onChangeClicked(CBaseUIButton *button) {
 void Changelog::onChangeClicked(CBaseUIButton *button) {
@@ -302,7 +303,7 @@ void Changelog::onChangeClicked(CBaseUIButton *button) {
 
 
         debugLog("url = %s\n", url.toUtf8());
         debugLog("url = %s\n", url.toUtf8());
 
 
-        m_osu->getNotificationOverlay()->addNotification("Opening browser, please wait ...", 0xffffffff, false, 0.75f);
+        osu->getNotificationOverlay()->addNotification("Opening browser, please wait ...", 0xffffffff, false, 0.75f);
         env->openURLInDefaultBrowser(url);
         env->openURLInDefaultBrowser(url);
     }
     }
 }
 }

+ 1 - 1
src/App/Osu/Changelog.h

@@ -8,7 +8,7 @@ class CBaseUILabel;
 
 
 class Changelog : public ScreenBackable {
 class Changelog : public ScreenBackable {
    public:
    public:
-    Changelog(Osu *osu);
+    Changelog();
     virtual ~Changelog();
     virtual ~Changelog();
 
 
     virtual void mouse_update(bool *propagate_clicks);
     virtual void mouse_update(bool *propagate_clicks);

+ 24 - 24
src/App/Osu/Chat.cpp

@@ -37,7 +37,7 @@ ChatChannel::ChatChannel(Chat *chat, UString name_arg) {
     ui->setDrawScrollbars(true);
     ui->setDrawScrollbars(true);
     ui->sticky = true;
     ui->sticky = true;
 
 
-    btn = new UIButton(bancho.osu, 0, 0, 0, 0, "button", name);
+    btn = new UIButton(0, 0, 0, 0, "button", name);
     btn->grabs_clicks = true;
     btn->grabs_clicks = true;
     btn->setUseDefaultSkin();
     btn->setUseDefaultSkin();
     btn->setClickCallback(fastdelegate::MakeDelegate(this, &ChatChannel::onChannelButtonClick));
     btn->setClickCallback(fastdelegate::MakeDelegate(this, &ChatChannel::onChannelButtonClick));
@@ -71,7 +71,7 @@ void ChatChannel::add_message(ChatMessage msg) {
     if(!is_system_message) {
     if(!is_system_message) {
         float name_width = m_chat->font->getStringWidth(msg.author_name);
         float name_width = m_chat->font->getStringWidth(msg.author_name);
 
 
-        auto user_box = new UIUserLabel(m_chat->m_osu, msg.author_id, msg.author_name);
+        auto user_box = new UIUserLabel(msg.author_id, msg.author_name);
         user_box->setTextColor(0xff2596be);
         user_box->setTextColor(0xff2596be);
         user_box->setPos(x, y_total);
         user_box->setPos(x, y_total);
         user_box->setSize(name_width, line_height);
         user_box->setSize(name_width, line_height);
@@ -131,12 +131,12 @@ void ChatChannel::updateLayout(Vector2 pos, Vector2 size) {
     ui->setScrollSizeToContent();
     ui->setScrollSizeToContent();
 }
 }
 
 
-Chat::Chat(Osu *osu) : OsuScreen(osu) {
+Chat::Chat() : OsuScreen() {
     font = engine->getResourceManager()->getFont("FONT_DEFAULT");
     font = engine->getResourceManager()->getFont("FONT_DEFAULT");
 
 
     m_button_container = new CBaseUIContainer(0, 0, 0, 0, "");
     m_button_container = new CBaseUIContainer(0, 0, 0, 0, "");
 
 
-    join_channel_btn = new UIButton(osu, 0, 0, 0, 0, "button", "+");
+    join_channel_btn = new UIButton(0, 0, 0, 0, "button", "+");
     join_channel_btn->setUseDefaultSkin();
     join_channel_btn->setUseDefaultSkin();
     join_channel_btn->setColor(0xffffff55);
     join_channel_btn->setColor(0xffffff55);
     join_channel_btn->setSize(button_height + 2, button_height + 2);
     join_channel_btn->setSize(button_height + 2, button_height + 2);
@@ -149,7 +149,7 @@ Chat::Chat(Osu *osu) : OsuScreen(osu) {
     m_input_box->setBackgroundColor(0xdd000000);
     m_input_box->setBackgroundColor(0xdd000000);
     addBaseUIElement(m_input_box);
     addBaseUIElement(m_input_box);
 
 
-    updateLayout(m_osu->getScreenSize());
+    updateLayout(osu->getScreenSize());
 }
 }
 
 
 Chat::~Chat() { delete m_button_container; }
 Chat::~Chat() { delete m_button_container; }
@@ -160,7 +160,7 @@ void Chat::draw(Graphics *g) {
 
 
     if(isAnimating) {
     if(isAnimating) {
         // XXX: Setting BLEND_MODE_PREMUL_ALPHA is not enough, transparency is still incorrect
         // XXX: Setting BLEND_MODE_PREMUL_ALPHA is not enough, transparency is still incorrect
-        m_osu->getSliderFrameBuffer()->enable();
+        osu->getSliderFrameBuffer()->enable();
         g->setBlendMode(Graphics::BLEND_MODE::BLEND_MODE_PREMUL_ALPHA);
         g->setBlendMode(Graphics::BLEND_MODE::BLEND_MODE_PREMUL_ALPHA);
     }
     }
 
 
@@ -191,7 +191,7 @@ void Chat::draw(Graphics *g) {
     }
     }
 
 
     if(isAnimating) {
     if(isAnimating) {
-        m_osu->getSliderFrameBuffer()->disable();
+        osu->getSliderFrameBuffer()->disable();
 
 
         g->setBlendMode(Graphics::BLEND_MODE::BLEND_MODE_ALPHA);
         g->setBlendMode(Graphics::BLEND_MODE::BLEND_MODE_ALPHA);
         g->push3DScene(McRect(0, 0, getSize().x, getSize().y));
         g->push3DScene(McRect(0, 0, getSize().x, getSize().y));
@@ -199,8 +199,8 @@ void Chat::draw(Graphics *g) {
             g->rotate3DScene(-(1.0f - m_fAnimation) * 90, 0, 0);
             g->rotate3DScene(-(1.0f - m_fAnimation) * 90, 0, 0);
             g->translate3DScene(0, -(1.0f - m_fAnimation) * getSize().y * 1.25f, -(1.0f - m_fAnimation) * 700);
             g->translate3DScene(0, -(1.0f - m_fAnimation) * getSize().y * 1.25f, -(1.0f - m_fAnimation) * 700);
 
 
-            m_osu->getSliderFrameBuffer()->setColor(COLORf(m_fAnimation, 1.0f, 1.0f, 1.0f));
-            m_osu->getSliderFrameBuffer()->draw(g, 0, 0);
+            osu->getSliderFrameBuffer()->setColor(COLORf(m_fAnimation, 1.0f, 1.0f, 1.0f));
+            osu->getSliderFrameBuffer()->draw(g, 0, 0);
         }
         }
         g->pop3DScene();
         g->pop3DScene();
     }
     }
@@ -378,7 +378,7 @@ void Chat::addChannel(UString channel_name, bool switch_to) {
         switchToChannel(chan);
         switchToChannel(chan);
     }
     }
 
 
-    updateLayout(m_osu->getScreenSize());
+    updateLayout(osu->getScreenSize());
 }
 }
 
 
 void Chat::addMessage(UString channel_name, ChatMessage msg) {
 void Chat::addMessage(UString channel_name, ChatMessage msg) {
@@ -558,7 +558,7 @@ void Chat::onDisconnect() {
     chat_channels.clear();
     chat_channels.clear();
 
 
     m_selected_channel = nullptr;
     m_selected_channel = nullptr;
-    updateLayout(m_osu->getScreenSize());
+    updateLayout(osu->getScreenSize());
 
 
     updateVisibility();
     updateVisibility();
 }
 }
@@ -566,30 +566,30 @@ void Chat::onDisconnect() {
 void Chat::onResolutionChange(Vector2 newResolution) { updateLayout(newResolution); }
 void Chat::onResolutionChange(Vector2 newResolution) { updateLayout(newResolution); }
 
 
 bool Chat::isVisibilityForced() {
 bool Chat::isVisibilityForced() {
-    if(m_osu->m_room == nullptr || m_osu->m_lobby == nullptr || m_osu->m_songBrowser2 == nullptr) return false;
+    if(osu->m_room == nullptr || osu->m_lobby == nullptr || osu->m_songBrowser2 == nullptr) return false;
     bool sitting_in_room =
     bool sitting_in_room =
-        m_osu->m_room->isVisible() && !m_osu->m_songBrowser2->isVisible() && !bancho.is_playing_a_multi_map();
-    bool sitting_in_lobby = m_osu->m_lobby->isVisible();
+        osu->m_room->isVisible() && !osu->m_songBrowser2->isVisible() && !bancho.is_playing_a_multi_map();
+    bool sitting_in_lobby = osu->m_lobby->isVisible();
     bool is_forced = (sitting_in_room || sitting_in_lobby);
     bool is_forced = (sitting_in_room || sitting_in_lobby);
 
 
     if(is_forced != visibility_was_forced) {
     if(is_forced != visibility_was_forced) {
         // Chat width changed: update the layout now
         // Chat width changed: update the layout now
         visibility_was_forced = is_forced;
         visibility_was_forced = is_forced;
-        updateLayout(m_osu->getScreenSize());
+        updateLayout(osu->getScreenSize());
     }
     }
     return is_forced;
     return is_forced;
 }
 }
 
 
 void Chat::updateVisibility() {
 void Chat::updateVisibility() {
-    auto selected_beatmap = m_osu->getSelectedBeatmap();
+    auto selected_beatmap = osu->getSelectedBeatmap();
     bool can_skip = (selected_beatmap != nullptr) && (selected_beatmap->isInSkippableSection());
     bool can_skip = (selected_beatmap != nullptr) && (selected_beatmap->isInSkippableSection());
-    bool is_spectating = m_osu->m_bModAuto || (m_osu->m_bModAutopilot && m_osu->m_bModRelax) ||
+    bool is_spectating = osu->m_bModAuto || (osu->m_bModAutopilot && osu->m_bModRelax) ||
                          (selected_beatmap != nullptr && selected_beatmap->m_bIsWatchingReplay);
                          (selected_beatmap != nullptr && selected_beatmap->m_bIsWatchingReplay);
-    bool is_clicking_circles = m_osu->isInPlayMode() && !can_skip && !is_spectating && !m_osu->m_pauseMenu->isVisible();
+    bool is_clicking_circles = osu->isInPlayMode() && !can_skip && !is_spectating && !osu->m_pauseMenu->isVisible();
     if(bancho.is_playing_a_multi_map() && !bancho.room.all_players_loaded) {
     if(bancho.is_playing_a_multi_map() && !bancho.room.all_players_loaded) {
         is_clicking_circles = false;
         is_clicking_circles = false;
     }
     }
-    bool force_hide = m_osu->m_optionsMenu->isVisible() || m_osu->m_modSelector->isVisible() || is_clicking_circles;
+    bool force_hide = osu->m_optionsMenu->isVisible() || osu->m_modSelector->isVisible() || is_clicking_circles;
     if(!bancho.is_online()) force_hide = true;
     if(!bancho.is_online()) force_hide = true;
 
 
     if(force_hide) {
     if(force_hide) {
@@ -605,13 +605,13 @@ CBaseUIContainer *Chat::setVisible(bool visible) {
     if(visible == m_bVisible) return this;
     if(visible == m_bVisible) return this;
 
 
     if(visible && bancho.user_id <= 0) {
     if(visible && bancho.user_id <= 0) {
-        m_osu->m_optionsMenu->askForLoginDetails();
+        osu->m_optionsMenu->askForLoginDetails();
         return this;
         return this;
     }
     }
 
 
     m_bVisible = visible;
     m_bVisible = visible;
     if(visible) {
     if(visible) {
-        m_osu->m_optionsMenu->setVisible(false);
+        osu->m_optionsMenu->setVisible(false);
         anim->moveQuartOut(&m_fAnimation, 1.0f, 0.25f * (1.0f - m_fAnimation), true);
         anim->moveQuartOut(&m_fAnimation, 1.0f, 0.25f * (1.0f - m_fAnimation), true);
 
 
         if(m_selected_channel != nullptr && !m_selected_channel->read) {
         if(m_selected_channel != nullptr && !m_selected_channel->read) {
@@ -619,7 +619,7 @@ CBaseUIContainer *Chat::setVisible(bool visible) {
         }
         }
 
 
         if(layout_update_scheduled) {
         if(layout_update_scheduled) {
-            updateLayout(m_osu->getScreenSize());
+            updateLayout(osu->getScreenSize());
         }
         }
     } else {
     } else {
         anim->moveQuadOut(&m_fAnimation, 0.0f, 0.25f * m_fAnimation, true);
         anim->moveQuadOut(&m_fAnimation, 0.0f, 0.25f * m_fAnimation, true);
@@ -636,6 +636,6 @@ bool Chat::isMouseInChat() {
 
 
 void Chat::askWhatChannelToJoin(CBaseUIButton *btn) {
 void Chat::askWhatChannelToJoin(CBaseUIButton *btn) {
     // XXX: Could display nicer UI with full channel list (chat_channels in Bancho.cpp)
     // XXX: Could display nicer UI with full channel list (chat_channels in Bancho.cpp)
-    m_osu->m_prompt->prompt("Type in the channel you want to join (e.g. '#osu'):",
-                            fastdelegate::MakeDelegate(this, &Chat::join));
+    osu->m_prompt->prompt("Type in the channel you want to join (e.g. '#osu'):",
+                          fastdelegate::MakeDelegate(this, &Chat::join));
 }
 }

+ 1 - 1
src/App/Osu/Chat.h

@@ -35,7 +35,7 @@ struct ChatChannel {
 
 
 class Chat : public OsuScreen {
 class Chat : public OsuScreen {
    public:
    public:
-    Chat(Osu *osu);
+    Chat();
     ~Chat();
     ~Chat();
 
 
     virtual void draw(Graphics *g);
     virtual void draw(Graphics *g);

+ 11 - 18
src/App/Osu/Circle.cpp

@@ -1,10 +1,3 @@
-//================ Copyright (c) 2015, PG, All rights reserved. =================//
-//
-// Purpose:		circle
-//
-// $NoKeywords: $circle
-//===============================================================================//
-
 #include "Circle.h"
 #include "Circle.h"
 
 
 #include "AnimationHandler.h"
 #include "AnimationHandler.h"
@@ -55,7 +48,7 @@ void Circle::drawApproachCircle(Graphics *g, Beatmap *beatmap, Vector2 rawPos, i
               (int)(COLOR_GET_Bi(comboColor) * colorRGBMultiplier * osu_circle_color_saturation.getFloat()));
               (int)(COLOR_GET_Bi(comboColor) * colorRGBMultiplier * osu_circle_color_saturation.getFloat()));
 
 
     drawApproachCircle(g, beatmap->getSkin(), beatmap->osuCoords2Pixels(rawPos), comboColor,
     drawApproachCircle(g, beatmap->getSkin(), beatmap->osuCoords2Pixels(rawPos), comboColor,
-                       beatmap->getHitcircleDiameter(), approachScale, alpha, beatmap->getOsu()->getModHD(),
+                       beatmap->getHitcircleDiameter(), approachScale, alpha, osu->getModHD(),
                        overrideHDApproachCircle);
                        overrideHDApproachCircle);
 }
 }
 
 
@@ -150,7 +143,7 @@ void Circle::drawSliderStartCircle(Graphics *g, Skin *skin, Vector2 pos, float h
 
 
     // approach circle
     // approach circle
     /// drawApproachCircle(g, skin, pos, comboColor, beatmap->getHitcircleDiameter(), approachScale, alpha,
     /// drawApproachCircle(g, skin, pos, comboColor, beatmap->getHitcircleDiameter(), approachScale, alpha,
-    /// beatmap->getOsu()->getModHD(), overrideHDApproachCircle); // they are now drawn separately in draw2()
+    /// osu->getModHD(), overrideHDApproachCircle); // they are now drawn separately in draw2()
 
 
     // circle
     // circle
     const float circleImageScale = hitcircleDiameter / (128.0f * (skin->isSliderStartCircle2x() ? 2.0f : 1.0f));
     const float circleImageScale = hitcircleDiameter / (128.0f * (skin->isSliderStartCircle2x() ? 2.0f : 1.0f));
@@ -433,10 +426,10 @@ Circle::~Circle() { onReset(0); }
 
 
 void Circle::draw(Graphics *g) {
 void Circle::draw(Graphics *g) {
     HitObject::draw(g);
     HitObject::draw(g);
-    Skin *skin = m_beatmap->getOsu()->getSkin();
+    Skin *skin = osu->getSkin();
 
 
     // draw hit animation
     // draw hit animation
-    if(m_fHitAnimation > 0.0f && m_fHitAnimation != 1.0f && !m_beatmap->getOsu()->getModHD()) {
+    if(m_fHitAnimation > 0.0f && m_fHitAnimation != 1.0f && !osu->getModHD()) {
         float alpha = 1.0f - m_fHitAnimation;
         float alpha = 1.0f - m_fHitAnimation;
 
 
         float scale = m_fHitAnimation;
         float scale = m_fHitAnimation;
@@ -464,7 +457,7 @@ void Circle::draw(Graphics *g) {
         return;
         return;
 
 
     // draw circle
     // draw circle
-    const bool hd = m_beatmap->getOsu()->getModHD();
+    const bool hd = osu->getModHD();
     Vector2 shakeCorrectedPos = m_vRawPos;
     Vector2 shakeCorrectedPos = m_vRawPos;
     if(engine->getTime() < m_fShakeAnimation && !m_beatmap->isInMafhamRenderChunk())  // handle note blocking shaking
     if(engine->getTime() < m_fShakeAnimation && !m_beatmap->isInMafhamRenderChunk())  // handle note blocking shaking
     {
     {
@@ -495,7 +488,7 @@ void Circle::draw2(Graphics *g) {
                  // we still need to draw the object
                  // we still need to draw the object
 
 
     // draw approach circle
     // draw approach circle
-    const bool hd = m_beatmap->getOsu()->getModHD();
+    const bool hd = osu->getModHD();
 
 
     // HACKHACK: don't fucking change this piece of code here, it fixes a heisenbug
     // HACKHACK: don't fucking change this piece of code here, it fixes a heisenbug
     // (https://github.com/McKay42/McOsu/issues/165)
     // (https://github.com/McKay42/McOsu/issues/165)
@@ -515,17 +508,17 @@ void Circle::update(long curPos) {
 
 
     // if we have not been clicked yet, check if we are in the timeframe of a miss, also handle auto and relax
     // if we have not been clicked yet, check if we are in the timeframe of a miss, also handle auto and relax
     if(!m_bFinished) {
     if(!m_bFinished) {
-        if(m_beatmap->getOsu()->getModAuto()) {
+        if(osu->getModAuto()) {
             if(curPos >= m_iTime) onHit(LiveScore::HIT::HIT_300, 0);
             if(curPos >= m_iTime) onHit(LiveScore::HIT::HIT_300, 0);
         } else {
         } else {
             const long delta = curPos - m_iTime;
             const long delta = curPos - m_iTime;
 
 
-            if(m_beatmap->getOsu()->getModRelax()) {
+            if(osu->getModRelax()) {
                 if(curPos >= m_iTime + (long)m_osu_relax_offset_ref->getInt() && !m_beatmap->isPaused() &&
                 if(curPos >= m_iTime + (long)m_osu_relax_offset_ref->getInt() && !m_beatmap->isPaused() &&
                    !m_beatmap->isContinueScheduled()) {
                    !m_beatmap->isContinueScheduled()) {
                     const Vector2 pos = m_beatmap->osuCoords2Pixels(m_vRawPos);
                     const Vector2 pos = m_beatmap->osuCoords2Pixels(m_vRawPos);
                     const float cursorDelta = (m_beatmap->getCursorPos() - pos).length();
                     const float cursorDelta = (m_beatmap->getCursorPos() - pos).length();
-                    if((cursorDelta < m_beatmap->getHitcircleDiameter() / 2.0f && m_beatmap->getOsu()->getModRelax())) {
+                    if((cursorDelta < m_beatmap->getHitcircleDiameter() / 2.0f && osu->getModRelax())) {
                         LiveScore::HIT result = GameRules::getHitResult(delta, m_beatmap);
                         LiveScore::HIT result = GameRules::getHitResult(delta, m_beatmap);
 
 
                         if(result != LiveScore::HIT::HIT_NULL) {
                         if(result != LiveScore::HIT::HIT_NULL) {
@@ -551,8 +544,8 @@ void Circle::update(long curPos) {
 }
 }
 
 
 void Circle::updateStackPosition(float stackOffset) {
 void Circle::updateStackPosition(float stackOffset) {
-    m_vRawPos = m_vOriginalRawPos - Vector2(m_iStack * stackOffset,
-                                            m_iStack * stackOffset * (m_beatmap->getOsu()->getModHR() ? -1.0f : 1.0f));
+    m_vRawPos =
+        m_vOriginalRawPos - Vector2(m_iStack * stackOffset, m_iStack * stackOffset * (osu->getModHR() ? -1.0f : 1.0f));
 }
 }
 
 
 void Circle::miss(long curPos) {
 void Circle::miss(long curPos) {

+ 16 - 17
src/App/Osu/Database.cpp

@@ -318,7 +318,7 @@ class DatabaseLoader : public Resource {
 ConVar *Database::m_name_ref = NULL;
 ConVar *Database::m_name_ref = NULL;
 ConVar *Database::m_osu_songbrowser_scores_sortingtype_ref = NULL;
 ConVar *Database::m_osu_songbrowser_scores_sortingtype_ref = NULL;
 
 
-Database::Database(Osu *osu) {
+Database::Database() {
     // convar refs
     // convar refs
     if(m_name_ref == NULL) m_name_ref = convar->getConVarByName("name");
     if(m_name_ref == NULL) m_name_ref = convar->getConVarByName("name");
     if(m_osu_songbrowser_scores_sortingtype_ref == NULL)
     if(m_osu_songbrowser_scores_sortingtype_ref == NULL)
@@ -336,7 +336,6 @@ Database::Database(Osu *osu) {
     m_fLoadingProgress = 0.0f;
     m_fLoadingProgress = 0.0f;
     m_bInterruptLoad = false;
     m_bInterruptLoad = false;
 
 
-    m_osu = osu;
     m_iVersion = 0;
     m_iVersion = 0;
     m_iFolderCount = 0;
     m_iFolderCount = 0;
 
 
@@ -906,12 +905,12 @@ void Database::scheduleLoadRaw() {
 
 
         m_bFoundChanges = m_iNumBeatmapsToLoad > 0;
         m_bFoundChanges = m_iNumBeatmapsToLoad > 0;
         if(m_bFoundChanges)
         if(m_bFoundChanges)
-            m_osu->getNotificationOverlay()->addNotification(
+            osu->getNotificationOverlay()->addNotification(
                 UString::format(m_iNumBeatmapsToLoad == 1 ? "Adding %i new beatmap." : "Adding %i new beatmaps.",
                 UString::format(m_iNumBeatmapsToLoad == 1 ? "Adding %i new beatmap." : "Adding %i new beatmaps.",
                                 m_iNumBeatmapsToLoad),
                                 m_iNumBeatmapsToLoad),
                 0xff00ff00);
                 0xff00ff00);
         else
         else
-            m_osu->getNotificationOverlay()->addNotification(
+            osu->getNotificationOverlay()->addNotification(
                 UString::format("No new beatmaps detected.", m_iNumBeatmapsToLoad), 0xff00ff00);
                 UString::format("No new beatmaps detected.", m_iNumBeatmapsToLoad), 0xff00ff00);
     }
     }
 
 
@@ -964,8 +963,8 @@ void Database::loadDB(Packet *db, bool &fallbackToRawLoad) {
 
 
     if(m_iVersion < 20170222) {
     if(m_iVersion < 20170222) {
         debugLog("Database: Version is quite old, below 20170222 ...\n");
         debugLog("Database: Version is quite old, below 20170222 ...\n");
-        m_osu->getNotificationOverlay()->addNotification("osu!.db version too old, update osu! and try again!",
-                                                         0xffff0000);
+        osu->getNotificationOverlay()->addNotification("osu!.db version too old, update osu! and try again!",
+                                                       0xffff0000);
         m_fLoadingProgress = 1.0f;
         m_fLoadingProgress = 1.0f;
         return;
         return;
     }
     }
@@ -973,14 +972,14 @@ void Database::loadDB(Packet *db, bool &fallbackToRawLoad) {
     if(!osu_database_ignore_version_warnings.getBool()) {
     if(!osu_database_ignore_version_warnings.getBool()) {
         if(m_iVersion < 20190207)  // xexxar angles star recalc
         if(m_iVersion < 20190207)  // xexxar angles star recalc
         {
         {
-            m_osu->getNotificationOverlay()->addNotification(
-                "osu!.db version is old,  let osu! update when convenient.", 0xffffff00, false, 3.0f);
+            osu->getNotificationOverlay()->addNotification("osu!.db version is old,  let osu! update when convenient.",
+                                                           0xffffff00, false, 3.0f);
         }
         }
     }
     }
 
 
     // hard cap upper db version
     // hard cap upper db version
     if(m_iVersion > osu_database_version.getInt() && !osu_database_ignore_version.getBool()) {
     if(m_iVersion > osu_database_version.getInt() && !osu_database_ignore_version.getBool()) {
-        m_osu->getNotificationOverlay()->addNotification(
+        osu->getNotificationOverlay()->addNotification(
             UString::format("osu!.db version unknown (%i),  using fallback loader.", m_iVersion), 0xffffff00, false,
             UString::format("osu!.db version unknown (%i),  using fallback loader.", m_iVersion), 0xffffff00, false,
             5.0f);
             5.0f);
 
 
@@ -1171,7 +1170,7 @@ void Database::loadDB(Packet *db, bool &fallbackToRawLoad) {
         // fill diff with data
         // fill diff with data
         if(mode != 0) continue;
         if(mode != 0) continue;
 
 
-        DatabaseBeatmap *diff2 = new DatabaseBeatmap(m_osu, fullFilePath, beatmapPath);
+        DatabaseBeatmap *diff2 = new DatabaseBeatmap(fullFilePath, beatmapPath);
         {
         {
             diff2->m_sTitle = songTitle;
             diff2->m_sTitle = songTitle;
             diff2->m_sAudioFileName = audioFileName;
             diff2->m_sAudioFileName = audioFileName;
@@ -1286,7 +1285,7 @@ void Database::loadDB(Packet *db, bool &fallbackToRawLoad) {
         if(beatmapSets[i].diffs2->empty()) continue;  // sanity check
         if(beatmapSets[i].diffs2->empty()) continue;  // sanity check
 
 
         if(beatmapSets[i].setID > 0) {
         if(beatmapSets[i].setID > 0) {
-            DatabaseBeatmap *bm = new DatabaseBeatmap(m_osu, beatmapSets[i].diffs2);
+            DatabaseBeatmap *bm = new DatabaseBeatmap(beatmapSets[i].diffs2);
             m_databaseBeatmaps.push_back(bm);
             m_databaseBeatmaps.push_back(bm);
         } else {
         } else {
             // set with invalid ID: treat all its diffs separately. we'll group the diffs by title+artist.
             // set with invalid ID: treat all its diffs separately. we'll group the diffs by title+artist.
@@ -1305,7 +1304,7 @@ void Database::loadDB(Packet *db, bool &fallbackToRawLoad) {
             }
             }
 
 
             for(auto scuffed_set : titleArtistToBeatmap) {
             for(auto scuffed_set : titleArtistToBeatmap) {
-                DatabaseBeatmap *bm = new DatabaseBeatmap(m_osu, scuffed_set.second);
+                DatabaseBeatmap *bm = new DatabaseBeatmap(scuffed_set.second);
                 m_databaseBeatmaps.push_back(bm);
                 m_databaseBeatmaps.push_back(bm);
             }
             }
         }
         }
@@ -1766,7 +1765,7 @@ BeatmapSet *Database::loadRawBeatmap(std::string beatmapPath) {
         std::string fullFilePath = beatmapPath;
         std::string fullFilePath = beatmapPath;
         fullFilePath.append(beatmapFiles[i]);
         fullFilePath.append(beatmapFiles[i]);
 
 
-        BeatmapDifficulty *diff2 = new BeatmapDifficulty(m_osu, fullFilePath, beatmapPath);
+        BeatmapDifficulty *diff2 = new BeatmapDifficulty(fullFilePath, beatmapPath);
         if(diff2->loadMetadata()) {
         if(diff2->loadMetadata()) {
             diffs2->push_back(diff2);
             diffs2->push_back(diff2);
         } else {
         } else {
@@ -1781,7 +1780,7 @@ BeatmapSet *Database::loadRawBeatmap(std::string beatmapPath) {
     if(diffs2->empty()) {
     if(diffs2->empty()) {
         delete diffs2;
         delete diffs2;
     } else {
     } else {
-        set = new BeatmapSet(m_osu, diffs2);
+        set = new BeatmapSet(diffs2);
     }
     }
 
 
     return set;
     return set;
@@ -1789,7 +1788,7 @@ BeatmapSet *Database::loadRawBeatmap(std::string beatmapPath) {
 
 
 void Database::onScoresRename(UString args) {
 void Database::onScoresRename(UString args) {
     if(args.length() < 2) {
     if(args.length() < 2) {
-        m_osu->getNotificationOverlay()->addNotification(
+        osu->getNotificationOverlay()->addNotification(
             UString::format("Usage: %s MyNewName", osu_scores_rename.getName().toUtf8()));
             UString::format("Usage: %s MyNewName", osu_scores_rename.getName().toUtf8()));
         return;
         return;
     }
     }
@@ -1811,9 +1810,9 @@ void Database::onScoresRename(UString args) {
     }
     }
 
 
     if(numRenamedScores < 1)
     if(numRenamedScores < 1)
-        m_osu->getNotificationOverlay()->addNotification("No (pp) scores for active user.");
+        osu->getNotificationOverlay()->addNotification("No (pp) scores for active user.");
     else {
     else {
-        m_osu->getNotificationOverlay()->addNotification(UString::format("Renamed %i scores.", numRenamedScores));
+        osu->getNotificationOverlay()->addNotification(UString::format("Renamed %i scores.", numRenamedScores));
 
 
         m_bDidScoresChangeForSave = true;
         m_bDidScoresChangeForSave = true;
         m_bDidScoresChangeForStats = true;
         m_bDidScoresChangeForStats = true;

+ 1 - 3
src/App/Osu/Database.h

@@ -8,7 +8,6 @@
 class Timer;
 class Timer;
 class ConVar;
 class ConVar;
 
 
-class Osu;
 class OsuFile;
 class OsuFile;
 class DatabaseBeatmap;
 class DatabaseBeatmap;
 class DatabaseLoader;
 class DatabaseLoader;
@@ -57,7 +56,7 @@ class Database {
     };
     };
 
 
    public:
    public:
-    Database(Osu *osu);
+    Database();
     ~Database();
     ~Database();
 
 
     void update();
     void update();
@@ -132,7 +131,6 @@ class Database {
     void onScoresRename(UString args);
     void onScoresRename(UString args);
     void onScoresExport();
     void onScoresExport();
 
 
-    Osu *m_osu;
     Timer *m_importTimer;
     Timer *m_importTimer;
     bool m_bIsFirstLoad;   // only load differences after first raw load
     bool m_bIsFirstLoad;   // only load differences after first raw load
     bool m_bFoundChanges;  // for total refresh detection of raw loading
     bool m_bFoundChanges;  // for total refresh detection of raw loading

+ 11 - 22
src/App/Osu/DatabaseBeatmap.cpp

@@ -1,10 +1,3 @@
-//================ Copyright (c) 2020, PG, All rights reserved. =================//
-//
-// Purpose:		loader + container for raw beatmap files/data (v2 rewrite)
-//
-// $NoKeywords: $osudiff
-//===============================================================================//
-
 #include "DatabaseBeatmap.h"
 #include "DatabaseBeatmap.h"
 
 
 #include <assert.h>
 #include <assert.h>
@@ -85,9 +78,7 @@ ConVar *DatabaseBeatmap::m_osu_stars_stacking_ref = NULL;
 ConVar *DatabaseBeatmap::m_osu_debug_pp_ref = NULL;
 ConVar *DatabaseBeatmap::m_osu_debug_pp_ref = NULL;
 ConVar *DatabaseBeatmap::m_osu_slider_end_inside_check_offset_ref = NULL;
 ConVar *DatabaseBeatmap::m_osu_slider_end_inside_check_offset_ref = NULL;
 
 
-DatabaseBeatmap::DatabaseBeatmap(Osu *osu, std::string filePath, std::string folder, bool filePathIsInMemoryBeatmap) {
-    m_osu = osu;
-
+DatabaseBeatmap::DatabaseBeatmap(std::string filePath, std::string folder, bool filePathIsInMemoryBeatmap) {
     m_sFilePath = filePath;
     m_sFilePath = filePath;
     m_bFilePathIsInMemoryBeatmap = filePathIsInMemoryBeatmap;
     m_bFilePathIsInMemoryBeatmap = filePathIsInMemoryBeatmap;
 
 
@@ -145,8 +136,7 @@ DatabaseBeatmap::DatabaseBeatmap(Osu *osu, std::string filePath, std::string fol
     m_iOnlineOffset = 0;
     m_iOnlineOffset = 0;
 }
 }
 
 
-DatabaseBeatmap::DatabaseBeatmap(Osu *osu, std::vector<DatabaseBeatmap *> *difficulties)
-    : DatabaseBeatmap(osu, "", "") {
+DatabaseBeatmap::DatabaseBeatmap(std::vector<DatabaseBeatmap *> *difficulties) : DatabaseBeatmap("", "") {
     m_difficulties = difficulties;
     m_difficulties = difficulties;
     if(m_difficulties->empty()) return;
     if(m_difficulties->empty()) return;
 
 
@@ -1210,7 +1200,7 @@ bool DatabaseBeatmap::loadMetadata() {
 
 
         // NOTE: if we have our own stars/bpm cached then use that
         // NOTE: if we have our own stars/bpm cached then use that
         bool bpm_was_cached = false;
         bool bpm_was_cached = false;
-        auto db = bancho.osu->getSongBrowser()->getDatabase();
+        auto db = osu->getSongBrowser()->getDatabase();
         const auto result = db->m_starsCache.find(getMD5Hash());
         const auto result = db->m_starsCache.find(getMD5Hash());
         if(result != db->m_starsCache.end()) {
         if(result != db->m_starsCache.end()) {
             if(result->second.starsNomod >= 0.f) {
             if(result->second.starsNomod >= 0.f) {
@@ -1390,10 +1380,9 @@ DatabaseBeatmap::LOAD_GAMEPLAY_RESULT DatabaseBeatmap::loadGameplay(DatabaseBeat
             const float AR = beatmap->getAR();
             const float AR = beatmap->getAR();
             const float CS = beatmap->getCS();
             const float CS = beatmap->getCS();
             const float OD = beatmap->getOD();
             const float OD = beatmap->getOD();
-            const float speedMultiplier =
-                databaseBeatmap->m_osu->getSpeedMultiplier();  // NOTE: not this->getSpeedMultiplier()!
-            const bool relax = databaseBeatmap->m_osu->getModRelax();
-            const bool touchDevice = databaseBeatmap->m_osu->getModTD();
+            const float speedMultiplier = osu->getSpeedMultiplier();  // NOTE: not this->getSpeedMultiplier()!
+            const bool relax = osu->getModRelax();
+            const bool touchDevice = osu->getModTD();
 
 
             LOAD_DIFFOBJ_RESULT diffres =
             LOAD_DIFFOBJ_RESULT diffres =
                 DatabaseBeatmap::loadDifficultyHitObjects(osuFilePath, AR, CS, speedMultiplier);
                 DatabaseBeatmap::loadDifficultyHitObjects(osuFilePath, AR, CS, speedMultiplier);
@@ -1406,7 +1395,7 @@ DatabaseBeatmap::LOAD_GAMEPLAY_RESULT DatabaseBeatmap::loadGameplay(DatabaseBeat
                 diffres.diffobjects, CS, OD, speedMultiplier, relax, touchDevice, &aim, &aimSliderFactor, &speed,
                 diffres.diffobjects, CS, OD, speedMultiplier, relax, touchDevice, &aim, &aimSliderFactor, &speed,
                 &speedNotes);
                 &speedNotes);
             double pp = DifficultyCalculator::calculatePPv2(
             double pp = DifficultyCalculator::calculatePPv2(
-                beatmap->getOsu(), beatmap, aim, aimSliderFactor, speed, speedNotes, databaseBeatmap->m_iNumObjects,
+                beatmap, aim, aimSliderFactor, speed, speedNotes, databaseBeatmap->m_iNumObjects,
                 databaseBeatmap->m_iNumCircles, databaseBeatmap->m_iNumSliders, databaseBeatmap->m_iNumSpinners,
                 databaseBeatmap->m_iNumCircles, databaseBeatmap->m_iNumSliders, databaseBeatmap->m_iNumSpinners,
                 maxPossibleCombo);
                 maxPossibleCombo);
 
 
@@ -1659,10 +1648,10 @@ void DatabaseBeatmapStarCalculator::init() {
     // technically the getSelectedBeatmap() call here is a bit unsafe, since the beatmap could have changed already
     // technically the getSelectedBeatmap() call here is a bit unsafe, since the beatmap could have changed already
     // between async and sync, but in that case we recalculate immediately after anyways
     // between async and sync, but in that case we recalculate immediately after anyways
     if(!m_bDead.load() && m_iErrorCode == 0)
     if(!m_bDead.load() && m_iErrorCode == 0)
-        m_pp = DifficultyCalculator::calculatePPv2(m_diff2->m_osu, m_diff2->m_osu->getSelectedBeatmap(),
-                                                   m_aimStars.load(), m_aimSliderFactor.load(), m_speedStars.load(),
-                                                   m_speedNotes.load(), m_iNumObjects.load(), m_iNumCircles.load(),
-                                                   m_iNumSliders.load(), m_iNumSpinners.load(), m_iMaxPossibleCombo);
+        m_pp = DifficultyCalculator::calculatePPv2(osu->getSelectedBeatmap(), m_aimStars.load(),
+                                                   m_aimSliderFactor.load(), m_speedStars.load(), m_speedNotes.load(),
+                                                   m_iNumObjects.load(), m_iNumCircles.load(), m_iNumSliders.load(),
+                                                   m_iNumSpinners.load(), m_iMaxPossibleCombo);
 
 
     m_bReady = true;
     m_bReady = true;
 }
 }

+ 2 - 7
src/App/Osu/DatabaseBeatmap.h

@@ -3,7 +3,6 @@
 #include "Osu.h"
 #include "Osu.h"
 #include "Resource.h"
 #include "Resource.h"
 
 
-class Osu;
 class Beatmap;
 class Beatmap;
 class HitObject;
 class HitObject;
 
 
@@ -89,8 +88,8 @@ class DatabaseBeatmap {
         bool isNaN;
         bool isNaN;
     };
     };
 
 
-    DatabaseBeatmap(Osu *osu, std::string filePath, std::string folder, bool filePathIsInMemoryBeatmap = false);
-    DatabaseBeatmap(Osu *osu, std::vector<DatabaseBeatmap *> *difficulties);
+    DatabaseBeatmap(std::string filePath, std::string folder, bool filePathIsInMemoryBeatmap = false);
+    DatabaseBeatmap(std::vector<DatabaseBeatmap *> *difficulties);
     ~DatabaseBeatmap();
     ~DatabaseBeatmap();
 
 
     static LOAD_DIFFOBJ_RESULT loadDifficultyHitObjects(const std::string &osuFilePath, float AR, float CS,
     static LOAD_DIFFOBJ_RESULT loadDifficultyHitObjects(const std::string &osuFilePath, float AR, float CS,
@@ -112,8 +111,6 @@ class DatabaseBeatmap {
 
 
     void setLocalOffset(long localOffset) { m_iLocalOffset = localOffset; }
     void setLocalOffset(long localOffset) { m_iLocalOffset = localOffset; }
 
 
-    inline Osu *getOsu() const { return m_osu; }
-
     inline std::string getFolder() const { return m_sFolder; }
     inline std::string getFolder() const { return m_sFolder; }
     inline std::string getFilePath() const { return m_sFilePath; }
     inline std::string getFilePath() const { return m_sFilePath; }
 
 
@@ -330,8 +327,6 @@ class DatabaseBeatmap {
         int beatmapVersion, std::vector<SLIDER> &sliders, zarray<TIMINGPOINT> &timingpoints, float sliderMultiplier,
         int beatmapVersion, std::vector<SLIDER> &sliders, zarray<TIMINGPOINT> &timingpoints, float sliderMultiplier,
         float sliderTickRate, const std::atomic<bool> &dead);
         float sliderTickRate, const std::atomic<bool> &dead);
 
 
-    Osu *m_osu;
-
     std::string m_sFolder;    // path to folder containing .osu file (e.g. "/path/to/beatmapfolder/")
     std::string m_sFolder;    // path to folder containing .osu file (e.g. "/path/to/beatmapfolder/")
     std::string m_sFilePath;  // path to .osu file (e.g. "/path/to/beatmapfolder/beatmap.osu")
     std::string m_sFilePath;  // path to .osu file (e.g. "/path/to/beatmapfolder/beatmap.osu")
     bool m_bFilePathIsInMemoryBeatmap;
     bool m_bFilePathIsInMemoryBeatmap;

+ 1 - 1
src/App/Osu/DifficultyCalculator.cpp

@@ -1085,7 +1085,7 @@ double DifficultyCalculator::calculateStarDiffForHitObjects(
     return calculateTotalStarsFromSkills(*aim, *speed);
     return calculateTotalStarsFromSkills(*aim, *speed);
 }
 }
 
 
-double DifficultyCalculator::calculatePPv2(Osu *osu, Beatmap *beatmap, double aim, double aimSliderFactor, double speed,
+double DifficultyCalculator::calculatePPv2(Beatmap *beatmap, double aim, double aimSliderFactor, double speed,
                                            double speedNotes, int numHitObjects, int numCircles, int numSliders,
                                            double speedNotes, int numHitObjects, int numCircles, int numSliders,
                                            int numSpinners, int maxPossibleCombo, int combo, int misses, int c300,
                                            int numSpinners, int maxPossibleCombo, int combo, int misses, int c300,
                                            int c100, int c50) {
                                            int c100, int c50) {

+ 3 - 15
src/App/Osu/DifficultyCalculator.h

@@ -1,16 +1,6 @@
-//================ Copyright (c) 2019, PG & Francesco149, All rights reserved. =================//
-//
-// Purpose:		star rating + pp calculation, based on https://github.com/Francesco149/oppai/
-//
-// $NoKeywords: $tomstarspp
-//==============================================================================================//
-
-#ifndef OSUDIFFICULTYCALCULATOR_H
-#define OSUDIFFICULTYCALCULATOR_H
-
+#pragma once
 #include "cbase.h"
 #include "cbase.h"
 
 
-class Osu;
 class Beatmap;
 class Beatmap;
 
 
 class SliderCurve;
 class SliderCurve;
@@ -122,8 +112,8 @@ class DifficultyCalculator {
                                                  std::vector<double> *outSpeedStrains, const std::atomic<bool> &dead);
                                                  std::vector<double> *outSpeedStrains, const std::atomic<bool> &dead);
 
 
     // pp, use runtime mods (convenience)
     // pp, use runtime mods (convenience)
-    static double calculatePPv2(Osu *osu, Beatmap *beatmap, double aim, double aimSliderFactor, double speed,
-                                double speedNotes, int numHitObjects, int numCircles, int numSliders, int numSpinners,
+    static double calculatePPv2(Beatmap *beatmap, double aim, double aimSliderFactor, double speed, double speedNotes,
+                                int numHitObjects, int numCircles, int numSliders, int numSpinners,
                                 int maxPossibleCombo, int combo = -1, int misses = 0, int c300 = -1, int c100 = 0,
                                 int maxPossibleCombo, int combo = -1, int misses = 0, int c300 = -1, int c100 = 0,
                                 int c50 = 0);
                                 int c50 = 0);
 
 
@@ -167,5 +157,3 @@ class DifficultyCalculator {
     static double computeSpeedValue(const ScoreData &score, const Attributes &attributes, double effectiveMissCount);
     static double computeSpeedValue(const ScoreData &score, const Attributes &attributes, double effectiveMissCount);
     static double computeAccuracyValue(const ScoreData &score, const Attributes &attributes);
     static double computeAccuracyValue(const ScoreData &score, const Attributes &attributes);
 };
 };
-
-#endif

+ 22 - 35
src/App/Osu/GameRules.h

@@ -1,13 +1,4 @@
-//================ Copyright (c) 2016, PG, All rights reserved. =================//
-//
-// Purpose:		difficulty & playfield behaviour
-//
-// $NoKeywords: $osugr
-//===============================================================================//
-
-#ifndef OSUGAMERULES_H
-#define OSUGAMERULES_H
-
+#pragma once
 #include "Beatmap.h"
 #include "Beatmap.h"
 #include "ConVar.h"
 #include "ConVar.h"
 #include "Osu.h"
 #include "Osu.h"
@@ -50,7 +41,7 @@ class GameRules {
     {
     {
         const float fade_out_time = osu_hitobject_fade_out_time.getFloat();
         const float fade_out_time = osu_hitobject_fade_out_time.getFloat();
         const float multiplier_min = osu_hitobject_fade_out_time_speed_multiplier_min.getFloat();
         const float multiplier_min = osu_hitobject_fade_out_time_speed_multiplier_min.getFloat();
-        return fade_out_time * (1.0f / std::max(beatmap->getOsu()->getAnimationSpeedMultiplier(), multiplier_min));
+        return fade_out_time * (1.0f / std::max(osu->getAnimationSpeedMultiplier(), multiplier_min));
     }
     }
 
 
     static inline long getFadeInTime() { return (long)osu_hitobject_fade_in_time.getInt(); }
     static inline long getFadeInTime() { return (long)osu_hitobject_fade_in_time.getInt(); }
@@ -162,18 +153,17 @@ class GameRules {
     }
     }
     static float getApproachRateForSpeedMultiplier(Beatmap *beatmap)  // respect all mods and overrides
     static float getApproachRateForSpeedMultiplier(Beatmap *beatmap)  // respect all mods and overrides
     {
     {
-        return getApproachRateForSpeedMultiplier(beatmap, beatmap->getOsu()->getSpeedMultiplier());
+        return getApproachRateForSpeedMultiplier(beatmap, osu->getSpeedMultiplier());
     }
     }
     static float getRawApproachRateForSpeedMultiplier(Beatmap *beatmap)  // ignore AR override
     static float getRawApproachRateForSpeedMultiplier(Beatmap *beatmap)  // ignore AR override
     {
     {
-        return mapDifficultyRangeInv(
-            (float)getRawApproachTime(beatmap) * (1.0f / beatmap->getOsu()->getSpeedMultiplier()), getMinApproachTime(),
-            getMidApproachTime(), getMaxApproachTime());
+        return mapDifficultyRangeInv((float)getRawApproachTime(beatmap) * (1.0f / osu->getSpeedMultiplier()),
+                                     getMinApproachTime(), getMidApproachTime(), getMaxApproachTime());
     }
     }
     static float getConstantApproachRateForSpeedMultiplier(
     static float getConstantApproachRateForSpeedMultiplier(
         Beatmap *beatmap)  // ignore AR override, keep AR consistent through speed changes
         Beatmap *beatmap)  // ignore AR override, keep AR consistent through speed changes
     {
     {
-        return mapDifficultyRangeInv((float)getRawApproachTime(beatmap) * beatmap->getOsu()->getSpeedMultiplier(),
+        return mapDifficultyRangeInv((float)getRawApproachTime(beatmap) * osu->getSpeedMultiplier(),
                                      getMinApproachTime(), getMidApproachTime(), getMaxApproachTime());
                                      getMinApproachTime(), getMidApproachTime(), getMaxApproachTime());
     }
     }
     static float getRawConstantApproachRateForSpeedMultiplier(
     static float getRawConstantApproachRateForSpeedMultiplier(
@@ -199,18 +189,17 @@ class GameRules {
     }
     }
     static float getOverallDifficultyForSpeedMultiplier(Beatmap *beatmap)  // respect all mods and overrides
     static float getOverallDifficultyForSpeedMultiplier(Beatmap *beatmap)  // respect all mods and overrides
     {
     {
-        return getOverallDifficultyForSpeedMultiplier(beatmap, beatmap->getOsu()->getSpeedMultiplier());
+        return getOverallDifficultyForSpeedMultiplier(beatmap, osu->getSpeedMultiplier());
     }
     }
     static float getRawOverallDifficultyForSpeedMultiplier(Beatmap *beatmap)  // ignore OD override
     static float getRawOverallDifficultyForSpeedMultiplier(Beatmap *beatmap)  // ignore OD override
     {
     {
-        return mapDifficultyRangeInv(
-            (float)getRawHitWindow300(beatmap) * (1.0f / beatmap->getOsu()->getSpeedMultiplier()), getMinHitWindow300(),
-            getMidHitWindow300(), getMaxHitWindow300());
+        return mapDifficultyRangeInv((float)getRawHitWindow300(beatmap) * (1.0f / osu->getSpeedMultiplier()),
+                                     getMinHitWindow300(), getMidHitWindow300(), getMaxHitWindow300());
     }
     }
     static float getConstantOverallDifficultyForSpeedMultiplier(
     static float getConstantOverallDifficultyForSpeedMultiplier(
         Beatmap *beatmap)  // ignore OD override, keep OD consistent through speed changes
         Beatmap *beatmap)  // ignore OD override, keep OD consistent through speed changes
     {
     {
-        return mapDifficultyRangeInv((float)getRawHitWindow300(beatmap) * beatmap->getOsu()->getSpeedMultiplier(),
+        return mapDifficultyRangeInv((float)getRawHitWindow300(beatmap) * osu->getSpeedMultiplier(),
                                      getMinHitWindow300(), getMidHitWindow300(), getMaxHitWindow300());
                                      getMinHitWindow300(), getMidHitWindow300(), getMaxHitWindow300());
     }
     }
     static float getRawConstantOverallDifficultyForSpeedMultiplier(
     static float getRawConstantOverallDifficultyForSpeedMultiplier(
@@ -285,7 +274,7 @@ class GameRules {
         Beatmap *beatmap,
         Beatmap *beatmap,
         long spinnerDuration)  // spinner length compensated rotations // respect all mods and overrides
         long spinnerDuration)  // spinner length compensated rotations // respect all mods and overrides
     {
     {
-        return getSpinnerRotationsForSpeedMultiplier(beatmap, spinnerDuration, beatmap->getOsu()->getSpeedMultiplier());
+        return getSpinnerRotationsForSpeedMultiplier(beatmap, spinnerDuration, osu->getSpeedMultiplier());
     }
     }
 
 
     static LiveScore::HIT getHitResult(long delta, Beatmap *beatmap) {
     static LiveScore::HIT getHitResult(long delta, Beatmap *beatmap) {
@@ -352,12 +341,12 @@ class GameRules {
                                  : 1.0f));  // gives the circle diameter in osu!pixels, goes negative above CS 12.1429
                                  : 1.0f));  // gives the circle diameter in osu!pixels, goes negative above CS 12.1429
     }
     }
 
 
-    static float getHitCircleXMultiplier(Osu *osu) {
-        return getPlayfieldSize(osu).x / OSU_COORD_WIDTH;  // scales osu!pixels to the actual playfield size
+    static float getHitCircleXMultiplier() {
+        return getPlayfieldSize().x / OSU_COORD_WIDTH;  // scales osu!pixels to the actual playfield size
     }
     }
 
 
     static float getHitCircleDiameter(Beatmap *beatmap) {
     static float getHitCircleDiameter(Beatmap *beatmap) {
-        return getRawHitCircleDiameter(beatmap->getCS()) * getHitCircleXMultiplier(beatmap->getOsu());
+        return getRawHitCircleDiameter(beatmap->getCS()) * getHitCircleXMultiplier();
     }
     }
 
 
     //*************//
     //*************//
@@ -370,7 +359,7 @@ class GameRules {
     static const int OSU_COORD_WIDTH = 512;
     static const int OSU_COORD_WIDTH = 512;
     static const int OSU_COORD_HEIGHT = 384;
     static const int OSU_COORD_HEIGHT = 384;
 
 
-    static float getPlayfieldScaleFactor(Osu *osu) {
+    static float getPlayfieldScaleFactor() {
         const int engineScreenWidth = osu->getScreenWidth();
         const int engineScreenWidth = osu->getScreenWidth();
         const int topBorderSize = osu_playfield_border_top_percent.getFloat() * osu->getScreenHeight();
         const int topBorderSize = osu_playfield_border_top_percent.getFloat() * osu->getScreenHeight();
         const int bottomBorderSize = osu_playfield_border_bottom_percent.getFloat() * osu->getScreenHeight();
         const int bottomBorderSize = osu_playfield_border_bottom_percent.getFloat() * osu->getScreenHeight();
@@ -381,14 +370,14 @@ class GameRules {
                    : engineScreenWidth / (float)OSU_COORD_WIDTH;
                    : engineScreenWidth / (float)OSU_COORD_WIDTH;
     }
     }
 
 
-    static Vector2 getPlayfieldSize(Osu *osu) {
-        const float scaleFactor = getPlayfieldScaleFactor(osu);
+    static Vector2 getPlayfieldSize() {
+        const float scaleFactor = getPlayfieldScaleFactor();
 
 
         return Vector2(OSU_COORD_WIDTH * scaleFactor, OSU_COORD_HEIGHT * scaleFactor);
         return Vector2(OSU_COORD_WIDTH * scaleFactor, OSU_COORD_HEIGHT * scaleFactor);
     }
     }
 
 
-    static Vector2 getPlayfieldOffset(Osu *osu) {
-        const Vector2 playfieldSize = getPlayfieldSize(osu);
+    static Vector2 getPlayfieldOffset() {
+        const Vector2 playfieldSize = getPlayfieldSize();
         const int bottomBorderSize = osu_playfield_border_bottom_percent.getFloat() * osu->getScreenHeight();
         const int bottomBorderSize = osu_playfield_border_bottom_percent.getFloat() * osu->getScreenHeight();
         int playfieldYOffset = (osu->getScreenHeight() / 2.0f - (playfieldSize.y / 2.0f)) - bottomBorderSize;
         int playfieldYOffset = (osu->getScreenHeight() / 2.0f - (playfieldSize.y / 2.0f)) - bottomBorderSize;
 
 
@@ -400,13 +389,11 @@ class GameRules {
                        (osu->getScreenHeight() - playfieldSize.y) / 2.0f + playfieldYOffset);
                        (osu->getScreenHeight() - playfieldSize.y) / 2.0f + playfieldYOffset);
     }
     }
 
 
-    static Vector2 getPlayfieldCenter(Osu *osu) {
-        const float scaleFactor = getPlayfieldScaleFactor(osu);
-        const Vector2 playfieldOffset = getPlayfieldOffset(osu);
+    static Vector2 getPlayfieldCenter() {
+        const float scaleFactor = getPlayfieldScaleFactor();
+        const Vector2 playfieldOffset = getPlayfieldOffset();
 
 
         return Vector2((OSU_COORD_WIDTH / 2) * scaleFactor + playfieldOffset.x,
         return Vector2((OSU_COORD_WIDTH / 2) * scaleFactor + playfieldOffset.x,
                        (OSU_COORD_HEIGHT / 2) * scaleFactor + playfieldOffset.y);
                        (OSU_COORD_HEIGHT / 2) * scaleFactor + playfieldOffset.y);
     }
     }
 };
 };
-
-#endif

File diff suppressed because it is too large
+ 222 - 211
src/App/Osu/HUD.cpp


+ 2 - 14
src/App/Osu/HUD.h

@@ -1,16 +1,6 @@
-//================ Copyright (c) 2016, PG, All rights reserved. =================//
-//
-// Purpose:		hud element drawing functions (accuracy, combo, score, etc.)
-//
-// $NoKeywords: $osuhud
-//===============================================================================//
-
-#ifndef OSUHUD_H
-#define OSUHUD_H
-
+#pragma once
 #include "OsuScreen.h"
 #include "OsuScreen.h"
 
 
-class Osu;
 class UIAvatar;
 class UIAvatar;
 class Beatmap;
 class Beatmap;
 struct ScoreboardSlot;
 struct ScoreboardSlot;
@@ -37,7 +27,7 @@ struct SCORE_ENTRY {
 
 
 class HUD : public OsuScreen {
 class HUD : public OsuScreen {
    public:
    public:
-    HUD(Osu *osu);
+    HUD();
     virtual ~HUD();
     virtual ~HUD();
 
 
     virtual void draw(Graphics *g);
     virtual void draw(Graphics *g);
@@ -228,5 +218,3 @@ class HUD : public OsuScreen {
     float m_fScoreBarBreakAnim;
     float m_fScoreBarBreakAnim;
     float m_fKiScaleAnim;
     float m_fKiScaleAnim;
 };
 };
-
-#endif

+ 10 - 12
src/App/Osu/HitObject.cpp

@@ -350,8 +350,8 @@ void HitObject::drawHitResultAnim(Graphics *g, const HITRESULTANIM &hitresultani
     if((hitresultanim.time - osu_hitresult_duration.getFloat()) <
     if((hitresultanim.time - osu_hitresult_duration.getFloat()) <
            engine->getTime()  // NOTE: this is written like that on purpose, don't change it ("future" results can be
            engine->getTime()  // NOTE: this is written like that on purpose, don't change it ("future" results can be
                               // scheduled with it, e.g. for slider end)
                               // scheduled with it, e.g. for slider end)
-       && (hitresultanim.time + osu_hitresult_duration_max.getFloat() *
-                                    (1.0f / m_beatmap->getOsu()->getAnimationSpeedMultiplier())) > engine->getTime()) {
+       && (hitresultanim.time + osu_hitresult_duration_max.getFloat() * (1.0f / osu->getAnimationSpeedMultiplier())) >
+              engine->getTime()) {
         Skin *skin = m_beatmap->getSkin();
         Skin *skin = m_beatmap->getSkin();
         {
         {
             const long skinAnimationTimeStartOffset =
             const long skinAnimationTimeStartOffset =
@@ -374,9 +374,8 @@ void HitObject::drawHitResultAnim(Graphics *g, const HITRESULTANIM &hitresultani
             skin->getHit300k()->setAnimationFrameClampUp();
             skin->getHit300k()->setAnimationFrameClampUp();
 
 
             const float animPercentInv =
             const float animPercentInv =
-                1.0f -
-                (((engine->getTime() - hitresultanim.time) * m_beatmap->getOsu()->getAnimationSpeedMultiplier()) /
-                 osu_hitresult_duration.getFloat());
+                1.0f - (((engine->getTime() - hitresultanim.time) * osu->getAnimationSpeedMultiplier()) /
+                        osu_hitresult_duration.getFloat());
 
 
             drawHitResult(g, m_beatmap, m_beatmap->osuCoords2Pixels(hitresultanim.rawPos), hitresultanim.result,
             drawHitResult(g, m_beatmap, m_beatmap->osuCoords2Pixels(hitresultanim.rawPos), hitresultanim.result,
                           animPercentInv,
                           animPercentInv,
@@ -389,8 +388,7 @@ void HitObject::update(long curPos) {
     m_fAlphaForApproachCircle = 0.0f;
     m_fAlphaForApproachCircle = 0.0f;
     m_fHittableDimRGBColorMultiplierPercent = 1.0f;
     m_fHittableDimRGBColorMultiplierPercent = 1.0f;
 
 
-    double animationSpeedMultipler =
-        m_beatmap->getOsu()->getSpeedMultiplier() / m_beatmap->getOsu()->getAnimationSpeedMultiplier();
+    double animationSpeedMultipler = osu->getSpeedMultiplier() / osu->getAnimationSpeedMultiplier();
     m_iApproachTime = (m_bUseFadeInTimeAsApproachTime ? (GameRules::getFadeInTime() * animationSpeedMultipler)
     m_iApproachTime = (m_bUseFadeInTimeAsApproachTime ? (GameRules::getFadeInTime() * animationSpeedMultipler)
                                                       : (long)GameRules::getApproachTime(m_beatmap));
                                                       : (long)GameRules::getApproachTime(m_beatmap));
     m_iFadeInTime = GameRules::getFadeInTime() * animationSpeedMultipler;
     m_iFadeInTime = GameRules::getFadeInTime() * animationSpeedMultipler;
@@ -466,7 +464,7 @@ void HitObject::update(long curPos) {
         m_fAlpha = clamp<float>(1.0f - ((float)(fadeInEnd - curPos) / (float)(fadeInEnd - fadeInStart)), 0.0f, 1.0f);
         m_fAlpha = clamp<float>(1.0f - ((float)(fadeInEnd - curPos) / (float)(fadeInEnd - fadeInStart)), 0.0f, 1.0f);
         m_fAlphaWithoutHidden = m_fAlpha;
         m_fAlphaWithoutHidden = m_fAlpha;
 
 
-        if(m_beatmap->getOsu()->getModHD()) {
+        if(osu->getModHD()) {
             // hidden hitobject body fadein
             // hidden hitobject body fadein
             const float fin_start_percent = osu_mod_hd_circle_fadein_start_percent.getFloat();
             const float fin_start_percent = osu_mod_hd_circle_fadein_start_percent.getFloat();
             const float fin_end_percent = osu_mod_hd_circle_fadein_end_percent.getFloat();
             const float fin_end_percent = osu_mod_hd_circle_fadein_end_percent.getFloat();
@@ -521,7 +519,7 @@ void HitObject::update(long curPos) {
 void HitObject::addHitResult(LiveScore::HIT result, long delta, bool isEndOfCombo, Vector2 posRaw, float targetDelta,
 void HitObject::addHitResult(LiveScore::HIT result, long delta, bool isEndOfCombo, Vector2 posRaw, float targetDelta,
                              float targetAngle, bool ignoreOnHitErrorBar, bool ignoreCombo, bool ignoreHealth,
                              float targetAngle, bool ignoreOnHitErrorBar, bool ignoreCombo, bool ignoreHealth,
                              bool addObjectDurationToSkinAnimationTimeStartOffset) {
                              bool addObjectDurationToSkinAnimationTimeStartOffset) {
-    if(m_beatmap->getOsu()->getModTarget() && result != LiveScore::HIT::HIT_MISS && targetDelta >= 0.0f) {
+    if(osu->getModTarget() && result != LiveScore::HIT::HIT_MISS && targetDelta >= 0.0f) {
         const float p300 = osu_mod_target_300_percent.getFloat();
         const float p300 = osu_mod_target_300_percent.getFloat();
         const float p100 = osu_mod_target_100_percent.getFloat();
         const float p100 = osu_mod_target_100_percent.getFloat();
         const float p50 = osu_mod_target_50_percent.getFloat();
         const float p50 = osu_mod_target_50_percent.getFloat();
@@ -535,7 +533,7 @@ void HitObject::addHitResult(LiveScore::HIT result, long delta, bool isEndOfComb
         else
         else
             result = LiveScore::HIT::HIT_MISS;
             result = LiveScore::HIT::HIT_MISS;
 
 
-        m_beatmap->getOsu()->getHUD()->addTarget(targetDelta, targetAngle);
+        osu->getHUD()->addTarget(targetDelta, targetAngle);
     }
     }
 
 
     const LiveScore::HIT returnedHit = m_beatmap->addHitResult(this, result, delta, isEndOfCombo, ignoreOnHitErrorBar,
     const LiveScore::HIT returnedHit = m_beatmap->addHitResult(this, result, delta, isEndOfCombo, ignoreOnHitErrorBar,
@@ -551,8 +549,8 @@ void HitObject::addHitResult(LiveScore::HIT result, long delta, bool isEndOfComb
     }
     }
 
 
     // currently a maximum of 2 simultaneous results are supported (for drawing, per hitobject)
     // currently a maximum of 2 simultaneous results are supported (for drawing, per hitobject)
-    if(engine->getTime() > m_hitresultanim1.time + osu_hitresult_duration_max.getFloat() *
-                                                       (1.0f / m_beatmap->getOsu()->getAnimationSpeedMultiplier()))
+    if(engine->getTime() >
+       m_hitresultanim1.time + osu_hitresult_duration_max.getFloat() * (1.0f / osu->getAnimationSpeedMultiplier()))
         m_hitresultanim1 = hitresultanim;
         m_hitresultanim1 = hitresultanim;
     else
     else
         m_hitresultanim2 = hitresultanim;
         m_hitresultanim2 = hitresultanim;

+ 12 - 12
src/App/Osu/Lobby.cpp

@@ -41,7 +41,7 @@ RoomUIElement::RoomUIElement(Lobby* multi, Room* room, float x, float y, float w
     slots_ui->setDrawBackground(false);
     slots_ui->setDrawBackground(false);
     getContainer()->addBaseUIElement(slots_ui);
     getContainer()->addBaseUIElement(slots_ui);
 
 
-    join_btn = new UIButton(multi->m_osu, 10, 65, 120, 30, "", "Join room");
+    join_btn = new UIButton(10, 65, 120, 30, "", "Join room");
     join_btn->setUseDefaultSkin();
     join_btn->setUseDefaultSkin();
     join_btn->setColor(0xff00ff00);
     join_btn->setColor(0xff00ff00);
     join_btn->setClickCallback(fastdelegate::MakeDelegate(this, &RoomUIElement::onRoomJoinButtonClick));
     join_btn->setClickCallback(fastdelegate::MakeDelegate(this, &RoomUIElement::onRoomJoinButtonClick));
@@ -58,24 +58,24 @@ RoomUIElement::RoomUIElement(Lobby* multi, Room* room, float x, float y, float w
 void RoomUIElement::onRoomJoinButtonClick(CBaseUIButton* btn) {
 void RoomUIElement::onRoomJoinButtonClick(CBaseUIButton* btn) {
     if(has_password) {
     if(has_password) {
         m_multi->room_to_join = room_id;
         m_multi->room_to_join = room_id;
-        m_multi->m_osu->m_prompt->prompt("Room password:",
-                                         fastdelegate::MakeDelegate(m_multi, &Lobby::on_room_join_with_password));
+        osu->m_prompt->prompt("Room password:",
+                              fastdelegate::MakeDelegate(m_multi, &Lobby::on_room_join_with_password));
     } else {
     } else {
         m_multi->joinRoom(room_id, "");
         m_multi->joinRoom(room_id, "");
     }
     }
 }
 }
 
 
-Lobby::Lobby(Osu* osu) : OsuScreen(osu) {
+Lobby::Lobby() : OsuScreen() {
     font = engine->getResourceManager()->getFont("FONT_DEFAULT");
     font = engine->getResourceManager()->getFont("FONT_DEFAULT");
 
 
     auto heading = new CBaseUILabel(50, 30, 300, 40, "", "Multiplayer rooms");
     auto heading = new CBaseUILabel(50, 30, 300, 40, "", "Multiplayer rooms");
-    heading->setFont(m_osu->getTitleFont());
+    heading->setFont(osu->getTitleFont());
     heading->setSizeToContent(0, 0);
     heading->setSizeToContent(0, 0);
     heading->setDrawFrame(false);
     heading->setDrawFrame(false);
     heading->setDrawBackground(false);
     heading->setDrawBackground(false);
     addBaseUIElement(heading);
     addBaseUIElement(heading);
 
 
-    m_create_room_btn = new UIButton(osu, 0, 0, 200, 50, "", "Create new room");
+    m_create_room_btn = new UIButton(0, 0, 200, 50, "", "Create new room");
     m_create_room_btn->setUseDefaultSkin();
     m_create_room_btn->setUseDefaultSkin();
     m_create_room_btn->setColor(0xff00ff00);
     m_create_room_btn->setColor(0xff00ff00);
     m_create_room_btn->setClickCallback(fastdelegate::MakeDelegate(this, &Lobby::on_create_room_clicked));
     m_create_room_btn->setClickCallback(fastdelegate::MakeDelegate(this, &Lobby::on_create_room_clicked));
@@ -88,7 +88,7 @@ Lobby::Lobby(Osu* osu) : OsuScreen(osu) {
     m_list->setHorizontalScrolling(false);
     m_list->setHorizontalScrolling(false);
     addBaseUIElement(m_list);
     addBaseUIElement(m_list);
 
 
-    updateLayout(m_osu->getScreenSize());
+    updateLayout(osu->getScreenSize());
 }
 }
 
 
 void Lobby::onKeyDown(KeyboardEvent& key) {
 void Lobby::onKeyDown(KeyboardEvent& key) {
@@ -97,7 +97,7 @@ void Lobby::onKeyDown(KeyboardEvent& key) {
     if(key.getKeyCode() == KEY_ESCAPE) {
     if(key.getKeyCode() == KEY_ESCAPE) {
         key.consume();
         key.consume();
         setVisible(false);
         setVisible(false);
-        m_osu->m_mainMenu->setVisible(true);
+        osu->m_mainMenu->setVisible(true);
         return;
         return;
     }
     }
 
 
@@ -133,7 +133,7 @@ CBaseUIContainer* Lobby::setVisible(bool visible) {
         send_packet(packet);
         send_packet(packet);
 
 
         // LOBBY presence is broken so we send MULTIPLAYER
         // LOBBY presence is broken so we send MULTIPLAYER
-        RichPresence::setBanchoStatus(m_osu, "Looking to play", MULTIPLAYER);
+        RichPresence::setBanchoStatus("Looking to play", MULTIPLAYER);
 
 
         // XXX: Could call refreshBeatmaps() here so we load them if not already done so.
         // XXX: Could call refreshBeatmaps() here so we load them if not already done so.
         //      Would need to edit it a bit to work outside of songBrowser2, + display loading progress.
         //      Would need to edit it a bit to work outside of songBrowser2, + display loading progress.
@@ -154,7 +154,7 @@ CBaseUIContainer* Lobby::setVisible(bool visible) {
         rooms.clear();
         rooms.clear();
     }
     }
 
 
-    m_osu->m_chat->updateVisibility();
+    osu->m_chat->updateVisibility();
     return this;
     return this;
 }
 }
 
 
@@ -210,7 +210,7 @@ void Lobby::joinRoom(u32 id, UString password) {
         break;
         break;
     }
     }
 
 
-    m_osu->getNotificationOverlay()->addNotification("Joining room...");
+    osu->getNotificationOverlay()->addNotification("Joining room...");
 }
 }
 
 
 void Lobby::updateRoom(Room room) {
 void Lobby::updateRoom(Room room) {
@@ -257,7 +257,7 @@ void Lobby::on_create_room_clicked() {
     bancho.room.pack(&packet);
     bancho.room.pack(&packet);
     send_packet(packet);
     send_packet(packet);
 
 
-    m_osu->getNotificationOverlay()->addNotification("Creating room...");
+    osu->getNotificationOverlay()->addNotification("Creating room...");
 }
 }
 
 
 void Lobby::on_room_join_with_password(UString password) { joinRoom(room_to_join, password); }
 void Lobby::on_room_join_with_password(UString password) { joinRoom(room_to_join, password); }

+ 1 - 1
src/App/Osu/Lobby.h

@@ -31,7 +31,7 @@ struct RoomUIElement : CBaseUIScrollView {
 
 
 class Lobby : public OsuScreen {
 class Lobby : public OsuScreen {
    public:
    public:
-    Lobby(Osu* osu);
+    Lobby();
 
 
     virtual void onKeyDown(KeyboardEvent& e);
     virtual void onKeyDown(KeyboardEvent& e);
     virtual void onKeyUp(KeyboardEvent& e);
     virtual void onKeyUp(KeyboardEvent& e);

+ 74 - 73
src/App/Osu/MainMenu.cpp

@@ -152,7 +152,7 @@ ConVar *MainMenu::m_osu_universal_offset_hardcoded_fallback_dsound_ref = NULL;
 ConVar *MainMenu::m_osu_mod_random_ref = NULL;
 ConVar *MainMenu::m_osu_mod_random_ref = NULL;
 ConVar *MainMenu::m_osu_songbrowser_background_fade_in_duration_ref = NULL;
 ConVar *MainMenu::m_osu_songbrowser_background_fade_in_duration_ref = NULL;
 
 
-MainMenu::MainMenu(Osu *osu) : OsuScreen(osu) {
+MainMenu::MainMenu() : OsuScreen() {
     if(m_osu_universal_offset_ref == NULL) m_osu_universal_offset_ref = convar->getConVarByName("osu_universal_offset");
     if(m_osu_universal_offset_ref == NULL) m_osu_universal_offset_ref = convar->getConVarByName("osu_universal_offset");
     if(m_osu_universal_offset_hardcoded_ref == NULL)
     if(m_osu_universal_offset_hardcoded_ref == NULL)
         m_osu_universal_offset_hardcoded_ref = convar->getConVarByName("osu_universal_offset_hardcoded");
         m_osu_universal_offset_hardcoded_ref = convar->getConVarByName("osu_universal_offset_hardcoded");
@@ -235,7 +235,7 @@ MainMenu::MainMenu(Osu *osu) : OsuScreen(osu) {
     m_bDidUserUpdateFromOlderVersion = m_bDrawVersionNotificationArrow;  // (same logic atm)
     m_bDidUserUpdateFromOlderVersion = m_bDrawVersionNotificationArrow;  // (same logic atm)
 
 
     setPos(-1, 0);
     setPos(-1, 0);
-    setSize(m_osu->getScreenWidth(), m_osu->getScreenHeight());
+    setSize(osu->getScreenWidth(), osu->getScreenHeight());
 
 
     m_cube = new MainMenuCubeButton(this, 0, 0, 1, 1, "", "");
     m_cube = new MainMenuCubeButton(this, 0, 0, 1, 1, "", "");
     m_cube->setClickCallback(fastdelegate::MakeDelegate(this, &MainMenu::onCubePressed));
     m_cube->setClickCallback(fastdelegate::MakeDelegate(this, &MainMenu::onCubePressed));
@@ -254,7 +254,7 @@ MainMenu::MainMenu(Osu *osu) : OsuScreen(osu) {
     addBaseUIElement(m_pauseButton);
     addBaseUIElement(m_pauseButton);
 
 
     if(env->getOS() == Environment::OS::OS_WINDOWS) {
     if(env->getOS() == Environment::OS::OS_WINDOWS) {
-        m_updateAvailableButton = new UIButton(m_osu, 0, 0, 0, 0, "", "Checking for updates ...");
+        m_updateAvailableButton = new UIButton(0, 0, 0, 0, "", "Checking for updates ...");
         m_updateAvailableButton->setUseDefaultSkin();
         m_updateAvailableButton->setUseDefaultSkin();
         m_updateAvailableButton->setClickCallback(fastdelegate::MakeDelegate(this, &MainMenu::onUpdatePressed));
         m_updateAvailableButton->setClickCallback(fastdelegate::MakeDelegate(this, &MainMenu::onUpdatePressed));
         m_updateAvailableButton->setColor(0x2200ff00);
         m_updateAvailableButton->setColor(0x2200ff00);
@@ -325,17 +325,17 @@ void MainMenu::draw(Graphics *g) {
 
 
     // menu-background
     // menu-background
     if(osu_draw_menu_background.getBool()) {
     if(osu_draw_menu_background.getBool()) {
-        Image *backgroundImage = m_osu->getSkin()->getMenuBackground();
-        if(backgroundImage != NULL && backgroundImage != m_osu->getSkin()->getMissingTexture() &&
+        Image *backgroundImage = osu->getSkin()->getMenuBackground();
+        if(backgroundImage != NULL && backgroundImage != osu->getSkin()->getMissingTexture() &&
            backgroundImage->isReady()) {
            backgroundImage->isReady()) {
-            const float scale = Osu::getImageScaleToFillResolution(backgroundImage, m_osu->getScreenSize());
+            const float scale = Osu::getImageScaleToFillResolution(backgroundImage, osu->getScreenSize());
 
 
             g->setColor(0xffffffff);
             g->setColor(0xffffffff);
             g->setAlpha(m_fStartupAnim);
             g->setAlpha(m_fStartupAnim);
             g->pushTransform();
             g->pushTransform();
             {
             {
                 g->scale(scale, scale);
                 g->scale(scale, scale);
-                g->translate(m_osu->getScreenWidth() / 2, m_osu->getScreenHeight() / 2);
+                g->translate(osu->getScreenWidth() / 2, osu->getScreenHeight() / 2);
                 g->drawImage(backgroundImage);
                 g->drawImage(backgroundImage);
             }
             }
             g->popTransform();
             g->popTransform();
@@ -346,11 +346,11 @@ void MainMenu::draw(Graphics *g) {
     float alpha = 1.0f;
     float alpha = 1.0f;
     if(m_osu_songbrowser_background_fade_in_duration_ref->getFloat() > 0.0f) {
     if(m_osu_songbrowser_background_fade_in_duration_ref->getFloat() > 0.0f) {
         // handle fadein trigger after handler is finished loading
         // handle fadein trigger after handler is finished loading
-        const bool ready = m_osu->getSelectedBeatmap()->getSelectedDifficulty2() != NULL &&
-                           m_osu->getBackgroundImageHandler()->getLoadBackgroundImage(
-                               m_osu->getSelectedBeatmap()->getSelectedDifficulty2()) != NULL &&
-                           m_osu->getBackgroundImageHandler()
-                               ->getLoadBackgroundImage(m_osu->getSelectedBeatmap()->getSelectedDifficulty2())
+        const bool ready = osu->getSelectedBeatmap()->getSelectedDifficulty2() != NULL &&
+                           osu->getBackgroundImageHandler()->getLoadBackgroundImage(
+                               osu->getSelectedBeatmap()->getSelectedDifficulty2()) != NULL &&
+                           osu->getBackgroundImageHandler()
+                               ->getLoadBackgroundImage(osu->getSelectedBeatmap()->getSelectedDifficulty2())
                                ->isReady();
                                ->isReady();
 
 
         if(!ready)
         if(!ready)
@@ -365,29 +365,29 @@ void MainMenu::draw(Graphics *g) {
 
 
     background_shader->enable();
     background_shader->enable();
     background_shader->setUniform1f("time", engine->getTime());
     background_shader->setUniform1f("time", engine->getTime());
-    background_shader->setUniform2f("resolution", m_osu->getScreenWidth(), m_osu->getScreenHeight());
-    SongBrowser::drawSelectedBeatmapBackgroundImage(g, m_osu, alpha);
+    background_shader->setUniform2f("resolution", osu->getScreenWidth(), osu->getScreenHeight());
+    SongBrowser::drawSelectedBeatmapBackgroundImage(g, alpha);
     background_shader->disable();
     background_shader->disable();
 
 
     // main button stuff
     // main button stuff
     bool haveTimingpoints = false;
     bool haveTimingpoints = false;
     const float div = 1.25f;
     const float div = 1.25f;
     float pulse = 0.0f;
     float pulse = 0.0f;
-    if(m_osu->getSelectedBeatmap()->getSelectedDifficulty2() != NULL &&
-       m_osu->getSelectedBeatmap()->getMusic() != NULL && m_osu->getSelectedBeatmap()->getMusic()->isPlaying()) {
+    if(osu->getSelectedBeatmap()->getSelectedDifficulty2() != NULL && osu->getSelectedBeatmap()->getMusic() != NULL &&
+       osu->getSelectedBeatmap()->getMusic()->isPlaying()) {
         haveTimingpoints = true;
         haveTimingpoints = true;
 
 
-        const long curMusicPos = (long)m_osu->getSelectedBeatmap()->getMusic()->getPositionMS() +
-                                 (long)(m_osu_universal_offset_ref->getFloat() * m_osu->getSpeedMultiplier()) +
+        const long curMusicPos = (long)osu->getSelectedBeatmap()->getMusic()->getPositionMS() +
+                                 (long)(m_osu_universal_offset_ref->getFloat() * osu->getSpeedMultiplier()) +
                                  (long)m_osu_universal_offset_hardcoded_ref->getInt() -
                                  (long)m_osu_universal_offset_hardcoded_ref->getInt() -
-                                 m_osu->getSelectedBeatmap()->getSelectedDifficulty2()->getLocalOffset() -
-                                 m_osu->getSelectedBeatmap()->getSelectedDifficulty2()->getOnlineOffset() -
-                                 (m_osu->getSelectedBeatmap()->getSelectedDifficulty2()->getVersion() < 5
+                                 osu->getSelectedBeatmap()->getSelectedDifficulty2()->getLocalOffset() -
+                                 osu->getSelectedBeatmap()->getSelectedDifficulty2()->getOnlineOffset() -
+                                 (osu->getSelectedBeatmap()->getSelectedDifficulty2()->getVersion() < 5
                                       ? m_osu_old_beatmap_offset_ref->getInt()
                                       ? m_osu_old_beatmap_offset_ref->getInt()
                                       : 0);
                                       : 0);
 
 
         DatabaseBeatmap::TIMING_INFO t =
         DatabaseBeatmap::TIMING_INFO t =
-            m_osu->getSelectedBeatmap()->getSelectedDifficulty2()->getTimingInfoForTime(curMusicPos);
+            osu->getSelectedBeatmap()->getSelectedDifficulty2()->getTimingInfoForTime(curMusicPos);
 
 
         if(t.beatLengthBase == 0.0f)  // bah
         if(t.beatLengthBase == 0.0f)  // bah
             t.beatLengthBase = 1.0f;
             t.beatLengthBase = 1.0f;
@@ -415,22 +415,22 @@ void MainMenu::draw(Graphics *g) {
         float animation = fmod((float)(engine->getTime()) * 3.2f, 2.0f);
         float animation = fmod((float)(engine->getTime()) * 3.2f, 2.0f);
         if(animation > 1.0f) animation = 2.0f - animation;
         if(animation > 1.0f) animation = 2.0f - animation;
         animation = -animation * (animation - 2);  // quad out
         animation = -animation * (animation - 2);  // quad out
-        float offset = m_osu->getUIScale(m_osu, 45.0f * animation);
+        float offset = osu->getUIScale(45.0f * animation);
 
 
-        const float scale = m_versionButton->getSize().x / m_osu->getSkin()->getPlayWarningArrow2()->getSizeBaseRaw().x;
+        const float scale = m_versionButton->getSize().x / osu->getSkin()->getPlayWarningArrow2()->getSizeBaseRaw().x;
 
 
         const Vector2 arrowPos =
         const Vector2 arrowPos =
             Vector2(m_versionButton->getSize().x / 1.75f,
             Vector2(m_versionButton->getSize().x / 1.75f,
-                    m_osu->getScreenHeight() - m_versionButton->getSize().y * 2 - m_versionButton->getSize().y * scale);
+                    osu->getScreenHeight() - m_versionButton->getSize().y * 2 - m_versionButton->getSize().y * scale);
 
 
         UString notificationText = "Changelog";
         UString notificationText = "Changelog";
         g->setColor(0xffffffff);
         g->setColor(0xffffffff);
         g->pushTransform();
         g->pushTransform();
         {
         {
-            McFont *smallFont = m_osu->getSubTitleFont();
+            McFont *smallFont = osu->getSubTitleFont();
             g->translate(arrowPos.x - smallFont->getStringWidth(notificationText) / 2.0f,
             g->translate(arrowPos.x - smallFont->getStringWidth(notificationText) / 2.0f,
                          (-offset * 2) * scale + arrowPos.y -
                          (-offset * 2) * scale + arrowPos.y -
-                             (m_osu->getSkin()->getPlayWarningArrow2()->getSizeBaseRaw().y * scale) / 1.5f,
+                             (osu->getSkin()->getPlayWarningArrow2()->getSizeBaseRaw().y * scale) / 1.5f,
                          0);
                          0);
             g->drawString(smallFont, notificationText);
             g->drawString(smallFont, notificationText);
         }
         }
@@ -441,7 +441,7 @@ void MainMenu::draw(Graphics *g) {
         {
         {
             g->rotate(90.0f);
             g->rotate(90.0f);
             g->translate(0, -offset * 2, 0);
             g->translate(0, -offset * 2, 0);
-            m_osu->getSkin()->getPlayWarningArrow2()->drawRaw(g, arrowPos, scale);
+            osu->getSkin()->getPlayWarningArrow2()->drawRaw(g, arrowPos, scale);
         }
         }
         g->popTransform();
         g->popTransform();
     }
     }
@@ -451,14 +451,13 @@ void MainMenu::draw(Graphics *g) {
 
 
     // draw update check button
     // draw update check button
     if(m_updateAvailableButton != nullptr) {
     if(m_updateAvailableButton != nullptr) {
-        if(m_osu->getUpdateHandler()->getStatus() == UpdateHandler::STATUS::STATUS_SUCCESS_INSTALLATION) {
+        if(osu->getUpdateHandler()->getStatus() == UpdateHandler::STATUS::STATUS_SUCCESS_INSTALLATION) {
             g->push3DScene(McRect(m_updateAvailableButton->getPos().x, m_updateAvailableButton->getPos().y,
             g->push3DScene(McRect(m_updateAvailableButton->getPos().x, m_updateAvailableButton->getPos().y,
                                   m_updateAvailableButton->getSize().x, m_updateAvailableButton->getSize().y));
                                   m_updateAvailableButton->getSize().x, m_updateAvailableButton->getSize().y));
             g->rotate3DScene(m_fUpdateButtonAnim * 360.0f, 0, 0);
             g->rotate3DScene(m_fUpdateButtonAnim * 360.0f, 0, 0);
         }
         }
         m_updateAvailableButton->draw(g);
         m_updateAvailableButton->draw(g);
-        if(m_osu->getUpdateHandler()->getStatus() == UpdateHandler::STATUS::STATUS_SUCCESS_INSTALLATION)
-            g->pop3DScene();
+        if(osu->getUpdateHandler()->getStatus() == UpdateHandler::STATUS::STATUS_SUCCESS_INSTALLATION) g->pop3DScene();
     }
     }
 
 
     // draw main button
     // draw main button
@@ -961,7 +960,7 @@ void MainMenu::mouse_update(bool *propagate_clicks) {
 
 
     // handle update checker and status text
     // handle update checker and status text
     if(m_updateAvailableButton != nullptr) {
     if(m_updateAvailableButton != nullptr) {
-        switch(m_osu->getUpdateHandler()->getStatus()) {
+        switch(osu->getUpdateHandler()->getStatus()) {
             case UpdateHandler::STATUS::STATUS_UP_TO_DATE:
             case UpdateHandler::STATUS::STATUS_UP_TO_DATE:
                 if(m_updateAvailableButton->isVisible()) {
                 if(m_updateAvailableButton->isVisible()) {
                     m_updateAvailableButton->setText("");
                     m_updateAvailableButton->setText("");
@@ -997,7 +996,7 @@ void MainMenu::mouse_update(bool *propagate_clicks) {
         }
         }
     }
     }
 
 
-    if(m_osu->getUpdateHandler()->getStatus() == UpdateHandler::STATUS::STATUS_SUCCESS_INSTALLATION &&
+    if(osu->getUpdateHandler()->getStatus() == UpdateHandler::STATUS::STATUS_SUCCESS_INSTALLATION &&
        engine->getTime() > m_fUpdateButtonAnimTime) {
        engine->getTime() > m_fUpdateButtonAnimTime) {
         m_fUpdateButtonAnimTime = engine->getTime() + 3.0f;
         m_fUpdateButtonAnimTime = engine->getTime() + 3.0f;
         m_fUpdateButtonAnim = 0.0f;
         m_fUpdateButtonAnim = 0.0f;
@@ -1006,7 +1005,7 @@ void MainMenu::mouse_update(bool *propagate_clicks) {
 
 
     // Update pause button and shuffle songs
     // Update pause button and shuffle songs
     m_pauseButton->setPaused(true);
     m_pauseButton->setPaused(true);
-    auto music = m_osu->getSelectedBeatmap()->getMusic();
+    auto music = osu->getSelectedBeatmap()->getMusic();
     if(music == nullptr) {
     if(music == nullptr) {
         selectRandomBeatmap();
         selectRandomBeatmap();
     } else {
     } else {
@@ -1022,18 +1021,18 @@ void MainMenu::mouse_update(bool *propagate_clicks) {
 }
 }
 
 
 void MainMenu::selectRandomBeatmap() {
 void MainMenu::selectRandomBeatmap() {
-    auto sb = m_osu->getSongBrowser();
+    auto sb = osu->getSongBrowser();
     if(sb->getDatabase()->isFinished() && !sb->m_beatmaps.empty()) {
     if(sb->getDatabase()->isFinished() && !sb->m_beatmaps.empty()) {
-        m_osu->getSongBrowser()->selectRandomBeatmap();
+        osu->getSongBrowser()->selectRandomBeatmap();
     } else {
     } else {
         // Database is not loaded yet, load a random map and select it
         // Database is not loaded yet, load a random map and select it
         // XXX: Also pick from neosu maps/ directory
         // XXX: Also pick from neosu maps/ directory
-        auto songs_folder = m_osu->getSongBrowser()->getDatabase()->getOsuSongsFolder();
+        auto songs_folder = osu->getSongBrowser()->getDatabase()->getOsuSongsFolder();
         auto mapset_folders = env->getFoldersInFolder(songs_folder);
         auto mapset_folders = env->getFoldersInFolder(songs_folder);
         auto nb_mapsets = mapset_folders.size();
         auto nb_mapsets = mapset_folders.size();
         if(nb_mapsets == 0) return;
         if(nb_mapsets == 0) return;
 
 
-        m_osu->getSongBrowser()->getSelectedBeatmap()->deselect();
+        osu->getSongBrowser()->getSelectedBeatmap()->deselect();
         SAFE_DELETE(preloaded_beatmapset);
         SAFE_DELETE(preloaded_beatmapset);
 
 
         for(int i = 0; i < 10; i++) {
         for(int i = 0; i < 10; i++) {
@@ -1041,7 +1040,7 @@ void MainMenu::selectRandomBeatmap() {
             mapset_folder.append(mapset_folders[rand() % nb_mapsets]);
             mapset_folder.append(mapset_folders[rand() % nb_mapsets]);
             mapset_folder.append("/");
             mapset_folder.append("/");
 
 
-            BeatmapSet *set = m_osu->getSongBrowser()->getDatabase()->loadRawBeatmap(mapset_folder);
+            BeatmapSet *set = osu->getSongBrowser()->getDatabase()->loadRawBeatmap(mapset_folder);
             if(set == nullptr) {
             if(set == nullptr) {
                 debugLog("Failed to load beatmap set '%s'\n", mapset_folder.c_str());
                 debugLog("Failed to load beatmap set '%s'\n", mapset_folder.c_str());
                 continue;
                 continue;
@@ -1061,7 +1060,7 @@ void MainMenu::selectRandomBeatmap() {
             preloaded_beatmap = beatmap_diffs[rand() % beatmap_diffs.size()];
             preloaded_beatmap = beatmap_diffs[rand() % beatmap_diffs.size()];
             preloaded_beatmap->do_not_store = true;
             preloaded_beatmap->do_not_store = true;
 
 
-            m_osu->getSongBrowser()->onDifficultySelected(preloaded_beatmap, false);
+            osu->getSongBrowser()->onDifficultySelected(preloaded_beatmap, false);
 
 
             return;
             return;
         }
         }
@@ -1074,7 +1073,7 @@ void MainMenu::onKeyDown(KeyboardEvent &e) {
     OsuScreen::onKeyDown(e);  // only used for options menu
     OsuScreen::onKeyDown(e);  // only used for options menu
     if(!m_bVisible || e.isConsumed()) return;
     if(!m_bVisible || e.isConsumed()) return;
 
 
-    if(!m_osu->getOptionsMenu()->isMouseInside()) {
+    if(!osu->getOptionsMenu()->isMouseInside()) {
         if(e == KEY_RIGHT || e == KEY_F2) selectRandomBeatmap();
         if(e == KEY_RIGHT || e == KEY_F2) selectRandomBeatmap();
     }
     }
 
 
@@ -1117,7 +1116,18 @@ CBaseUIContainer *MainMenu::setVisible(bool visible) {
     m_bVisible = visible;
     m_bVisible = visible;
 
 
     if(visible) {
     if(visible) {
-        RichPresence::onMainMenu(m_osu);
+        RichPresence::onMainMenu();
+
+        if(!bancho.spectators.empty()) {
+            Packet packet;
+            packet.id = SPECTATE_FRAMES;
+            write<i32>(&packet, 0);
+            write<u16>(&packet, 0);
+            write<u8>(&packet, LiveReplayBundle::Action::NONE);
+            write<ScoreFrame>(&packet, ScoreFrame::get());
+            write<u16>(&packet, osu->getSelectedBeatmap()->spectator_sequence++);
+            send_packet(packet);
+        }
 
 
         updateLayout();
         updateLayout();
 
 
@@ -1139,29 +1149,28 @@ CBaseUIContainer *MainMenu::setVisible(bool visible) {
 }
 }
 
 
 void MainMenu::updateLayout() {
 void MainMenu::updateLayout() {
-    const float dpiScale = Osu::getUIScale(m_osu);
+    const float dpiScale = Osu::getUIScale();
 
 
-    m_vCenter = m_osu->getScreenSize() / 2.0f;
-    const float size = Osu::getUIScale(m_osu, 324.0f);
+    m_vCenter = osu->getScreenSize() / 2.0f;
+    const float size = Osu::getUIScale(324.0f);
     m_vSize = Vector2(size, size);
     m_vSize = Vector2(size, size);
 
 
     m_cube->setRelPos(m_vCenter - m_vSize / 2.0f - Vector2(m_fCenterOffsetAnim, 0.0f));
     m_cube->setRelPos(m_vCenter - m_vSize / 2.0f - Vector2(m_fCenterOffsetAnim, 0.0f));
     m_cube->setSize(m_vSize);
     m_cube->setSize(m_vSize);
 
 
     m_pauseButton->setSize(30 * dpiScale, 30 * dpiScale);
     m_pauseButton->setSize(30 * dpiScale, 30 * dpiScale);
-    m_pauseButton->setRelPos(m_osu->getScreenWidth() - m_pauseButton->getSize().x * 2 - 10 * dpiScale,
+    m_pauseButton->setRelPos(osu->getScreenWidth() - m_pauseButton->getSize().x * 2 - 10 * dpiScale,
                              m_pauseButton->getSize().y + 10 * dpiScale);
                              m_pauseButton->getSize().y + 10 * dpiScale);
 
 
     if(m_updateAvailableButton != nullptr) {
     if(m_updateAvailableButton != nullptr) {
         m_updateAvailableButton->setSize(375 * dpiScale, 50 * dpiScale);
         m_updateAvailableButton->setSize(375 * dpiScale, 50 * dpiScale);
-        m_updateAvailableButton->setPos(
-            m_osu->getScreenWidth() / 2 - m_updateAvailableButton->getSize().x / 2,
-            m_osu->getScreenHeight() - m_updateAvailableButton->getSize().y - 10 * dpiScale);
+        m_updateAvailableButton->setPos(osu->getScreenWidth() / 2 - m_updateAvailableButton->getSize().x / 2,
+                                        osu->getScreenHeight() - m_updateAvailableButton->getSize().y - 10 * dpiScale);
     }
     }
 
 
     m_versionButton->onResized();  // HACKHACK: framework, setSizeToContent() does not update string metrics
     m_versionButton->onResized();  // HACKHACK: framework, setSizeToContent() does not update string metrics
     m_versionButton->setSizeToContent(8 * dpiScale, 8 * dpiScale);
     m_versionButton->setSizeToContent(8 * dpiScale, 8 * dpiScale);
-    m_versionButton->setRelPos(-1, m_osu->getScreenSize().y - m_versionButton->getSize().y);
+    m_versionButton->setRelPos(-1, osu->getScreenSize().y - m_versionButton->getSize().y);
 
 
     int numButtons = m_menuElements.size();
     int numButtons = m_menuElements.size();
     int menuElementHeight = m_vSize.y / numButtons;
     int menuElementHeight = m_vSize.y / numButtons;
@@ -1189,7 +1198,7 @@ void MainMenu::updateLayout() {
         m_menuElements[i]->setBackgroundColor(COLORf(offsetPercent * osu_main_menu_alpha.getFloat(), 0.0f, 0.0f, 0.0f));
         m_menuElements[i]->setBackgroundColor(COLORf(offsetPercent * osu_main_menu_alpha.getFloat(), 0.0f, 0.0f, 0.0f));
     }
     }
 
 
-    setSize(m_osu->getScreenSize() + Vector2(1, 1));
+    setSize(osu->getScreenSize() + Vector2(1, 1));
     update_pos();
     update_pos();
 }
 }
 
 
@@ -1296,7 +1305,7 @@ void MainMenu::writeVersionFile() {
 
 
 MainMenuButton *MainMenu::addMainMenuButton(UString text) {
 MainMenuButton *MainMenu::addMainMenuButton(UString text) {
     MainMenuButton *button = new MainMenuButton(this, m_vSize.x, 0, 1, 1, "", text);
     MainMenuButton *button = new MainMenuButton(this, m_vSize.x, 0, 1, 1, "", text);
-    button->setFont(m_osu->getSubTitleFont());
+    button->setFont(osu->getSubTitleFont());
     button->setVisible(false);
     button->setVisible(false);
 
 
     m_menuElements.push_back(button);
     m_menuElements.push_back(button);
@@ -1305,7 +1314,7 @@ MainMenuButton *MainMenu::addMainMenuButton(UString text) {
 }
 }
 
 
 void MainMenu::onCubePressed() {
 void MainMenu::onCubePressed() {
-    engine->getSound()->play(m_osu->getSkin()->getMenuHit());
+    engine->getSound()->play(osu->getSkin()->getMenuHit());
 
 
     anim->moveQuadInOut(&m_fSizeAddAnim, 0.0f, 0.06f, 0.0f, false);
     anim->moveQuadInOut(&m_fSizeAddAnim, 0.0f, 0.06f, 0.0f, false);
     anim->moveQuadInOut(&m_fSizeAddAnim, 0.12f, 0.06f, 0.07f, false);
     anim->moveQuadInOut(&m_fSizeAddAnim, 0.12f, 0.06f, 0.07f, false);
@@ -1353,23 +1362,21 @@ void MainMenu::onPlayButtonPressed() {
     m_bMainMenuAnimFadeToFriendForNextAnim = false;
     m_bMainMenuAnimFadeToFriendForNextAnim = false;
     m_bMainMenuAnimFriendScheduled = false;
     m_bMainMenuAnimFriendScheduled = false;
 
 
-    if(m_osu->getInstanceID() > 1) return;
-
-    m_osu->toggleSongBrowser();
+    osu->toggleSongBrowser();
 }
 }
 
 
 void MainMenu::onMultiplayerButtonPressed() {
 void MainMenu::onMultiplayerButtonPressed() {
     if(bancho.user_id <= 0) {
     if(bancho.user_id <= 0) {
-        m_osu->m_optionsMenu->askForLoginDetails();
+        osu->m_optionsMenu->askForLoginDetails();
         return;
         return;
     }
     }
 
 
     setVisible(false);
     setVisible(false);
-    m_osu->m_lobby->setVisible(true);
+    osu->m_lobby->setVisible(true);
 }
 }
 
 
 void MainMenu::onOptionsButtonPressed() {
 void MainMenu::onOptionsButtonPressed() {
-    if(!m_osu->getOptionsMenu()->isVisible()) m_osu->toggleOptionsMenu();
+    if(!osu->getOptionsMenu()->isVisible()) osu->toggleOptionsMenu();
 }
 }
 
 
 void MainMenu::onExitButtonPressed() {
 void MainMenu::onExitButtonPressed() {
@@ -1379,12 +1386,10 @@ void MainMenu::onExitButtonPressed() {
 }
 }
 
 
 void MainMenu::onPausePressed() {
 void MainMenu::onPausePressed() {
-    if(m_osu->getInstanceID() > 1) return;
-
-    if(m_osu->getSelectedBeatmap()->isPreviewMusicPlaying()) {
-        m_osu->getSelectedBeatmap()->pausePreviewMusic();
+    if(osu->getSelectedBeatmap()->isPreviewMusicPlaying()) {
+        osu->getSelectedBeatmap()->pausePreviewMusic();
     } else {
     } else {
-        auto music = m_osu->getSelectedBeatmap()->getMusic();
+        auto music = osu->getSelectedBeatmap()->getMusic();
         if(music != nullptr) {
         if(music != nullptr) {
             engine->getSound()->play(music);
             engine->getSound()->play(music);
         }
         }
@@ -1392,20 +1397,16 @@ void MainMenu::onPausePressed() {
 }
 }
 
 
 void MainMenu::onUpdatePressed() {
 void MainMenu::onUpdatePressed() {
-    if(m_osu->getInstanceID() > 1) return;
-
-    if(m_osu->getUpdateHandler()->getStatus() == UpdateHandler::STATUS::STATUS_SUCCESS_INSTALLATION)
+    if(osu->getUpdateHandler()->getStatus() == UpdateHandler::STATUS::STATUS_SUCCESS_INSTALLATION)
         engine->restart();
         engine->restart();
-    else if(m_osu->getUpdateHandler()->getStatus() == UpdateHandler::STATUS::STATUS_ERROR)
-        m_osu->getUpdateHandler()->checkForUpdates();
+    else if(osu->getUpdateHandler()->getStatus() == UpdateHandler::STATUS::STATUS_ERROR)
+        osu->getUpdateHandler()->checkForUpdates();
 }
 }
 
 
 void MainMenu::onVersionPressed() {
 void MainMenu::onVersionPressed() {
-    if(m_osu->getInstanceID() > 1) return;
-
     m_bDrawVersionNotificationArrow = false;
     m_bDrawVersionNotificationArrow = false;
     writeVersionFile();
     writeVersionFile();
-    m_osu->toggleChangelog();
+    osu->toggleChangelog();
 }
 }
 
 
 MainMenuCubeButton::MainMenuCubeButton(MainMenu *mainMenu, float xPos, float yPos, float xSize, float ySize,
 MainMenuCubeButton::MainMenuCubeButton(MainMenu *mainMenu, float xPos, float yPos, float xSize, float ySize,
@@ -1440,6 +1441,6 @@ MainMenuButton::MainMenuButton(MainMenu *mainMenu, float xPos, float yPos, float
 void MainMenuButton::onMouseDownInside() {
 void MainMenuButton::onMouseDownInside() {
     if(m_mainMenu->m_cube->isMouseInside()) return;
     if(m_mainMenu->m_cube->isMouseInside()) return;
 
 
-    engine->getSound()->play(m_mainMenu->getOsu()->getSkin()->getMenuHit());
+    engine->getSound()->play(osu->getSkin()->getMenuHit());
     CBaseUIButton::onMouseDownInside();
     CBaseUIButton::onMouseDownInside();
 }
 }

+ 2 - 16
src/App/Osu/MainMenu.h

@@ -1,19 +1,9 @@
-//================ Copyright (c) 2015, PG, All rights reserved. =================//
-//
-// Purpose:		main menu
-//
-// $NoKeywords: $osumain
-//===============================================================================//
-
-#ifndef OSUMENUMAIN_H
-#define OSUMENUMAIN_H
-
+#pragma once
 #include "CBaseUIButton.h"
 #include "CBaseUIButton.h"
 #include "MouseListener.h"
 #include "MouseListener.h"
 #include "OsuScreen.h"
 #include "OsuScreen.h"
 
 
 class Image;
 class Image;
-class Osu;
 
 
 class Beatmap;
 class Beatmap;
 class DatabaseBeatmap;
 class DatabaseBeatmap;
@@ -54,7 +44,7 @@ class MainMenu : public OsuScreen, public MouseListener {
     void onPausePressed();
     void onPausePressed();
     void onCubePressed();
     void onCubePressed();
 
 
-    MainMenu(Osu *osu);
+    MainMenu();
     virtual ~MainMenu();
     virtual ~MainMenu();
 
 
     virtual void draw(Graphics *g);
     virtual void draw(Graphics *g);
@@ -82,8 +72,6 @@ class MainMenu : public OsuScreen, public MouseListener {
         m_fStartupAnim = m_fStartupAnim2 = (m_bStartupAnim ? 0.0f : 1.0f);
         m_fStartupAnim = m_fStartupAnim2 = (m_bStartupAnim ? 0.0f : 1.0f);
     }
     }
 
 
-    inline Osu *getOsu() const { return m_osu; }
-
    private:
    private:
     static ConVar *m_osu_universal_offset_ref;
     static ConVar *m_osu_universal_offset_ref;
     static ConVar *m_osu_universal_offset_hardcoded_ref;
     static ConVar *m_osu_universal_offset_hardcoded_ref;
@@ -172,5 +160,3 @@ class MainMenu : public OsuScreen, public MouseListener {
     Image *logo_img;
     Image *logo_img;
     Shader *background_shader = nullptr;
     Shader *background_shader = nullptr;
 };
 };
-
-#endif

+ 22 - 32
src/App/Osu/ModFPoSu.cpp

@@ -1,10 +1,3 @@
-//================ Copyright (c) 2019, Colin Brook & PG, All rights reserved. =================//
-//
-// Purpose:		real 3d first person mode for fps warmup/practice
-//
-// $NoKeywords: $fposu
-//=============================================================================================//
-
 #include "ModFPoSu.h"
 #include "ModFPoSu.h"
 
 
 #include <sstream>
 #include <sstream>
@@ -83,9 +76,7 @@ ConVar fposu_mod_3d_depthwobble("fposu_mod_3d_depthwobble", false, FCVAR_UNLOCKE
 constexpr const float ModFPoSu::SIZEDIV3D;
 constexpr const float ModFPoSu::SIZEDIV3D;
 constexpr const int ModFPoSu::SUBDIVISIONS;
 constexpr const int ModFPoSu::SUBDIVISIONS;
 
 
-ModFPoSu::ModFPoSu(Osu *osu) {
-    m_osu = osu;
-
+ModFPoSu::ModFPoSu() {
     // convar refs
     // convar refs
     m_mouse_sensitivity_ref = convar->getConVarByName("mouse_sensitivity");
     m_mouse_sensitivity_ref = convar->getConVarByName("mouse_sensitivity");
     m_osu_draw_beatmap_background_image_ref = convar->getConVarByName("osu_draw_beatmap_background_image");
     m_osu_draw_beatmap_background_image_ref = convar->getConVarByName("osu_draw_beatmap_background_image");
@@ -132,9 +123,9 @@ void ModFPoSu::draw(Graphics *g) {
     Matrix4 projectionMatrix =
     Matrix4 projectionMatrix =
         fposu_vertical_fov.getBool()
         fposu_vertical_fov.getBool()
             ? Camera::buildMatrixPerspectiveFovVertical(
             ? Camera::buildMatrixPerspectiveFovVertical(
-                  deg2rad(fov), ((float)m_osu->getScreenWidth() / (float)m_osu->getScreenHeight()), 0.05f, 1000.0f)
+                  deg2rad(fov), ((float)osu->getScreenWidth() / (float)osu->getScreenHeight()), 0.05f, 1000.0f)
             : Camera::buildMatrixPerspectiveFovHorizontal(
             : Camera::buildMatrixPerspectiveFovHorizontal(
-                  deg2rad(fov), ((float)m_osu->getScreenHeight() / (float)m_osu->getScreenWidth()), 0.05f, 1000.0f);
+                  deg2rad(fov), ((float)osu->getScreenHeight() / (float)osu->getScreenWidth()), 0.05f, 1000.0f);
     Matrix4 viewMatrix = Camera::buildMatrixLookAt(
     Matrix4 viewMatrix = Camera::buildMatrixLookAt(
         m_camera->getPos(), m_camera->getPos() + m_camera->getViewDirection(), m_camera->getViewUp());
         m_camera->getPos(), m_camera->getPos() + m_camera->getViewDirection(), m_camera->getViewUp());
 
 
@@ -142,11 +133,11 @@ void ModFPoSu::draw(Graphics *g) {
     // non-2d stuff with correct offsets (i.e. top left) is by rendering into a rendertarget HACKHACK: abusing
     // non-2d stuff with correct offsets (i.e. top left) is by rendering into a rendertarget HACKHACK: abusing
     // sliderFrameBuffer
     // sliderFrameBuffer
 
 
-    m_osu->getSliderFrameBuffer()->enable();
+    osu->getSliderFrameBuffer()->enable();
     {
     {
         const Vector2 resolutionBackup = g->getResolution();
         const Vector2 resolutionBackup = g->getResolution();
         g->onResolutionChange(
         g->onResolutionChange(
-            m_osu->getSliderFrameBuffer()
+            osu->getSliderFrameBuffer()
                 ->getSize());  // set renderer resolution to game resolution (to correctly support letterboxing etc.)
                 ->getSize());  // set renderer resolution to game resolution (to correctly support letterboxing etc.)
         {
         {
             g->clearDepthBuffer();
             g->clearDepthBuffer();
@@ -190,14 +181,14 @@ void ModFPoSu::draw(Graphics *g) {
 
 
                         // cube
                         // cube
                         if(fposu_cube.getBool()) {
                         if(fposu_cube.getBool()) {
-                            m_osu->getSkin()->getBackgroundCube()->bind();
+                            osu->getSkin()->getBackgroundCube()->bind();
                             {
                             {
                                 g->setColor(COLOR(255, clamp<int>(fposu_cube_tint_r.getInt(), 0, 255),
                                 g->setColor(COLOR(255, clamp<int>(fposu_cube_tint_r.getInt(), 0, 255),
                                                   clamp<int>(fposu_cube_tint_g.getInt(), 0, 255),
                                                   clamp<int>(fposu_cube_tint_g.getInt(), 0, 255),
                                                   clamp<int>(fposu_cube_tint_b.getInt(), 0, 255)));
                                                   clamp<int>(fposu_cube_tint_b.getInt(), 0, 255)));
                                 g->drawVAO(m_vaoCube);
                                 g->drawVAO(m_vaoCube);
                             }
                             }
-                            m_osu->getSkin()->getBackgroundCube()->unbind();
+                            osu->getSkin()->getBackgroundCube()->unbind();
                         }
                         }
                     }
                     }
                     g->setDepthBuffer(false);
                     g->setDepthBuffer(false);
@@ -207,12 +198,12 @@ void ModFPoSu::draw(Graphics *g) {
                     Matrix4 worldMatrix = m_modelMatrix;
                     Matrix4 worldMatrix = m_modelMatrix;
                     g->setWorldMatrixMul(worldMatrix);
                     g->setWorldMatrixMul(worldMatrix);
                     {
                     {
-                        m_osu->getPlayfieldBuffer()->bind();
+                        osu->getPlayfieldBuffer()->bind();
                         {
                         {
                             g->setColor(0xffffffff);
                             g->setColor(0xffffffff);
                             g->drawVAO(m_vao);
                             g->drawVAO(m_vao);
                         }
                         }
-                        m_osu->getPlayfieldBuffer()->unbind();
+                        osu->getPlayfieldBuffer()->unbind();
                     }
                     }
 
 
                     // (no setBlending(false), since we are already at the end)
                     // (no setBlending(false), since we are already at the end)
@@ -223,11 +214,11 @@ void ModFPoSu::draw(Graphics *g) {
         }
         }
         g->onResolutionChange(resolutionBackup);
         g->onResolutionChange(resolutionBackup);
     }
     }
-    m_osu->getSliderFrameBuffer()->disable();
+    osu->getSliderFrameBuffer()->disable();
 
 
     // finally, draw that to the screen
     // finally, draw that to the screen
     g->setBlending(false);
     g->setBlending(false);
-    { m_osu->getSliderFrameBuffer()->draw(g, 0, 0); }
+    { osu->getSliderFrameBuffer()->draw(g, 0, 0); }
     g->setBlending(true);
     g->setBlending(true);
 }
 }
 
 
@@ -239,8 +230,7 @@ void ModFPoSu::update() {
     m_modelMatrix = Matrix4();
     m_modelMatrix = Matrix4();
     {
     {
         m_modelMatrix.scale(
         m_modelMatrix.scale(
-            1.0f,
-            (m_osu->getPlayfieldBuffer()->getHeight() / m_osu->getPlayfieldBuffer()->getWidth()) * (m_fCircumLength),
+            1.0f, (osu->getPlayfieldBuffer()->getHeight() / osu->getPlayfieldBuffer()->getWidth()) * (m_fCircumLength),
             1.0f);
             1.0f);
 
 
         // rotate around center
         // rotate around center
@@ -260,10 +250,10 @@ void ModFPoSu::update() {
                            .getFloat());  // NOTE: slightly move back by default to avoid aliasing with background cube
                            .getFloat());  // NOTE: slightly move back by default to avoid aliasing with background cube
 
 
         if(fposu_mod_strafing.getBool()) {
         if(fposu_mod_strafing.getBool()) {
-            if(m_osu->isInPlayMode()) {
-                const long curMusicPos = m_osu->getSelectedBeatmap()->getCurMusicPos();
+            if(osu->isInPlayMode()) {
+                const long curMusicPos = osu->getSelectedBeatmap()->getCurMusicPos();
 
 
-                const float speedMultiplierCompensation = 1.0f / m_osu->getSelectedBeatmap()->getSpeedMultiplier();
+                const float speedMultiplierCompensation = 1.0f / osu->getSelectedBeatmap()->getSpeedMultiplier();
 
 
                 const float x = std::sin((curMusicPos / 1000.0f) * 5 * speedMultiplierCompensation *
                 const float x = std::sin((curMusicPos / 1000.0f) * 5 * speedMultiplierCompensation *
                                          fposu_mod_strafing_frequency_x.getFloat()) *
                                          fposu_mod_strafing_frequency_x.getFloat()) *
@@ -281,7 +271,7 @@ void ModFPoSu::update() {
     }
     }
 
 
     const bool isAutoCursor =
     const bool isAutoCursor =
-        (m_osu->getModAuto() || m_osu->getModAutopilot() || m_osu->getSelectedBeatmap()->m_bIsWatchingReplay);
+        (osu->getModAuto() || osu->getModAutopilot() || osu->getSelectedBeatmap()->m_bIsWatchingReplay);
 
 
     m_bCrosshairIntersectsScreen = true;
     m_bCrosshairIntersectsScreen = true;
     if(!fposu_absolute_mode.getBool() && !isAutoCursor &&
     if(!fposu_absolute_mode.getBool() && !isAutoCursor &&
@@ -321,7 +311,7 @@ void ModFPoSu::update() {
             // special case: force to center of screen if no intersection
             // special case: force to center of screen if no intersection
             if(newMousePos.x == 0.0f && newMousePos.y == 0.0f) {
             if(newMousePos.x == 0.0f && newMousePos.y == 0.0f) {
                 m_bCrosshairIntersectsScreen = false;
                 m_bCrosshairIntersectsScreen = false;
-                newMousePos = m_osu->getScreenSize() / 2;
+                newMousePos = osu->getScreenSize() / 2;
             }
             }
 
 
             setMousePosCompensated(newMousePos);
             setMousePosCompensated(newMousePos);
@@ -329,7 +319,7 @@ void ModFPoSu::update() {
     } else {
     } else {
         // absolute mouse position mode (or auto)
         // absolute mouse position mode (or auto)
         Vector2 mousePos = engine->getMouse()->getPos();
         Vector2 mousePos = engine->getMouse()->getPos();
-        auto beatmap = m_osu->getSelectedBeatmap();
+        auto beatmap = osu->getSelectedBeatmap();
         if(isAutoCursor && !beatmap->isPaused()) {
         if(isAutoCursor && !beatmap->isPaused()) {
             mousePos = beatmap->getCursorPos();
             mousePos = beatmap->getCursorPos();
         }
         }
@@ -508,11 +498,11 @@ Vector2 ModFPoSu::intersectRayMesh(Vector3 pos, Vector3 dir) {
                         const float x = u / (rightLength * rightLength);
                         const float x = u / (rightLength * rightLength);
                         const float y = v / (downLength * downLength);
                         const float y = v / (downLength * downLength);
                         const float distancePerFace =
                         const float distancePerFace =
-                            (float)m_osu->getScreenWidth() / std::pow(2.0f, (float)SUBDIVISIONS);
+                            (float)osu->getScreenWidth() / std::pow(2.0f, (float)SUBDIVISIONS);
                         const float distanceInFace = distancePerFace * x;
                         const float distanceInFace = distancePerFace * x;
 
 
                         const Vector2 newMousePos =
                         const Vector2 newMousePos =
-                            Vector2((distancePerFace * face) + distanceInFace, y * m_osu->getScreenHeight());
+                            Vector2((distancePerFace * face) + distanceInFace, y * osu->getScreenHeight());
 
 
                         return newMousePos;
                         return newMousePos;
                     }
                     }
@@ -530,8 +520,8 @@ Vector2 ModFPoSu::intersectRayMesh(Vector3 pos, Vector3 dir) {
 
 
 Vector3 ModFPoSu::calculateUnProjectedVector(Vector2 pos) {
 Vector3 ModFPoSu::calculateUnProjectedVector(Vector2 pos) {
     // calculate 3d position of 2d cursor on screen mesh
     // calculate 3d position of 2d cursor on screen mesh
-    const float cursorXPercent = clamp<float>(pos.x / (float)m_osu->getScreenWidth(), 0.0f, 1.0f);
-    const float cursorYPercent = clamp<float>(pos.y / (float)m_osu->getScreenHeight(), 0.0f, 1.0f);
+    const float cursorXPercent = clamp<float>(pos.x / (float)osu->getScreenWidth(), 0.0f, 1.0f);
+    const float cursorYPercent = clamp<float>(pos.y / (float)osu->getScreenHeight(), 0.0f, 1.0f);
 
 
     std::list<VertexPair>::iterator begin = m_meshList.begin();
     std::list<VertexPair>::iterator begin = m_meshList.begin();
     std::list<VertexPair>::iterator next = ++m_meshList.begin();
     std::list<VertexPair>::iterator next = ++m_meshList.begin();

+ 2 - 17
src/App/Osu/ModFPoSu.h

@@ -1,19 +1,8 @@
-//================ Copyright (c) 2019, Colin Brook & PG, All rights reserved. =================//
-//
-// Purpose:		real 3d first person mode for fps warmup/practice
-//
-// $NoKeywords: $fposu
-//=============================================================================================//
-
-#ifndef OSUMODFPOSU_H
-#define OSUMODFPOSU_H
-
+#pragma once
 #include <list>
 #include <list>
 
 
 #include "cbase.h"
 #include "cbase.h"
 
 
-class Osu;
-
 class Camera;
 class Camera;
 class ConVar;
 class ConVar;
 class Image;
 class Image;
@@ -28,7 +17,7 @@ class ModFPoSu {
     static constexpr const int SUBDIVISIONS = 4;
     static constexpr const int SUBDIVISIONS = 4;
 
 
    public:
    public:
-    ModFPoSu(Osu *osu);
+    ModFPoSu();
     ~ModFPoSu();
     ~ModFPoSu();
 
 
     void draw(Graphics *g);
     void draw(Graphics *g);
@@ -76,8 +65,6 @@ class ModFPoSu {
     static Vector3 normalFromTriangle(Vector3 p1, Vector3 p2, Vector3 p3);
     static Vector3 normalFromTriangle(Vector3 p1, Vector3 p2, Vector3 p3);
 
 
    private:
    private:
-    Osu *m_osu;
-
     ConVar *m_mouse_sensitivity_ref;
     ConVar *m_mouse_sensitivity_ref;
     ConVar *m_osu_draw_beatmap_background_image_ref;
     ConVar *m_osu_draw_beatmap_background_image_ref;
     ConVar *m_osu_background_dim_ref;
     ConVar *m_osu_background_dim_ref;
@@ -107,5 +94,3 @@ class ModFPoSu {
 
 
     Shader *m_hitcircleShader;
     Shader *m_hitcircleShader;
 };
 };
-
-#endif

+ 147 - 160
src/App/Osu/ModSelector.cpp

@@ -1,10 +1,3 @@
-//================ Copyright (c) 2015, PG, All rights reserved. =================//
-//
-// Purpose:		difficulty modifier selection screen
-//
-// $NoKeywords: $osums
-//===============================================================================//
-
 #include "ModSelector.h"
 #include "ModSelector.h"
 
 
 #include "AnimationHandler.h"
 #include "AnimationHandler.h"
@@ -46,20 +39,17 @@
 
 
 class ModSelectorOverrideSliderDescButton : public CBaseUIButton {
 class ModSelectorOverrideSliderDescButton : public CBaseUIButton {
    public:
    public:
-    ModSelectorOverrideSliderDescButton(Osu *osu, float xPos, float yPos, float xSize, float ySize, UString name,
-                                        UString text)
-        : CBaseUIButton(xPos, yPos, xSize, ySize, name, text) {
-        m_osu = osu;
-    }
+    ModSelectorOverrideSliderDescButton(float xPos, float yPos, float xSize, float ySize, UString name, UString text)
+        : CBaseUIButton(xPos, yPos, xSize, ySize, name, text) {}
 
 
     virtual void mouse_update(bool *propagate_clicks) {
     virtual void mouse_update(bool *propagate_clicks) {
         if(!m_bVisible) return;
         if(!m_bVisible) return;
         CBaseUIButton::mouse_update(propagate_clicks);
         CBaseUIButton::mouse_update(propagate_clicks);
 
 
         if(isMouseInside() && m_sTooltipText.length() > 0) {
         if(isMouseInside() && m_sTooltipText.length() > 0) {
-            m_osu->getTooltipOverlay()->begin();
-            { m_osu->getTooltipOverlay()->addLine(m_sTooltipText); }
-            m_osu->getTooltipOverlay()->end();
+            osu->getTooltipOverlay()->begin();
+            { osu->getTooltipOverlay()->addLine(m_sTooltipText); }
+            osu->getTooltipOverlay()->end();
         }
         }
     }
     }
 
 
@@ -85,16 +75,13 @@ class ModSelectorOverrideSliderDescButton : public CBaseUIButton {
         }
         }
     }
     }
 
 
-    Osu *m_osu;
     UString m_sTooltipText;
     UString m_sTooltipText;
 };
 };
 
 
 class ModSelectorOverrideSliderLockButton : public CBaseUICheckbox {
 class ModSelectorOverrideSliderLockButton : public CBaseUICheckbox {
    public:
    public:
-    ModSelectorOverrideSliderLockButton(Osu *osu, float xPos, float yPos, float xSize, float ySize, UString name,
-                                        UString text)
+    ModSelectorOverrideSliderLockButton(float xPos, float yPos, float xSize, float ySize, UString name, UString text)
         : CBaseUICheckbox(xPos, yPos, xSize, ySize, name, text) {
         : CBaseUICheckbox(xPos, yPos, xSize, ySize, name, text) {
-        m_osu = osu;
         m_fAnim = 1.0f;
         m_fAnim = 1.0f;
     }
     }
 
 
@@ -105,7 +92,7 @@ class ModSelectorOverrideSliderLockButton : public CBaseUICheckbox {
         UString iconString;
         UString iconString;
         iconString.insert(0, icon);
         iconString.insert(0, icon);
 
 
-        McFont *iconFont = m_osu->getFontIcons();
+        McFont *iconFont = osu->getFontIcons();
         const float scale = (m_vSize.y / iconFont->getHeight()) * m_fAnim;
         const float scale = (m_vSize.y / iconFont->getHeight()) * m_fAnim;
         g->setColor(m_bChecked ? 0xffffffff : 0xff1166ff);
         g->setColor(m_bChecked ? 0xffffffff : 0xff1166ff);
 
 
@@ -122,7 +109,7 @@ class ModSelectorOverrideSliderLockButton : public CBaseUICheckbox {
    private:
    private:
     virtual void onPressed() {
     virtual void onPressed() {
         CBaseUICheckbox::onPressed();
         CBaseUICheckbox::onPressed();
-        engine->getSound()->play(isChecked() ? m_osu->getSkin()->getCheckOn() : m_osu->getSkin()->getCheckOff());
+        engine->getSound()->play(isChecked() ? osu->getSkin()->getCheckOn() : osu->getSkin()->getCheckOff());
 
 
         if(isChecked()) {
         if(isChecked()) {
             // anim->moveQuadOut(&m_fAnim, 1.5f, 0.060f, true);
             // anim->moveQuadOut(&m_fAnim, 1.5f, 0.060f, true);
@@ -133,18 +120,17 @@ class ModSelectorOverrideSliderLockButton : public CBaseUICheckbox {
         }
         }
     }
     }
 
 
-    Osu *m_osu;
     float m_fAnim;
     float m_fAnim;
 };
 };
 
 
-ModSelector::ModSelector(Osu *osu) : OsuScreen(osu) {
+ModSelector::ModSelector() : OsuScreen() {
     m_fAnimation = 0.0f;
     m_fAnimation = 0.0f;
     m_fExperimentalAnimation = 0.0f;
     m_fExperimentalAnimation = 0.0f;
     m_bScheduledHide = false;
     m_bScheduledHide = false;
     m_bExperimentalVisible = false;
     m_bExperimentalVisible = false;
-    setSize(m_osu->getScreenWidth(), m_osu->getScreenHeight());
-    m_overrideSliderContainer = new CBaseUIContainer(0, 0, m_osu->getScreenWidth(), m_osu->getScreenHeight(), "");
-    m_experimentalContainer = new CBaseUIScrollView(-1, 0, m_osu->getScreenWidth(), m_osu->getScreenHeight(), "");
+    setSize(osu->getScreenWidth(), osu->getScreenHeight());
+    m_overrideSliderContainer = new CBaseUIContainer(0, 0, osu->getScreenWidth(), osu->getScreenHeight(), "");
+    m_experimentalContainer = new CBaseUIScrollView(-1, 0, osu->getScreenWidth(), osu->getScreenHeight(), "");
     m_experimentalContainer->setHorizontalScrolling(false);
     m_experimentalContainer->setHorizontalScrolling(false);
     m_experimentalContainer->setVerticalScrolling(true);
     m_experimentalContainer->setVerticalScrolling(true);
     m_experimentalContainer->setDrawFrame(false);
     m_experimentalContainer->setDrawFrame(false);
@@ -169,7 +155,7 @@ ModSelector::ModSelector(Osu *osu) : OsuScreen(osu) {
 
 
     for(int x = 0; x < m_iGridWidth; x++) {
     for(int x = 0; x < m_iGridWidth; x++) {
         for(int y = 0; y < m_iGridHeight; y++) {
         for(int y = 0; y < m_iGridHeight; y++) {
-            UIModSelectorModButton *imageButton = new UIModSelectorModButton(m_osu, this, 50, 50, 100, 100, "");
+            UIModSelectorModButton *imageButton = new UIModSelectorModButton(this, 50, 50, 100, 100, "");
             imageButton->setDrawBackground(false);
             imageButton->setDrawBackground(false);
             imageButton->setVisible(false);
             imageButton->setVisible(false);
 
 
@@ -304,87 +290,87 @@ ModSelector::ModSelector(Osu *osu) : OsuScreen(osu) {
 
 
 void ModSelector::updateButtons(bool initial) {
 void ModSelector::updateButtons(bool initial) {
     m_modButtonEasy = setModButtonOnGrid(
     m_modButtonEasy = setModButtonOnGrid(
-        0, 0, 0, initial && m_osu->getModEZ(), "ez",
+        0, 0, 0, initial && osu->getModEZ(), "ez",
         "Reduces overall difficulty - larger circles, more forgiving HP drain, less accuracy required.",
         "Reduces overall difficulty - larger circles, more forgiving HP drain, less accuracy required.",
-        [this]() -> SkinImage * { return m_osu->getSkin()->getSelectionModEasy(); });
+        []() -> SkinImage * { return osu->getSkin()->getSelectionModEasy(); });
     m_modButtonNofail =
     m_modButtonNofail =
-        setModButtonOnGrid(1, 0, 0, initial && m_osu->getModNF(), "nf",
+        setModButtonOnGrid(1, 0, 0, initial && osu->getModNF(), "nf",
                            "You can't fail. No matter what.\nNOTE: To disable drain completely:\nOptions > Gameplay > "
                            "You can't fail. No matter what.\nNOTE: To disable drain completely:\nOptions > Gameplay > "
                            "Mechanics > \"Select HP Drain\" > \"None\".",
                            "Mechanics > \"Select HP Drain\" > \"None\".",
-                           [this]() -> SkinImage * { return m_osu->getSkin()->getSelectionModNoFail(); });
+                           []() -> SkinImage * { return osu->getSkin()->getSelectionModNoFail(); });
     m_modButtonNofail->setAvailable(m_osu_drain_type_ref->getInt() > 1);
     m_modButtonNofail->setAvailable(m_osu_drain_type_ref->getInt() > 1);
-    setModButtonOnGrid(4, 0, 0, initial && m_osu->getModNightmare(), "nightmare",
+    setModButtonOnGrid(4, 0, 0, initial && osu->getModNightmare(), "nightmare",
                        "Unnecessary clicks count as misses.\nMassively reduced slider follow circle radius.",
                        "Unnecessary clicks count as misses.\nMassively reduced slider follow circle radius.",
-                       [this]() -> SkinImage * { return m_osu->getSkin()->getSelectionModNightmare(); });
+                       []() -> SkinImage * { return osu->getSkin()->getSelectionModNightmare(); });
 
 
     m_modButtonHardrock =
     m_modButtonHardrock =
-        setModButtonOnGrid(0, 1, 0, initial && m_osu->getModHR(), "hr", "Everything just got a bit harder...",
-                           [this]() -> SkinImage * { return m_osu->getSkin()->getSelectionModHardRock(); });
+        setModButtonOnGrid(0, 1, 0, initial && osu->getModHR(), "hr", "Everything just got a bit harder...",
+                           []() -> SkinImage * { return osu->getSkin()->getSelectionModHardRock(); });
     m_modButtonSuddendeath =
     m_modButtonSuddendeath =
-        setModButtonOnGrid(1, 1, 0, initial && m_osu->getModSD(), "sd", "Miss a note and fail.",
-                           [this]() -> SkinImage * { return m_osu->getSkin()->getSelectionModSuddenDeath(); });
-    setModButtonOnGrid(1, 1, 1, initial && m_osu->getModSS(), "ss", "SS or quit.",
-                       [this]() -> SkinImage * { return m_osu->getSkin()->getSelectionModPerfect(); });
+        setModButtonOnGrid(1, 1, 0, initial && osu->getModSD(), "sd", "Miss a note and fail.",
+                           []() -> SkinImage * { return osu->getSkin()->getSelectionModSuddenDeath(); });
+    setModButtonOnGrid(1, 1, 1, initial && osu->getModSS(), "ss", "SS or quit.",
+                       []() -> SkinImage * { return osu->getSkin()->getSelectionModPerfect(); });
 
 
     if(convar->getConVarByName("nightcore_enjoyer")->getBool()) {
     if(convar->getConVarByName("nightcore_enjoyer")->getBool()) {
         m_modButtonHalftime =
         m_modButtonHalftime =
-            setModButtonOnGrid(2, 0, 0, initial && m_osu->getModDC(), "dc", "A E S T H E T I C",
-                               [this]() -> SkinImage * { return m_osu->getSkin()->getSelectionModDayCore(); });
-        setModButtonOnGrid(2, 0, 1, initial && m_osu->getModHT(), "ht", "Less zoom.",
-                           [this]() -> SkinImage * { return m_osu->getSkin()->getSelectionModHalfTime(); });
+            setModButtonOnGrid(2, 0, 0, initial && osu->getModDC(), "dc", "A E S T H E T I C",
+                               []() -> SkinImage * { return osu->getSkin()->getSelectionModDayCore(); });
+        setModButtonOnGrid(2, 0, 1, initial && osu->getModHT(), "ht", "Less zoom.",
+                           []() -> SkinImage * { return osu->getSkin()->getSelectionModHalfTime(); });
 
 
         m_modButtonDoubletime =
         m_modButtonDoubletime =
-            setModButtonOnGrid(2, 1, 0, initial && m_osu->getModNC(), "nc", "uguuuuuuuu",
-                               [this]() -> SkinImage * { return m_osu->getSkin()->getSelectionModNightCore(); });
-        setModButtonOnGrid(2, 1, 1, initial && m_osu->getModDT(), "dt", "Zoooooooooom.",
-                           [this]() -> SkinImage * { return m_osu->getSkin()->getSelectionModDoubleTime(); });
+            setModButtonOnGrid(2, 1, 0, initial && osu->getModNC(), "nc", "uguuuuuuuu",
+                               []() -> SkinImage * { return osu->getSkin()->getSelectionModNightCore(); });
+        setModButtonOnGrid(2, 1, 1, initial && osu->getModDT(), "dt", "Zoooooooooom.",
+                           []() -> SkinImage * { return osu->getSkin()->getSelectionModDoubleTime(); });
     } else {
     } else {
         m_modButtonHalftime =
         m_modButtonHalftime =
-            setModButtonOnGrid(2, 0, 0, initial && m_osu->getModHT(), "ht", "Less zoom.",
-                               [this]() -> SkinImage * { return m_osu->getSkin()->getSelectionModHalfTime(); });
-        setModButtonOnGrid(2, 0, 1, initial && m_osu->getModDC(), "dc", "A E S T H E T I C",
-                           [this]() -> SkinImage * { return m_osu->getSkin()->getSelectionModDayCore(); });
+            setModButtonOnGrid(2, 0, 0, initial && osu->getModHT(), "ht", "Less zoom.",
+                               []() -> SkinImage * { return osu->getSkin()->getSelectionModHalfTime(); });
+        setModButtonOnGrid(2, 0, 1, initial && osu->getModDC(), "dc", "A E S T H E T I C",
+                           []() -> SkinImage * { return osu->getSkin()->getSelectionModDayCore(); });
 
 
         m_modButtonDoubletime =
         m_modButtonDoubletime =
-            setModButtonOnGrid(2, 1, 0, initial && m_osu->getModDT(), "dt", "Zoooooooooom.",
-                               [this]() -> SkinImage * { return m_osu->getSkin()->getSelectionModDoubleTime(); });
-        setModButtonOnGrid(2, 1, 1, initial && m_osu->getModNC(), "nc", "uguuuuuuuu",
-                           [this]() -> SkinImage * { return m_osu->getSkin()->getSelectionModNightCore(); });
+            setModButtonOnGrid(2, 1, 0, initial && osu->getModDT(), "dt", "Zoooooooooom.",
+                               []() -> SkinImage * { return osu->getSkin()->getSelectionModDoubleTime(); });
+        setModButtonOnGrid(2, 1, 1, initial && osu->getModNC(), "nc", "uguuuuuuuu",
+                           []() -> SkinImage * { return osu->getSkin()->getSelectionModNightCore(); });
     }
     }
 
 
     m_modButtonHidden =
     m_modButtonHidden =
-        setModButtonOnGrid(3, 1, 0, initial && m_osu->getModHD(), "hd",
+        setModButtonOnGrid(3, 1, 0, initial && osu->getModHD(), "hd",
                            "Play with no approach circles and fading notes for a slight score advantage.",
                            "Play with no approach circles and fading notes for a slight score advantage.",
-                           [this]() -> SkinImage * { return m_osu->getSkin()->getSelectionModHidden(); });
-    m_modButtonFlashlight = setModButtonOnGrid(4, 1, 0, false, "fl", "Restricted view area.", [this]() -> SkinImage * {
-        return m_osu->getSkin()->getSelectionModFlashlight();
+                           []() -> SkinImage * { return osu->getSkin()->getSelectionModHidden(); });
+    m_modButtonFlashlight = setModButtonOnGrid(4, 1, 0, false, "fl", "Restricted view area.", []() -> SkinImage * {
+        return osu->getSkin()->getSelectionModFlashlight();
     });
     });
-    m_modButtonTD = setModButtonOnGrid(5, 1, 0, initial && (m_osu->getModTD() || m_osu_mod_touchdevice_ref->getBool()),
+    m_modButtonTD = setModButtonOnGrid(5, 1, 0, initial && (osu->getModTD() || m_osu_mod_touchdevice_ref->getBool()),
                                        "nerftd", "Simulate pp nerf for touch devices.\nOnly affects pp calculation.",
                                        "nerftd", "Simulate pp nerf for touch devices.\nOnly affects pp calculation.",
-                                       [this]() -> SkinImage * { return m_osu->getSkin()->getSelectionModTD(); });
+                                       []() -> SkinImage * { return osu->getSkin()->getSelectionModTD(); });
     getModButtonOnGrid(5, 1)->setAvailable(!m_osu_mod_touchdevice_ref->getBool());
     getModButtonOnGrid(5, 1)->setAvailable(!m_osu_mod_touchdevice_ref->getBool());
 
 
     m_modButtonRelax = setModButtonOnGrid(
     m_modButtonRelax = setModButtonOnGrid(
-        0, 2, 0, initial && m_osu->getModRelax(), "relax",
+        0, 2, 0, initial && osu->getModRelax(), "relax",
         "You don't need to click.\nGive your clicking/tapping fingers a break from the heat of things.\n** UNRANKED **",
         "You don't need to click.\nGive your clicking/tapping fingers a break from the heat of things.\n** UNRANKED **",
-        [this]() -> SkinImage * { return m_osu->getSkin()->getSelectionModRelax(); });
+        []() -> SkinImage * { return osu->getSkin()->getSelectionModRelax(); });
     m_modButtonAutopilot =
     m_modButtonAutopilot =
-        setModButtonOnGrid(1, 2, 0, initial && m_osu->getModAutopilot(), "autopilot",
+        setModButtonOnGrid(1, 2, 0, initial && osu->getModAutopilot(), "autopilot",
                            "Automatic cursor movement - just follow the rhythm.\n** UNRANKED **",
                            "Automatic cursor movement - just follow the rhythm.\n** UNRANKED **",
-                           [this]() -> SkinImage * { return m_osu->getSkin()->getSelectionModAutopilot(); });
-    m_modButtonSpunout = setModButtonOnGrid(
-        2, 2, 0, initial && m_osu->getModSpunout(), "spunout", "Spinners will be automatically completed.",
-        [this]() -> SkinImage * { return m_osu->getSkin()->getSelectionModSpunOut(); });
-    m_modButtonAuto = setModButtonOnGrid(
-        3, 2, 0, initial && m_osu->getModAuto(), "auto", "Watch a perfect automated play through the song.",
-        [this]() -> SkinImage * { return m_osu->getSkin()->getSelectionModAutoplay(); });
-    setModButtonOnGrid(4, 2, 0, initial && m_osu->getModTarget(), "practicetarget",
+                           []() -> SkinImage * { return osu->getSkin()->getSelectionModAutopilot(); });
+    m_modButtonSpunout = setModButtonOnGrid(2, 2, 0, initial && osu->getModSpunout(), "spunout",
+                                            "Spinners will be automatically completed.",
+                                            []() -> SkinImage * { return osu->getSkin()->getSelectionModSpunOut(); });
+    m_modButtonAuto = setModButtonOnGrid(3, 2, 0, initial && osu->getModAuto(), "auto",
+                                         "Watch a perfect automated play through the song.",
+                                         []() -> SkinImage * { return osu->getSkin()->getSelectionModAutoplay(); });
+    setModButtonOnGrid(4, 2, 0, initial && osu->getModTarget(), "practicetarget",
                        "Accuracy is based on the distance to the center of all hitobjects.\n300s still require at "
                        "Accuracy is based on the distance to the center of all hitobjects.\n300s still require at "
                        "least being in the hit window of a 100 in addition to the rule above.",
                        "least being in the hit window of a 100 in addition to the rule above.",
-                       [this]() -> SkinImage * { return m_osu->getSkin()->getSelectionModTarget(); });
-    m_modButtonScoreV2 = setModButtonOnGrid(
-        5, 2, 0, initial && m_osu->getModScorev2(), "v2", "Try the future scoring system.\n** UNRANKED **",
-        [this]() -> SkinImage * { return m_osu->getSkin()->getSelectionModScorev2(); });
+                       []() -> SkinImage * { return osu->getSkin()->getSelectionModTarget(); });
+    m_modButtonScoreV2 = setModButtonOnGrid(5, 2, 0, initial && osu->getModScorev2(), "v2",
+                                            "Try the future scoring system.\n** UNRANKED **",
+                                            []() -> SkinImage * { return osu->getSkin()->getSelectionModScorev2(); });
 
 
     // Enable all mods that we disable conditionally below
     // Enable all mods that we disable conditionally below
     getModButtonOnGrid(2, 0)->setAvailable(true);
     getModButtonOnGrid(2, 0)->setAvailable(true);
@@ -408,7 +394,7 @@ void ModSelector::updateButtons(bool initial) {
 }
 }
 
 
 void ModSelector::updateScoreMultiplierLabelText() {
 void ModSelector::updateScoreMultiplierLabelText() {
-    const float scoreMultiplier = m_osu->getScoreMultiplier();
+    const float scoreMultiplier = osu->getScoreMultiplier();
 
 
     const int alpha = 200;
     const int alpha = 200;
     if(scoreMultiplier > 1.0f)
     if(scoreMultiplier > 1.0f)
@@ -453,8 +439,8 @@ void ModSelector::draw(Graphics *g) {
 
 
     if(bancho.is_in_a_multi_room()) {
     if(bancho.is_in_a_multi_room()) {
         // get mod button element bounds
         // get mod button element bounds
-        Vector2 modGridButtonsStart = Vector2(m_osu->getScreenWidth(), m_osu->getScreenHeight());
-        Vector2 modGridButtonsSize = Vector2(0, m_osu->getScreenHeight());
+        Vector2 modGridButtonsStart = Vector2(osu->getScreenWidth(), osu->getScreenHeight());
+        Vector2 modGridButtonsSize = Vector2(0, osu->getScreenHeight());
         for(int i = 0; i < m_modButtons.size(); i++) {
         for(int i = 0; i < m_modButtons.size(); i++) {
             CBaseUIButton *button = m_modButtons[i];
             CBaseUIButton *button = m_modButtons[i];
 
 
@@ -481,7 +467,7 @@ void ModSelector::draw(Graphics *g) {
         // if we are in compact mode, draw some backgrounds under the override sliders & mod grid buttons
         // if we are in compact mode, draw some backgrounds under the override sliders & mod grid buttons
 
 
         // get override slider element bounds
         // get override slider element bounds
-        Vector2 overrideSlidersStart = Vector2(m_osu->getScreenWidth(), 0);
+        Vector2 overrideSlidersStart = Vector2(osu->getScreenWidth(), 0);
         Vector2 overrideSlidersSize;
         Vector2 overrideSlidersSize;
         for(int i = 0; i < m_overrideSliders.size(); i++) {
         for(int i = 0; i < m_overrideSliders.size(); i++) {
             CBaseUIButton *desc = m_overrideSliders[i].desc;
             CBaseUIButton *desc = m_overrideSliders[i].desc;
@@ -497,8 +483,8 @@ void ModSelector::draw(Graphics *g) {
         overrideSlidersSize.x -= overrideSlidersStart.x;
         overrideSlidersSize.x -= overrideSlidersStart.x;
 
 
         // get mod button element bounds
         // get mod button element bounds
-        Vector2 modGridButtonsStart = Vector2(m_osu->getScreenWidth(), m_osu->getScreenHeight());
-        Vector2 modGridButtonsSize = Vector2(0, m_osu->getScreenHeight());
+        Vector2 modGridButtonsStart = Vector2(osu->getScreenWidth(), osu->getScreenHeight());
+        Vector2 modGridButtonsSize = Vector2(0, osu->getScreenHeight());
         for(int i = 0; i < m_modButtons.size(); i++) {
         for(int i = 0; i < m_modButtons.size(); i++) {
             CBaseUIButton *button = m_modButtons[i];
             CBaseUIButton *button = m_modButtons[i];
 
 
@@ -536,10 +522,10 @@ void ModSelector::draw(Graphics *g) {
     {
     {
         // draw hint text on left edge of screen
         // draw hint text on left edge of screen
         {
         {
-            const float dpiScale = Osu::getUIScale(m_osu);
+            const float dpiScale = Osu::getUIScale();
 
 
             UString experimentalText = "Experimental Mods";
             UString experimentalText = "Experimental Mods";
-            McFont *experimentalFont = m_osu->getSubTitleFont();
+            McFont *experimentalFont = osu->getSubTitleFont();
 
 
             const float experimentalTextWidth = experimentalFont->getStringWidth(experimentalText);
             const float experimentalTextWidth = experimentalFont->getStringWidth(experimentalText);
             const float experimentalTextHeight = experimentalFont->getHeight();
             const float experimentalTextHeight = experimentalFont->getHeight();
@@ -554,7 +540,7 @@ void ModSelector::draw(Graphics *g) {
                 g->translate(
                 g->translate(
                     (int)(experimentalTextHeight / 3.0f +
                     (int)(experimentalTextHeight / 3.0f +
                           std::max(0.0f, experimentalModsAnimationTranslation + m_experimentalContainer->getSize().x)),
                           std::max(0.0f, experimentalModsAnimationTranslation + m_experimentalContainer->getSize().x)),
-                    (int)(m_osu->getScreenHeight() / 2 - experimentalTextWidth / 2));
+                    (int)(osu->getScreenHeight() / 2 - experimentalTextWidth / 2));
                 g->setColor(0xff777777);
                 g->setColor(0xff777777);
                 g->setAlpha(1.0f - m_fExperimentalAnimation * m_fExperimentalAnimation);
                 g->setAlpha(1.0f - m_fExperimentalAnimation * m_fExperimentalAnimation);
                 g->drawString(experimentalFont, experimentalText);
                 g->drawString(experimentalFont, experimentalText);
@@ -566,7 +552,7 @@ void ModSelector::draw(Graphics *g) {
                 g->rotate(90);
                 g->rotate(90);
                 g->translate((int)(rectHeight + std::max(0.0f, experimentalModsAnimationTranslation +
                 g->translate((int)(rectHeight + std::max(0.0f, experimentalModsAnimationTranslation +
                                                                    m_experimentalContainer->getSize().x)),
                                                                    m_experimentalContainer->getSize().x)),
-                             (int)(m_osu->getScreenHeight() / 2 - rectWidth / 2));
+                             (int)(osu->getScreenHeight() / 2 - rectWidth / 2));
                 g->drawRect(0, 0, rectWidth, rectHeight);
                 g->drawRect(0, 0, rectWidth, rectHeight);
             }
             }
             g->popTransform();
             g->popTransform();
@@ -621,9 +607,9 @@ void ModSelector::mouse_update(bool *propagate_clicks) {
         if(m_bShowOverrideSliderALTHint) {
         if(m_bShowOverrideSliderALTHint) {
             for(int i = 0; i < m_overrideSliders.size(); i++) {
             for(int i = 0; i < m_overrideSliders.size(); i++) {
                 if(m_overrideSliders[i].slider->isBusy()) {
                 if(m_overrideSliders[i].slider->isBusy()) {
-                    m_osu->getTooltipOverlay()->begin();
-                    { m_osu->getTooltipOverlay()->addLine("Hold [ALT] to slide in 0.01 increments."); }
-                    m_osu->getTooltipOverlay()->end();
+                    osu->getTooltipOverlay()->begin();
+                    { osu->getTooltipOverlay()->addLine("Hold [ALT] to slide in 0.01 increments."); }
+                    osu->getTooltipOverlay()->end();
 
 
                     if(engine->getKeyboard()->isAltDown()) m_bShowOverrideSliderALTHint = false;
                     if(engine->getKeyboard()->isAltDown()) m_bShowOverrideSliderALTHint = false;
                 }
                 }
@@ -633,7 +619,7 @@ void ModSelector::mouse_update(bool *propagate_clicks) {
         // some experimental mod tooltip overrides
         // some experimental mod tooltip overrides
         if(m_experimentalModRandomCheckbox->isChecked())
         if(m_experimentalModRandomCheckbox->isChecked())
             m_experimentalModRandomCheckbox->setTooltipText(
             m_experimentalModRandomCheckbox->setTooltipText(
-                UString::format("Seed = %i", m_osu->getSelectedBeatmap()->getRandomSeed()));
+                UString::format("Seed = %i", osu->getSelectedBeatmap()->getRandomSeed()));
 
 
         // handle experimental mods visibility
         // handle experimental mods visibility
         bool experimentalModEnabled = false;
         bool experimentalModEnabled = false;
@@ -645,9 +631,9 @@ void ModSelector::mouse_update(bool *propagate_clicks) {
             }
             }
         }
         }
 
 
-        McRect experimentalTrigger = McRect(
-            0, 0, m_bExperimentalVisible ? m_experimentalContainer->getSize().x : m_osu->getScreenWidth() * 0.05f,
-            m_osu->getScreenHeight());
+        McRect experimentalTrigger =
+            McRect(0, 0, m_bExperimentalVisible ? m_experimentalContainer->getSize().x : osu->getScreenWidth() * 0.05f,
+                   osu->getScreenHeight());
         if(experimentalTrigger.contains(engine->getMouse()->getPos())) {
         if(experimentalTrigger.contains(engine->getMouse()->getPos())) {
             if(!m_bExperimentalVisible) {
             if(!m_bExperimentalVisible) {
                 m_bExperimentalVisible = true;
                 m_bExperimentalVisible = true;
@@ -672,8 +658,8 @@ void ModSelector::mouse_update(bool *propagate_clicks) {
             m_bWaitForHPChangeFinished = false;
             m_bWaitForHPChangeFinished = false;
 
 
             {
             {
-                if(m_osu->isInPlayMode()) m_osu->getSelectedBeatmap()->onModUpdate();
-                m_osu->getSongBrowser()->recalculateStarsForSelectedBeatmap(true);
+                if(osu->isInPlayMode()) osu->getSelectedBeatmap()->onModUpdate();
+                osu->getSongBrowser()->recalculateStarsForSelectedBeatmap(true);
             }
             }
         }
         }
 
 
@@ -686,8 +672,8 @@ void ModSelector::mouse_update(bool *propagate_clicks) {
             m_bWaitForHPChangeFinished = false;
             m_bWaitForHPChangeFinished = false;
 
 
             {
             {
-                if(m_osu->isInPlayMode()) m_osu->getSelectedBeatmap()->onModUpdate();
-                m_osu->getSongBrowser()->recalculateStarsForSelectedBeatmap(true);
+                if(osu->isInPlayMode()) osu->getSelectedBeatmap()->onModUpdate();
+                osu->getSongBrowser()->recalculateStarsForSelectedBeatmap(true);
             }
             }
         }
         }
 
 
@@ -698,7 +684,7 @@ void ModSelector::mouse_update(bool *propagate_clicks) {
             m_bWaitForCSChangeFinished = false;
             m_bWaitForCSChangeFinished = false;
             m_bWaitForSpeedChangeFinished = false;
             m_bWaitForSpeedChangeFinished = false;
             m_bWaitForHPChangeFinished = false;
             m_bWaitForHPChangeFinished = false;
-            if(m_osu->isInPlayMode()) m_osu->getSelectedBeatmap()->onModUpdate();
+            if(osu->isInPlayMode()) osu->getSelectedBeatmap()->onModUpdate();
         }
         }
     }
     }
 }
 }
@@ -787,7 +773,7 @@ CBaseUIContainer *ModSelector::setVisible(bool visible) {
     return this;
     return this;
 }
 }
 
 
-bool ModSelector::isInCompactMode() { return m_osu->isInPlayMode(); }
+bool ModSelector::isInCompactMode() { return osu->isInPlayMode(); }
 
 
 bool ModSelector::isCSOverrideSliderActive() { return m_CSSlider->isActive(); }
 bool ModSelector::isCSOverrideSliderActive() { return m_CSSlider->isActive(); }
 
 
@@ -819,14 +805,14 @@ bool ModSelector::isMouseInside() {
 void ModSelector::updateLayout() {
 void ModSelector::updateLayout() {
     if(m_modButtons.size() < 1 || m_overrideSliders.size() < 1) return;
     if(m_modButtons.size() < 1 || m_overrideSliders.size() < 1) return;
 
 
-    const float dpiScale = Osu::getUIScale(m_osu);
+    const float dpiScale = Osu::getUIScale();
     const float uiScale = Osu::ui_scale->getFloat();
     const float uiScale = Osu::ui_scale->getFloat();
 
 
     if(!isInCompactMode())  // normal layout
     if(!isInCompactMode())  // normal layout
     {
     {
         // mod grid buttons
         // mod grid buttons
-        Vector2 center = m_osu->getScreenSize() / 2.0f;
-        Vector2 size = m_osu->getSkin()->getSelectionModEasy()->getSizeBase() * uiScale;
+        Vector2 center = osu->getScreenSize() / 2.0f;
+        Vector2 size = osu->getSkin()->getSelectionModEasy()->getSizeBase() * uiScale;
         Vector2 offset = Vector2(size.x * 1.0f, size.y * 0.25f);
         Vector2 offset = Vector2(size.x * 1.0f, size.y * 0.25f);
         Vector2 start = Vector2(center.x - (size.x * m_iGridWidth) / 2.0f - (offset.x * (m_iGridWidth - 1)) / 2.0f,
         Vector2 start = Vector2(center.x - (size.x * m_iGridWidth) / 2.0f - (offset.x * (m_iGridWidth - 1)) / 2.0f,
                                 center.y - (size.y * m_iGridHeight) / 2.0f - (offset.y * (m_iGridHeight - 1)) / 2.0f);
                                 center.y - (size.y * m_iGridHeight) / 2.0f - (offset.y * (m_iGridHeight - 1)) / 2.0f);
@@ -845,12 +831,12 @@ void ModSelector::updateLayout() {
 
 
         // override sliders (down here because they depend on the mod grid button alignment)
         // override sliders (down here because they depend on the mod grid button alignment)
         const int margin = 10 * dpiScale;
         const int margin = 10 * dpiScale;
-        const int overrideSliderWidth = m_osu->getUIScale(m_osu, 250.0f);
+        const int overrideSliderWidth = osu->getUIScale(250.0f);
         const int overrideSliderHeight = 25 * dpiScale;
         const int overrideSliderHeight = 25 * dpiScale;
         const int overrideSliderOffsetY =
         const int overrideSliderOffsetY =
             ((start.y - m_overrideSliders.size() * overrideSliderHeight) / (m_overrideSliders.size() - 1)) * 0.35f;
             ((start.y - m_overrideSliders.size() * overrideSliderHeight) / (m_overrideSliders.size() - 1)) * 0.35f;
         const Vector2 overrideSliderStart =
         const Vector2 overrideSliderStart =
-            Vector2(m_osu->getScreenWidth() / 2 - overrideSliderWidth / 2,
+            Vector2(osu->getScreenWidth() / 2 - overrideSliderWidth / 2,
                     start.y / 2 - (m_overrideSliders.size() * overrideSliderHeight +
                     start.y / 2 - (m_overrideSliders.size() * overrideSliderHeight +
                                    (m_overrideSliders.size() - 1) * overrideSliderOffsetY) /
                                    (m_overrideSliders.size() - 1) * overrideSliderOffsetY) /
                                       1.75f);
                                       1.75f);
@@ -884,11 +870,11 @@ void ModSelector::updateLayout() {
         // action buttons
         // action buttons
         float actionMinY =
         float actionMinY =
             start.y + size.y * m_iGridHeight + offset.y * (m_iGridHeight - 1);  // exact bottom of the mod buttons
             start.y + size.y * m_iGridHeight + offset.y * (m_iGridHeight - 1);  // exact bottom of the mod buttons
-        Vector2 actionSize = Vector2(m_osu->getUIScale(m_osu, 448.0f) * uiScale, size.y * 0.75f);
+        Vector2 actionSize = Vector2(osu->getUIScale(448.0f) * uiScale, size.y * 0.75f);
         float actionOffsetY = actionSize.y * 0.5f;
         float actionOffsetY = actionSize.y * 0.5f;
         Vector2 actionStart =
         Vector2 actionStart =
-            Vector2(m_osu->getScreenWidth() / 2.0f - actionSize.x / 2.0f,
-                    actionMinY + (m_osu->getScreenHeight() - actionMinY) / 2.0f -
+            Vector2(osu->getScreenWidth() / 2.0f - actionSize.x / 2.0f,
+                    actionMinY + (osu->getScreenHeight() - actionMinY) / 2.0f -
                         (actionSize.y * m_actionButtons.size() + actionOffsetY * (m_actionButtons.size() - 1)) / 2.0f);
                         (actionSize.y * m_actionButtons.size() + actionOffsetY * (m_actionButtons.size() - 1)) / 2.0f);
         for(int i = 0; i < m_actionButtons.size(); i++) {
         for(int i = 0; i < m_actionButtons.size(); i++) {
             m_actionButtons[i]->setVisible(true);
             m_actionButtons[i]->setVisible(true);
@@ -903,23 +889,23 @@ void ModSelector::updateLayout() {
 
 
         m_nonVanillaWarning->setVisible(!convar->isVanilla() && bancho.submit_scores());
         m_nonVanillaWarning->setVisible(!convar->isVanilla() && bancho.submit_scores());
         m_nonVanillaWarning->setSizeToContent();
         m_nonVanillaWarning->setSizeToContent();
-        m_nonVanillaWarning->setSize(Vector2(m_osu->getScreenWidth(), 20 * uiScale));
+        m_nonVanillaWarning->setSize(Vector2(osu->getScreenWidth(), 20 * uiScale));
         m_nonVanillaWarning->setPos(
         m_nonVanillaWarning->setPos(
             0, modGridMaxY + std::abs(actionStart.y - modGridMaxY) / 2 - m_nonVanillaWarning->getSize().y);
             0, modGridMaxY + std::abs(actionStart.y - modGridMaxY) / 2 - m_nonVanillaWarning->getSize().y);
 
 
         m_scoreMultiplierLabel->setVisible(true);
         m_scoreMultiplierLabel->setVisible(true);
         m_scoreMultiplierLabel->setSizeToContent();
         m_scoreMultiplierLabel->setSizeToContent();
-        m_scoreMultiplierLabel->setSize(Vector2(m_osu->getScreenWidth(), 30 * uiScale));
+        m_scoreMultiplierLabel->setSize(Vector2(osu->getScreenWidth(), 30 * uiScale));
         m_scoreMultiplierLabel->setPos(0, m_nonVanillaWarning->getPos().y + 20 * uiScale);
         m_scoreMultiplierLabel->setPos(0, m_nonVanillaWarning->getPos().y + 20 * uiScale);
     } else  // compact in-beatmap mode
     } else  // compact in-beatmap mode
     {
     {
         // mod grid buttons
         // mod grid buttons
-        Vector2 center = m_osu->getScreenSize() / 2.0f;
-        Vector2 blockSize = m_osu->getSkin()->getSelectionModEasy()->getSizeBase() * uiScale;
+        Vector2 center = osu->getScreenSize() / 2.0f;
+        Vector2 blockSize = osu->getSkin()->getSelectionModEasy()->getSizeBase() * uiScale;
         Vector2 offset = Vector2(blockSize.x * 0.15f, blockSize.y * 0.05f);
         Vector2 offset = Vector2(blockSize.x * 0.15f, blockSize.y * 0.05f);
         Vector2 size = Vector2((blockSize.x * m_iGridWidth) + (offset.x * (m_iGridWidth - 1)),
         Vector2 size = Vector2((blockSize.x * m_iGridWidth) + (offset.x * (m_iGridWidth - 1)),
                                (blockSize.y * m_iGridHeight) + (offset.y * (m_iGridHeight - 1)));
                                (blockSize.y * m_iGridHeight) + (offset.y * (m_iGridHeight - 1)));
-        center.y = m_osu->getScreenHeight() - size.y / 2 - offset.y * 3.0f;
+        center.y = osu->getScreenHeight() - size.y / 2 - offset.y * 3.0f;
         Vector2 start = Vector2(center.x - size.x / 2.0f, center.y - size.y / 2.0f);
         Vector2 start = Vector2(center.x - size.x / 2.0f, center.y - size.y / 2.0f);
 
 
         for(int x = 0; x < m_iGridWidth; x++) {
         for(int x = 0; x < m_iGridWidth; x++) {
@@ -936,10 +922,10 @@ void ModSelector::updateLayout() {
 
 
         // override sliders (down here because they depend on the mod grid button alignment)
         // override sliders (down here because they depend on the mod grid button alignment)
         const int margin = 10 * dpiScale;
         const int margin = 10 * dpiScale;
-        int overrideSliderWidth = m_osu->getUIScale(m_osu, 250.0f);
+        int overrideSliderWidth = osu->getUIScale(250.0f);
         int overrideSliderHeight = 25 * dpiScale;
         int overrideSliderHeight = 25 * dpiScale;
         int overrideSliderOffsetY = 5 * dpiScale;
         int overrideSliderOffsetY = 5 * dpiScale;
-        Vector2 overrideSliderStart = Vector2(m_osu->getScreenWidth() / 2 - overrideSliderWidth / 2, 5 * dpiScale);
+        Vector2 overrideSliderStart = Vector2(osu->getScreenWidth() / 2 - overrideSliderWidth / 2, 5 * dpiScale);
         for(int i = 0; i < m_overrideSliders.size(); i++) {
         for(int i = 0; i < m_overrideSliders.size(); i++) {
             m_overrideSliders[i].desc->setSizeToContent(5 * dpiScale, 0);
             m_overrideSliders[i].desc->setSizeToContent(5 * dpiScale, 0);
             m_overrideSliders[i].desc->setSizeY(overrideSliderHeight);
             m_overrideSliders[i].desc->setSizeY(overrideSliderHeight);
@@ -979,7 +965,7 @@ void ModSelector::updateLayout() {
 }
 }
 
 
 void ModSelector::updateExperimentalLayout() {
 void ModSelector::updateExperimentalLayout() {
-    const float dpiScale = Osu::getUIScale(m_osu);
+    const float dpiScale = Osu::getUIScale();
 
 
     // experimental mods
     // experimental mods
     int yCounter = 5 * dpiScale;
     int yCounter = 5 * dpiScale;
@@ -1013,8 +999,8 @@ void ModSelector::updateExperimentalLayout() {
     }
     }
 
 
     // laziness
     // laziness
-    if(m_osu->getScreenHeight() > yCounter)
-        yCounter = 5 * dpiScale + m_osu->getScreenHeight() / 2.0f - yCounter / 2.0f;
+    if(osu->getScreenHeight() > yCounter)
+        yCounter = 5 * dpiScale + osu->getScreenHeight() / 2.0f - yCounter / 2.0f;
     else
     else
         yCounter = 5 * dpiScale;
         yCounter = 5 * dpiScale;
 
 
@@ -1049,7 +1035,7 @@ void ModSelector::updateModConVar() {
 
 
     updateScoreMultiplierLabelText();
     updateScoreMultiplierLabelText();
     updateOverrideSliderLabels();
     updateOverrideSliderLabels();
-    m_osu->updateMods();
+    osu->updateMods();
 }
 }
 
 
 UIModSelectorModButton *ModSelector::setModButtonOnGrid(int x, int y, int state, bool initialState, UString modName,
 UIModSelectorModButton *ModSelector::setModButtonOnGrid(int x, int y, int state, bool initialState, UString modName,
@@ -1080,12 +1066,12 @@ ModSelector::OVERRIDE_SLIDER ModSelector::addOverrideSlider(UString text, UStrin
 
 
     OVERRIDE_SLIDER os;
     OVERRIDE_SLIDER os;
     if(lockCvar != NULL) {
     if(lockCvar != NULL) {
-        os.lock = new ModSelectorOverrideSliderLockButton(m_osu, 0, 0, height, height, "", "");
+        os.lock = new ModSelectorOverrideSliderLockButton(0, 0, height, height, "", "");
         os.lock->setChangeCallback(fastdelegate::MakeDelegate(this, &ModSelector::onOverrideSliderLockChange));
         os.lock->setChangeCallback(fastdelegate::MakeDelegate(this, &ModSelector::onOverrideSliderLockChange));
     }
     }
-    os.desc = new ModSelectorOverrideSliderDescButton(m_osu, 0, 0, 100, height, "", text);
+    os.desc = new ModSelectorOverrideSliderDescButton(0, 0, 100, height, "", text);
     os.desc->setTooltipText(tooltipText);
     os.desc->setTooltipText(tooltipText);
-    os.slider = new UISlider(m_osu, 0, 0, 100, height, "");
+    os.slider = new UISlider(0, 0, 100, height, "");
     os.label = new CBaseUILabel(0, 0, 100, height, labelText, labelText);
     os.label = new CBaseUILabel(0, 0, 100, height, labelText, labelText);
     os.cvar = cvar;
     os.cvar = cvar;
     os.lockCvar = lockCvar;
     os.lockCvar = lockCvar;
@@ -1122,7 +1108,7 @@ ModSelector::OVERRIDE_SLIDER ModSelector::addOverrideSlider(UString text, UStrin
 }
 }
 
 
 UIButton *ModSelector::addActionButton(UString text) {
 UIButton *ModSelector::addActionButton(UString text) {
-    UIButton *actionButton = new UIButton(m_osu, 50, 50, 100, 100, text, text);
+    UIButton *actionButton = new UIButton(50, 50, 100, 100, text, text);
     m_actionButtons.push_back(actionButton);
     m_actionButtons.push_back(actionButton);
     addBaseUIElement(actionButton);
     addBaseUIElement(actionButton);
 
 
@@ -1131,7 +1117,7 @@ UIButton *ModSelector::addActionButton(UString text) {
 
 
 CBaseUILabel *ModSelector::addExperimentalLabel(UString text) {
 CBaseUILabel *ModSelector::addExperimentalLabel(UString text) {
     CBaseUILabel *label = new CBaseUILabel(0, 0, 0, 25, text, text);
     CBaseUILabel *label = new CBaseUILabel(0, 0, 0, 25, text, text);
-    label->setFont(m_osu->getSubTitleFont());
+    label->setFont(osu->getSubTitleFont());
     label->setWidthToContent(0);
     label->setWidthToContent(0);
     label->setDrawBackground(false);
     label->setDrawBackground(false);
     label->setDrawFrame(false);
     label->setDrawFrame(false);
@@ -1146,7 +1132,7 @@ CBaseUILabel *ModSelector::addExperimentalLabel(UString text) {
 }
 }
 
 
 UICheckbox *ModSelector::addExperimentalCheckbox(UString text, UString tooltipText, ConVar *cvar) {
 UICheckbox *ModSelector::addExperimentalCheckbox(UString text, UString tooltipText, ConVar *cvar) {
-    UICheckbox *checkbox = new UICheckbox(m_osu, 0, 0, 0, 35, text, text);
+    UICheckbox *checkbox = new UICheckbox(0, 0, 0, 35, text, text);
     checkbox->setTooltipText(tooltipText);
     checkbox->setTooltipText(tooltipText);
     checkbox->setWidthToContent(0);
     checkbox->setWidthToContent(0);
     if(cvar != NULL) {
     if(cvar != NULL) {
@@ -1167,7 +1153,7 @@ void ModSelector::resetModsUserInitiated() {
     bancho.prefer_daycore = false;
     bancho.prefer_daycore = false;
     resetMods();
     resetMods();
 
 
-    engine->getSound()->play(m_osu->getSkin()->getCheckOff());
+    engine->getSound()->play(osu->getSkin()->getCheckOff());
     m_resetModsButton->animateClickColor();
     m_resetModsButton->animateClickColor();
 
 
     if(bancho.is_online()) {
     if(bancho.is_online()) {
@@ -1191,7 +1177,7 @@ void ModSelector::resetModsUserInitiated() {
             write<u32>(&packet, bancho.room.slots[i].mods);
             write<u32>(&packet, bancho.room.slots[i].mods);
             send_packet(packet);
             send_packet(packet);
 
 
-            m_osu->m_room->updateLayout(m_osu->getScreenSize());
+            osu->m_room->updateLayout(osu->getScreenSize());
             break;
             break;
         }
         }
     }
     }
@@ -1247,6 +1233,8 @@ u32 ModSelector::getModFlags() {
     if(m_modButtonSpunout->isOn()) flags |= ModFlags::SpunOut;
     if(m_modButtonSpunout->isOn()) flags |= ModFlags::SpunOut;
     if(m_modButtonAutopilot->isOn()) flags |= ModFlags::Autopilot;
     if(m_modButtonAutopilot->isOn()) flags |= ModFlags::Autopilot;
     if(getModButtonOnGrid(4, 2)->isOn()) flags |= ModFlags::Target;
     if(getModButtonOnGrid(4, 2)->isOn()) flags |= ModFlags::Target;
+    if(m_modButtonAuto->isOn()) flags |= ModFlags::Autoplay;
+    if(m_modButtonFlashlight) flags |= ModFlags::Flashlight;
 
 
     return flags;
     return flags;
 }
 }
@@ -1285,7 +1273,7 @@ void ModSelector::enableModsFromFlags(u32 flags) {
 
 
 void ModSelector::close() {
 void ModSelector::close() {
     m_closeButton->animateClickColor();
     m_closeButton->animateClickColor();
-    m_osu->toggleModSelection();
+    osu->toggleModSelection();
 }
 }
 
 
 void ModSelector::onOverrideSliderChange(CBaseUISlider *slider) {
 void ModSelector::onOverrideSliderChange(CBaseUISlider *slider) {
@@ -1305,7 +1293,7 @@ void ModSelector::onOverrideSliderChange(CBaseUISlider *slider) {
                 m_overrideSliders[i].label->setWidthToContent(0);
                 m_overrideSliders[i].label->setWidthToContent(0);
 
 
                 // HACKHACK: dirty
                 // HACKHACK: dirty
-                if(m_osu->getSelectedBeatmap()->getSelectedDifficulty2() != NULL) {
+                if(osu->getSelectedBeatmap()->getSelectedDifficulty2() != NULL) {
                     if(m_overrideSliders[i].label->getName().find("BPM") != -1) {
                     if(m_overrideSliders[i].label->getName().find("BPM") != -1) {
                         // reset AR and OD override sliders if the bpm slider was reset
                         // reset AR and OD override sliders if the bpm slider was reset
                         if(!m_ARLock->isChecked()) m_ARSlider->setValue(0.0f, false);
                         if(!m_ARLock->isChecked()) m_ARSlider->setValue(0.0f, false);
@@ -1326,7 +1314,7 @@ void ModSelector::onOverrideSliderChange(CBaseUISlider *slider) {
                 }
                 }
 
 
                 // HACKHACK: dirty
                 // HACKHACK: dirty
-                if(m_osu->getSelectedBeatmap()->getSelectedDifficulty2() != NULL) {
+                if(osu->getSelectedBeatmap()->getSelectedDifficulty2() != NULL) {
                     if(m_overrideSliders[i].label->getName().find("BPM") != -1) {
                     if(m_overrideSliders[i].label->getName().find("BPM") != -1) {
                         // HACKHACK: force BPM slider to have a min value of 0.05 instead of 0 (because that's the
                         // HACKHACK: force BPM slider to have a min value of 0.05 instead of 0 (because that's the
                         // minimum for BASS) note that the BPM slider is just a 'fake' slider, it directly controls the
                         // minimum for BASS) note that the BPM slider is just a 'fake' slider, it directly controls the
@@ -1341,9 +1329,9 @@ void ModSelector::onOverrideSliderChange(CBaseUISlider *slider) {
 
 
                         // force change all other depending sliders
                         // force change all other depending sliders
                         const float newAR =
                         const float newAR =
-                            GameRules::getConstantApproachRateForSpeedMultiplier(m_osu->getSelectedBeatmap());
+                            GameRules::getConstantApproachRateForSpeedMultiplier(osu->getSelectedBeatmap());
                         const float newOD =
                         const float newOD =
-                            GameRules::getConstantOverallDifficultyForSpeedMultiplier(m_osu->getSelectedBeatmap());
+                            GameRules::getConstantOverallDifficultyForSpeedMultiplier(osu->getSelectedBeatmap());
 
 
                         m_ARSlider->setValue(newAR + 1.0f,
                         m_ARSlider->setValue(newAR + 1.0f,
                                              false);  // '+1' to compensate for turn-off area of the override sliders
                                              false);  // '+1' to compensate for turn-off area of the override sliders
@@ -1380,11 +1368,11 @@ void ModSelector::onOverrideSliderLockChange(CBaseUICheckbox *checkbox) {
             if(locked && !wasLocked) {
             if(locked && !wasLocked) {
                 if(checkbox == m_ARLock) {
                 if(checkbox == m_ARLock) {
                     if(m_ARSlider->getFloat() < 1.0f)
                     if(m_ARSlider->getFloat() < 1.0f)
-                        m_ARSlider->setValue(m_osu->getSelectedBeatmap()->getRawAR() + 1.0f,
+                        m_ARSlider->setValue(osu->getSelectedBeatmap()->getRawAR() + 1.0f,
                                              false);  // '+1' to compensate for turn-off area of the override sliders
                                              false);  // '+1' to compensate for turn-off area of the override sliders
                 } else if(checkbox == m_ODLock) {
                 } else if(checkbox == m_ODLock) {
                     if(m_ODSlider->getFloat() < 1.0f)
                     if(m_ODSlider->getFloat() < 1.0f)
-                        m_ODSlider->setValue(m_osu->getSelectedBeatmap()->getRawOD() + 1.0f,
+                        m_ODSlider->setValue(osu->getSelectedBeatmap()->getRawOD() + 1.0f,
                                              false);  // '+1' to compensate for turn-off area of the override sliders
                                              false);  // '+1' to compensate for turn-off area of the override sliders
                 }
                 }
             }
             }
@@ -1437,55 +1425,54 @@ UString ModSelector::getOverrideSliderLabelText(ModSelector::OVERRIDE_SLIDER s,
     float convarValue = s.cvar->getFloat();
     float convarValue = s.cvar->getFloat();
 
 
     UString newLabelText = s.label->getName();
     UString newLabelText = s.label->getName();
-    if(m_osu->getSelectedBeatmap()->getSelectedDifficulty2() != NULL) {
-        // used for compensating speed changing experimental mods (which cause m_osu->getSpeedMultiplier() !=
+    if(osu->getSelectedBeatmap()->getSelectedDifficulty2() != NULL) {
+        // used for compensating speed changing experimental mods (which cause osu->getSpeedMultiplier() !=
         // beatmap->getSpeedMultiplier()) to keep the AR/OD display correct
         // beatmap->getSpeedMultiplier()) to keep the AR/OD display correct
         const float speedMultiplierLive =
         const float speedMultiplierLive =
-            m_osu->isInPlayMode() ? m_osu->getSelectedBeatmap()->getSpeedMultiplier() : m_osu->getSpeedMultiplier();
+            osu->isInPlayMode() ? osu->getSelectedBeatmap()->getSpeedMultiplier() : osu->getSpeedMultiplier();
 
 
         // for relevant values (AR/OD), any non-1.0x speed multiplier should show the fractional parts caused by such a
         // for relevant values (AR/OD), any non-1.0x speed multiplier should show the fractional parts caused by such a
         // speed multiplier (same for non-1.0x difficulty multiplier)
         // speed multiplier (same for non-1.0x difficulty multiplier)
         const bool forceDisplayTwoDecimalDigits =
         const bool forceDisplayTwoDecimalDigits =
-            (speedMultiplierLive != 1.0f || m_osu->getDifficultyMultiplier() != 1.0f ||
-             m_osu->getCSDifficultyMultiplier() != 1.0f);
+            (speedMultiplierLive != 1.0f || osu->getDifficultyMultiplier() != 1.0f ||
+             osu->getCSDifficultyMultiplier() != 1.0f);
 
 
         // HACKHACK: dirty
         // HACKHACK: dirty
         bool wasSpeedSlider = false;
         bool wasSpeedSlider = false;
         float beatmapValue = 1.0f;
         float beatmapValue = 1.0f;
         if(s.label->getName().find("CS") != -1) {
         if(s.label->getName().find("CS") != -1) {
             beatmapValue = clamp<float>(
             beatmapValue = clamp<float>(
-                m_osu->getSelectedBeatmap()->getSelectedDifficulty2()->getCS() * m_osu->getCSDifficultyMultiplier(),
-                0.0f, 10.0f);
-            convarValue = m_osu->getSelectedBeatmap()->getCS();
+                osu->getSelectedBeatmap()->getSelectedDifficulty2()->getCS() * osu->getCSDifficultyMultiplier(), 0.0f,
+                10.0f);
+            convarValue = osu->getSelectedBeatmap()->getCS();
         } else if(s.label->getName().find("AR") != -1) {
         } else if(s.label->getName().find("AR") != -1) {
-            beatmapValue = active ? GameRules::getRawApproachRateForSpeedMultiplier(m_osu->getSelectedBeatmap())
-                                  : GameRules::getApproachRateForSpeedMultiplier(m_osu->getSelectedBeatmap());
+            beatmapValue = active ? GameRules::getRawApproachRateForSpeedMultiplier(osu->getSelectedBeatmap())
+                                  : GameRules::getApproachRateForSpeedMultiplier(osu->getSelectedBeatmap());
 
 
             // compensate and round
             // compensate and round
-            convarValue =
-                GameRules::getApproachRateForSpeedMultiplier(m_osu->getSelectedBeatmap(), speedMultiplierLive);
+            convarValue = GameRules::getApproachRateForSpeedMultiplier(osu->getSelectedBeatmap(), speedMultiplierLive);
             if(!engine->getKeyboard()->isAltDown() && !forceDisplayTwoDecimalDigits)
             if(!engine->getKeyboard()->isAltDown() && !forceDisplayTwoDecimalDigits)
                 convarValue = std::round(convarValue * 10.0f) / 10.0f;
                 convarValue = std::round(convarValue * 10.0f) / 10.0f;
             else
             else
                 convarValue = std::round(convarValue * 100.0f) / 100.0f;
                 convarValue = std::round(convarValue * 100.0f) / 100.0f;
         } else if(s.label->getName().find("OD") != -1) {
         } else if(s.label->getName().find("OD") != -1) {
-            beatmapValue = active ? GameRules::getRawOverallDifficultyForSpeedMultiplier(m_osu->getSelectedBeatmap())
-                                  : GameRules::getOverallDifficultyForSpeedMultiplier(m_osu->getSelectedBeatmap());
+            beatmapValue = active ? GameRules::getRawOverallDifficultyForSpeedMultiplier(osu->getSelectedBeatmap())
+                                  : GameRules::getOverallDifficultyForSpeedMultiplier(osu->getSelectedBeatmap());
 
 
             // compensate and round
             // compensate and round
             convarValue =
             convarValue =
-                GameRules::getOverallDifficultyForSpeedMultiplier(m_osu->getSelectedBeatmap(), speedMultiplierLive);
+                GameRules::getOverallDifficultyForSpeedMultiplier(osu->getSelectedBeatmap(), speedMultiplierLive);
             if(!engine->getKeyboard()->isAltDown() && !forceDisplayTwoDecimalDigits)
             if(!engine->getKeyboard()->isAltDown() && !forceDisplayTwoDecimalDigits)
                 convarValue = std::round(convarValue * 10.0f) / 10.0f;
                 convarValue = std::round(convarValue * 10.0f) / 10.0f;
             else
             else
                 convarValue = std::round(convarValue * 100.0f) / 100.0f;
                 convarValue = std::round(convarValue * 100.0f) / 100.0f;
         } else if(s.label->getName().find("HP") != -1) {
         } else if(s.label->getName().find("HP") != -1) {
             beatmapValue = clamp<float>(
             beatmapValue = clamp<float>(
-                m_osu->getSelectedBeatmap()->getSelectedDifficulty2()->getHP() * m_osu->getDifficultyMultiplier(), 0.0f,
+                osu->getSelectedBeatmap()->getSelectedDifficulty2()->getHP() * osu->getDifficultyMultiplier(), 0.0f,
                 10.0f);
                 10.0f);
-            convarValue = m_osu->getSelectedBeatmap()->getHP();
+            convarValue = osu->getSelectedBeatmap()->getHP();
         } else if(s.desc->getText().find("Speed") != -1) {
         } else if(s.desc->getText().find("Speed") != -1) {
-            beatmapValue = active ? m_osu->getRawSpeedMultiplier() : m_osu->getSpeedMultiplier();
+            beatmapValue = active ? osu->getRawSpeedMultiplier() : osu->getSpeedMultiplier();
 
 
             wasSpeedSlider = true;
             wasSpeedSlider = true;
             {
             {
@@ -1498,13 +1485,13 @@ UString ModSelector::getOverrideSliderLabelText(ModSelector::OVERRIDE_SLIDER s,
 
 
                 newLabelText.append("  (BPM: ");
                 newLabelText.append("  (BPM: ");
 
 
-                int minBPM = m_osu->getSelectedBeatmap()->getSelectedDifficulty2()->getMinBPM();
-                int maxBPM = m_osu->getSelectedBeatmap()->getSelectedDifficulty2()->getMaxBPM();
-                int mostCommonBPM = m_osu->getSelectedBeatmap()->getSelectedDifficulty2()->getMostCommonBPM();
-                int newMinBPM = minBPM * m_osu->getSpeedMultiplier();
-                int newMaxBPM = maxBPM * m_osu->getSpeedMultiplier();
-                int newMostCommonBPM = mostCommonBPM * m_osu->getSpeedMultiplier();
-                if(!active || m_osu->getSpeedMultiplier() == 1.0f) {
+                int minBPM = osu->getSelectedBeatmap()->getSelectedDifficulty2()->getMinBPM();
+                int maxBPM = osu->getSelectedBeatmap()->getSelectedDifficulty2()->getMaxBPM();
+                int mostCommonBPM = osu->getSelectedBeatmap()->getSelectedDifficulty2()->getMostCommonBPM();
+                int newMinBPM = minBPM * osu->getSpeedMultiplier();
+                int newMaxBPM = maxBPM * osu->getSpeedMultiplier();
+                int newMostCommonBPM = mostCommonBPM * osu->getSpeedMultiplier();
+                if(!active || osu->getSpeedMultiplier() == 1.0f) {
                     if(minBPM == maxBPM)
                     if(minBPM == maxBPM)
                         newLabelText.append(UString::format("%i", newMaxBPM));
                         newLabelText.append(UString::format("%i", newMaxBPM));
                     else
                     else
@@ -1555,8 +1542,8 @@ void ModSelector::onCheckboxChange(CBaseUICheckbox *checkbox) {
 
 
             // force mod update
             // force mod update
             {
             {
-                if(m_osu->isInPlayMode()) m_osu->getSelectedBeatmap()->onModUpdate();
-                m_osu->getSongBrowser()->recalculateStarsForSelectedBeatmap(true);
+                if(osu->isInPlayMode()) osu->getSelectedBeatmap()->onModUpdate();
+                osu->getSongBrowser()->recalculateStarsForSelectedBeatmap(true);
             }
             }
 
 
             break;
             break;

+ 2 - 14
src/App/Osu/ModSelector.h

@@ -1,16 +1,6 @@
-//================ Copyright (c) 2015, PG, All rights reserved. =================//
-//
-// Purpose:		difficulty modifier selection screen
-//
-// $NoKeywords: $osums
-//===============================================================================//
-
-#ifndef OSUMODSELECTOR_H
-#define OSUMODSELECTOR_H
-
+#pragma once
 #include "OsuScreen.h"
 #include "OsuScreen.h"
 
 
-class Osu;
 class SkinImage;
 class SkinImage;
 class SongBrowser;
 class SongBrowser;
 
 
@@ -31,7 +21,7 @@ class ConVar;
 
 
 class ModSelector : public OsuScreen {
 class ModSelector : public OsuScreen {
    public:
    public:
-    ModSelector(Osu *osu);
+    ModSelector();
     virtual ~ModSelector();
     virtual ~ModSelector();
 
 
     virtual void draw(Graphics *g);
     virtual void draw(Graphics *g);
@@ -172,5 +162,3 @@ class ModSelector : public OsuScreen {
     ConVar *m_osu_drain_type_ref;
     ConVar *m_osu_drain_type_ref;
     ConVar *m_osu_mod_touchdevice_ref;
     ConVar *m_osu_mod_touchdevice_ref;
 };
 };
-
-#endif

+ 7 - 14
src/App/Osu/NotificationOverlay.cpp

@@ -1,10 +1,3 @@
-//================ Copyright (c) 2016, PG, All rights reserved. =================//
-//
-// Purpose:		text bar overlay which can eat inputs (also used for key bindings)
-//
-// $NoKeywords: $osunot
-//===============================================================================//
-
 #include "NotificationOverlay.h"
 #include "NotificationOverlay.h"
 
 
 #include "AnimationHandler.h"
 #include "AnimationHandler.h"
@@ -16,7 +9,7 @@
 
 
 ConVar osu_notification_duration("osu_notification_duration", 1.25f, FCVAR_DEFAULT);
 ConVar osu_notification_duration("osu_notification_duration", 1.25f, FCVAR_DEFAULT);
 
 
-NotificationOverlay::NotificationOverlay(Osu *osu) : OsuScreen(osu) {
+NotificationOverlay::NotificationOverlay() : OsuScreen() {
     m_bWaitForKey = false;
     m_bWaitForKey = false;
     m_bWaitForKeyDisallowsLeftClick = false;
     m_bWaitForKeyDisallowsLeftClick = false;
     m_bConsumeNextChar = false;
     m_bConsumeNextChar = false;
@@ -29,7 +22,7 @@ void NotificationOverlay::draw(Graphics *g) {
     if(m_bWaitForKey) {
     if(m_bWaitForKey) {
         g->setColor(0x22ffffff);
         g->setColor(0x22ffffff);
         g->setAlpha((m_notification1.backgroundAnim / 0.5f) * 0.13f);
         g->setAlpha((m_notification1.backgroundAnim / 0.5f) * 0.13f);
-        g->fillRect(0, 0, m_osu->getScreenWidth(), m_osu->getScreenHeight());
+        g->fillRect(0, 0, osu->getScreenWidth(), osu->getScreenHeight());
     }
     }
 
 
     drawNotificationBackground(g, m_notification2);
     drawNotificationBackground(g, m_notification2);
@@ -39,7 +32,7 @@ void NotificationOverlay::draw(Graphics *g) {
 }
 }
 
 
 void NotificationOverlay::drawNotificationText(Graphics *g, NotificationOverlay::NOTIFICATION &n) {
 void NotificationOverlay::drawNotificationText(Graphics *g, NotificationOverlay::NOTIFICATION &n) {
-    McFont *font = m_osu->getSubTitleFont();
+    McFont *font = osu->getSubTitleFont();
     int height = font->getHeight() * 2;
     int height = font->getHeight() * 2;
     int stringWidth = font->getStringWidth(n.text);
     int stringWidth = font->getStringWidth(n.text);
 
 
@@ -47,8 +40,8 @@ void NotificationOverlay::drawNotificationText(Graphics *g, NotificationOverlay:
     {
     {
         g->setColor(0xff000000);
         g->setColor(0xff000000);
         g->setAlpha(n.alpha);
         g->setAlpha(n.alpha);
-        g->translate((int)(m_osu->getScreenWidth() / 2 - stringWidth / 2 + 1),
-                     (int)(m_osu->getScreenHeight() / 2 + font->getHeight() / 2 + n.fallAnim * height * 0.15f + 1));
+        g->translate((int)(osu->getScreenWidth() / 2 - stringWidth / 2 + 1),
+                     (int)(osu->getScreenHeight() / 2 + font->getHeight() / 2 + n.fallAnim * height * 0.15f + 1));
         g->drawString(font, n.text);
         g->drawString(font, n.text);
 
 
         g->setColor(n.textColor);
         g->setColor(n.textColor);
@@ -60,12 +53,12 @@ void NotificationOverlay::drawNotificationText(Graphics *g, NotificationOverlay:
 }
 }
 
 
 void NotificationOverlay::drawNotificationBackground(Graphics *g, NotificationOverlay::NOTIFICATION &n) {
 void NotificationOverlay::drawNotificationBackground(Graphics *g, NotificationOverlay::NOTIFICATION &n) {
-    McFont *font = m_osu->getSubTitleFont();
+    McFont *font = osu->getSubTitleFont();
     int height = font->getHeight() * 2 * n.backgroundAnim;
     int height = font->getHeight() * 2 * n.backgroundAnim;
 
 
     g->setColor(0xff000000);
     g->setColor(0xff000000);
     g->setAlpha(n.alpha * 0.75f);
     g->setAlpha(n.alpha * 0.75f);
-    g->fillRect(0, m_osu->getScreenHeight() / 2 - height / 2, m_osu->getScreenWidth(), height);
+    g->fillRect(0, osu->getScreenHeight() / 2 - height / 2, osu->getScreenWidth(), height);
 }
 }
 
 
 void NotificationOverlay::onKeyDown(KeyboardEvent &e) {
 void NotificationOverlay::onKeyDown(KeyboardEvent &e) {

+ 2 - 15
src/App/Osu/NotificationOverlay.h

@@ -1,18 +1,7 @@
-//================ Copyright (c) 2016, PG, All rights reserved. =================//
-//
-// Purpose:		text bar overlay which can eat inputs (also used for key bindings)
-//
-// $NoKeywords: $osunot
-//===============================================================================//
-
-#ifndef OSUNOTIFICATIONOVERLAY_H
-#define OSUNOTIFICATIONOVERLAY_H
-
+#pragma once
 #include "KeyboardEvent.h"
 #include "KeyboardEvent.h"
 #include "OsuScreen.h"
 #include "OsuScreen.h"
 
 
-class Osu;
-
 class NotificationOverlayKeyListener {
 class NotificationOverlayKeyListener {
    public:
    public:
     virtual ~NotificationOverlayKeyListener() { ; }
     virtual ~NotificationOverlayKeyListener() { ; }
@@ -21,7 +10,7 @@ class NotificationOverlayKeyListener {
 
 
 class NotificationOverlay : public OsuScreen {
 class NotificationOverlay : public OsuScreen {
    public:
    public:
-    NotificationOverlay(Osu *osu);
+    NotificationOverlay();
     virtual ~NotificationOverlay() { ; }
     virtual ~NotificationOverlay() { ; }
 
 
     virtual void draw(Graphics *g);
     virtual void draw(Graphics *g);
@@ -65,5 +54,3 @@ class NotificationOverlay : public OsuScreen {
     bool m_bConsumeNextChar;
     bool m_bConsumeNextChar;
     NotificationOverlayKeyListener *m_keyListener;
     NotificationOverlayKeyListener *m_keyListener;
 };
 };
-
-#endif

+ 113 - 137
src/App/Osu/OptionsMenu.cpp

@@ -1,10 +1,3 @@
-//================ Copyright (c) 2016, PG, All rights reserved. =================//
-//
-// Purpose:		settings
-//
-// $NoKeywords: $
-//===============================================================================//
-
 #include "OptionsMenu.h"
 #include "OptionsMenu.h"
 
 
 #include <fstream>
 #include <fstream>
@@ -64,16 +57,15 @@ const char *OptionsMenu::OSU_CONFIG_FILE_NAME = "";  // set dynamically below in
 
 
 class OptionsMenuSkinPreviewElement : public CBaseUIElement {
 class OptionsMenuSkinPreviewElement : public CBaseUIElement {
    public:
    public:
-    OptionsMenuSkinPreviewElement(Osu *osu, float xPos, float yPos, float xSize, float ySize, UString name)
+    OptionsMenuSkinPreviewElement(float xPos, float yPos, float xSize, float ySize, UString name)
         : CBaseUIElement(xPos, yPos, xSize, ySize, name) {
         : CBaseUIElement(xPos, yPos, xSize, ySize, name) {
-        m_osu = osu;
         m_iMode = 0;
         m_iMode = 0;
     }
     }
 
 
     virtual void draw(Graphics *g) {
     virtual void draw(Graphics *g) {
         if(!m_bVisible) return;
         if(!m_bVisible) return;
 
 
-        Skin *skin = m_osu->getSkin();
+        Skin *skin = osu->getSkin();
 
 
         float hitcircleDiameter = m_vSize.y * 0.5f;
         float hitcircleDiameter = m_vSize.y * 0.5f;
         float numberScale = (hitcircleDiameter / (160.0f * (skin->isDefault12x() ? 2.0f : 1.0f))) * 1 *
         float numberScale = (hitcircleDiameter / (160.0f * (skin->isDefault12x() ? 2.0f : 1.0f))) * 1 *
@@ -95,22 +87,22 @@ class OptionsMenuSkinPreviewElement : public CBaseUIElement {
             const int colorOffset = 0;
             const int colorOffset = 0;
             const float colorRGBMultiplier = 1.0f;
             const float colorRGBMultiplier = 1.0f;
 
 
-            Circle::drawCircle(g, m_osu->getSkin(),
+            Circle::drawCircle(g, osu->getSkin(),
                                m_vPos + Vector2(0, m_vSize.y / 2) + Vector2(m_vSize.x * (1.0f / 5.0f), 0.0f),
                                m_vPos + Vector2(0, m_vSize.y / 2) + Vector2(m_vSize.x * (1.0f / 5.0f), 0.0f),
                                hitcircleDiameter, numberScale, overlapScale, number, colorCounter, colorOffset,
                                hitcircleDiameter, numberScale, overlapScale, number, colorCounter, colorOffset,
                                colorRGBMultiplier, approachScale, approachAlpha, approachAlpha, true, false);
                                colorRGBMultiplier, approachScale, approachAlpha, approachAlpha, true, false);
-            Circle::drawHitResult(g, m_osu->getSkin(), hitcircleDiameter, hitcircleDiameter,
+            Circle::drawHitResult(g, osu->getSkin(), hitcircleDiameter, hitcircleDiameter,
                                   m_vPos + Vector2(0, m_vSize.y / 2) + Vector2(m_vSize.x * (2.0f / 5.0f), 0.0f),
                                   m_vPos + Vector2(0, m_vSize.y / 2) + Vector2(m_vSize.x * (2.0f / 5.0f), 0.0f),
                                   LiveScore::HIT::HIT_100, 0.45f, 0.33f);
                                   LiveScore::HIT::HIT_100, 0.45f, 0.33f);
-            Circle::drawHitResult(g, m_osu->getSkin(), hitcircleDiameter, hitcircleDiameter,
+            Circle::drawHitResult(g, osu->getSkin(), hitcircleDiameter, hitcircleDiameter,
                                   m_vPos + Vector2(0, m_vSize.y / 2) + Vector2(m_vSize.x * (3.0f / 5.0f), 0.0f),
                                   m_vPos + Vector2(0, m_vSize.y / 2) + Vector2(m_vSize.x * (3.0f / 5.0f), 0.0f),
                                   LiveScore::HIT::HIT_50, 0.45f, 0.66f);
                                   LiveScore::HIT::HIT_50, 0.45f, 0.66f);
-            Circle::drawHitResult(g, m_osu->getSkin(), hitcircleDiameter, hitcircleDiameter,
+            Circle::drawHitResult(g, osu->getSkin(), hitcircleDiameter, hitcircleDiameter,
                                   m_vPos + Vector2(0, m_vSize.y / 2) + Vector2(m_vSize.x * (4.0f / 5.0f), 0.0f),
                                   m_vPos + Vector2(0, m_vSize.y / 2) + Vector2(m_vSize.x * (4.0f / 5.0f), 0.0f),
                                   LiveScore::HIT::HIT_MISS, 0.45f, 1.0f);
                                   LiveScore::HIT::HIT_MISS, 0.45f, 1.0f);
-            Circle::drawApproachCircle(g, m_osu->getSkin(),
+            Circle::drawApproachCircle(g, osu->getSkin(),
                                        m_vPos + Vector2(0, m_vSize.y / 2) + Vector2(m_vSize.x * (1.0f / 5.0f), 0.0f),
                                        m_vPos + Vector2(0, m_vSize.y / 2) + Vector2(m_vSize.x * (1.0f / 5.0f), 0.0f),
-                                       m_osu->getSkin()->getComboColorForCounter(colorCounter, colorOffset),
+                                       osu->getSkin()->getComboColorForCounter(colorCounter, colorOffset),
                                        hitcircleDiameter, approachScale, approachCircleAlpha, false, false);
                                        hitcircleDiameter, approachScale, approachCircleAlpha, false, false);
         } else if(m_iMode == 1) {
         } else if(m_iMode == 1) {
             const int numNumbers = 6;
             const int numNumbers = 6;
@@ -129,7 +121,7 @@ class OptionsMenuSkinPreviewElement : public CBaseUIElement {
                 g->pushTransform();
                 g->pushTransform();
                 g->scale(scoreScale, scoreScale);
                 g->scale(scoreScale, scoreScale);
                 g->translate(pos.x - skin->getScore0()->getWidth() * scoreScale, pos.y);
                 g->translate(pos.x - skin->getScore0()->getWidth() * scoreScale, pos.y);
-                m_osu->getHUD()->drawScoreNumber(g, i - 1, 1.0f);
+                osu->getHUD()->drawScoreNumber(g, i - 1, 1.0f);
                 g->popTransform();
                 g->popTransform();
             }
             }
         }
         }
@@ -141,15 +133,13 @@ class OptionsMenuSkinPreviewElement : public CBaseUIElement {
     }
     }
 
 
    private:
    private:
-    Osu *m_osu;
     int m_iMode;
     int m_iMode;
 };
 };
 
 
 class OptionsMenuSliderPreviewElement : public CBaseUIElement {
 class OptionsMenuSliderPreviewElement : public CBaseUIElement {
    public:
    public:
-    OptionsMenuSliderPreviewElement(Osu *osu, float xPos, float yPos, float xSize, float ySize, UString name)
+    OptionsMenuSliderPreviewElement(float xPos, float yPos, float xSize, float ySize, UString name)
         : CBaseUIElement(xPos, yPos, xSize, ySize, name) {
         : CBaseUIElement(xPos, yPos, xSize, ySize, name) {
-        m_osu = osu;
         m_bDrawSliderHack = true;
         m_bDrawSliderHack = true;
         m_fPrevLength = 0.0f;
         m_fPrevLength = 0.0f;
         m_vao = NULL;
         m_vao = NULL;
@@ -166,8 +156,8 @@ class OptionsMenuSliderPreviewElement : public CBaseUIElement {
         */
         */
 
 
         const float hitcircleDiameter = m_vSize.y * 0.5f;
         const float hitcircleDiameter = m_vSize.y * 0.5f;
-        const float numberScale = (hitcircleDiameter / (160.0f * (m_osu->getSkin()->isDefault12x() ? 2.0f : 1.0f))) *
-                                  1 * convar->getConVarByName("osu_number_scale_multiplier")->getFloat();
+        const float numberScale = (hitcircleDiameter / (160.0f * (osu->getSkin()->isDefault12x() ? 2.0f : 1.0f))) * 1 *
+                                  convar->getConVarByName("osu_number_scale_multiplier")->getFloat();
         const float overlapScale =
         const float overlapScale =
             (hitcircleDiameter / (160.0f)) * 1 * convar->getConVarByName("osu_number_scale_multiplier")->getFloat();
             (hitcircleDiameter / (160.0f)) * 1 * convar->getConVarByName("osu_number_scale_multiplier")->getFloat();
 
 
@@ -212,13 +202,13 @@ class OptionsMenuSliderPreviewElement : public CBaseUIElement {
                 const int colorOffset = 0;
                 const int colorOffset = 0;
                 const float colorRGBMultiplier = 1.0f;
                 const float colorRGBMultiplier = 1.0f;
 
 
-                Circle::drawCircle(g, m_osu->getSkin(),
+                Circle::drawCircle(g, osu->getSkin(),
                                    points[numPoints / 2] + (!useLegacyRenderer ? m_vPos : Vector2(0, 0)),
                                    points[numPoints / 2] + (!useLegacyRenderer ? m_vPos : Vector2(0, 0)),
                                    hitcircleDiameter, numberScale, overlapScale, number, colorCounter, colorOffset,
                                    hitcircleDiameter, numberScale, overlapScale, number, colorCounter, colorOffset,
                                    colorRGBMultiplier, approachScale, approachAlpha, approachAlpha, true, false);
                                    colorRGBMultiplier, approachScale, approachAlpha, approachAlpha, true, false);
-                Circle::drawApproachCircle(g, m_osu->getSkin(),
+                Circle::drawApproachCircle(g, osu->getSkin(),
                                            points[numPoints / 2] + (!useLegacyRenderer ? m_vPos : Vector2(0, 0)),
                                            points[numPoints / 2] + (!useLegacyRenderer ? m_vPos : Vector2(0, 0)),
-                                           m_osu->getSkin()->getComboColorForCounter(420, 0), hitcircleDiameter,
+                                           osu->getSkin()->getComboColorForCounter(420, 0), hitcircleDiameter,
                                            approachScale, approachCircleAlpha, false, false);
                                            approachScale, approachCircleAlpha, false, false);
             }
             }
 
 
@@ -228,8 +218,8 @@ class OptionsMenuSliderPreviewElement : public CBaseUIElement {
                 // the options menu is animating
                 // the options menu is animating
                 if(m_bDrawSliderHack) {
                 if(m_bDrawSliderHack) {
                     if(useLegacyRenderer)
                     if(useLegacyRenderer)
-                        SliderRenderer::draw(g, m_osu, points, emptyVector, hitcircleDiameter, 0, 1,
-                                             m_osu->getSkin()->getComboColorForCounter(420, 0));
+                        SliderRenderer::draw(g, points, emptyVector, hitcircleDiameter, 0, 1,
+                                             osu->getSkin()->getComboColorForCounter(420, 0));
                     else {
                     else {
                         // (lazy generate vao)
                         // (lazy generate vao)
                         if(m_vao == NULL || length != m_fPrevLength) {
                         if(m_vao == NULL || length != m_fPrevLength) {
@@ -243,11 +233,10 @@ class OptionsMenuSliderPreviewElement : public CBaseUIElement {
                             }
                             }
 
 
                             if(m_vao == NULL)
                             if(m_vao == NULL)
-                                m_vao = SliderRenderer::generateVAO(m_osu, points, hitcircleDiameter, Vector3(0, 0, 0),
-                                                                    false);
+                                m_vao = SliderRenderer::generateVAO(points, hitcircleDiameter, Vector3(0, 0, 0), false);
                         }
                         }
-                        SliderRenderer::draw(g, m_osu, m_vao, emptyVector, m_vPos, 1, hitcircleDiameter, 0, 1,
-                                             m_osu->getSkin()->getComboColorForCounter(420, 0));
+                        SliderRenderer::draw(g, m_vao, emptyVector, m_vPos, 1, hitcircleDiameter, 0, 1,
+                                             osu->getSkin()->getComboColorForCounter(420, 0));
                     }
                     }
                 }
                 }
             }
             }
@@ -260,9 +249,9 @@ class OptionsMenuSliderPreviewElement : public CBaseUIElement {
                 const float colorRGBMultiplier = 1.0f;
                 const float colorRGBMultiplier = 1.0f;
 
 
                 Circle::drawSliderStartCircle(
                 Circle::drawSliderStartCircle(
-                    g, m_osu->getSkin(), points[0] + (!useLegacyRenderer ? m_vPos : Vector2(0, 0)), hitcircleDiameter,
+                    g, osu->getSkin(), points[0] + (!useLegacyRenderer ? m_vPos : Vector2(0, 0)), hitcircleDiameter,
                     numberScale, overlapScale, number, colorCounter, colorOffset, colorRGBMultiplier);
                     numberScale, overlapScale, number, colorCounter, colorOffset, colorRGBMultiplier);
-                Circle::drawSliderEndCircle(g, m_osu->getSkin(),
+                Circle::drawSliderEndCircle(g, osu->getSkin(),
                                             points[points.size() - 1] + (!useLegacyRenderer ? m_vPos : Vector2(0, 0)),
                                             points[points.size() - 1] + (!useLegacyRenderer ? m_vPos : Vector2(0, 0)),
                                             hitcircleDiameter, numberScale, overlapScale, number, colorCounter,
                                             hitcircleDiameter, numberScale, overlapScale, number, colorCounter,
                                             colorOffset, colorRGBMultiplier, 1.0f, 1.0f, 0.0f, false, false);
                                             colorOffset, colorRGBMultiplier, 1.0f, 1.0f, 0.0f, false, false);
@@ -273,7 +262,6 @@ class OptionsMenuSliderPreviewElement : public CBaseUIElement {
     void setDrawSliderHack(bool drawSliderHack) { m_bDrawSliderHack = drawSliderHack; }
     void setDrawSliderHack(bool drawSliderHack) { m_bDrawSliderHack = drawSliderHack; }
 
 
    private:
    private:
-    Osu *m_osu;
     bool m_bDrawSliderHack;
     bool m_bDrawSliderHack;
     VertexArrayObject *m_vao;
     VertexArrayObject *m_vao;
     float m_fPrevLength;
     float m_fPrevLength;
@@ -331,8 +319,8 @@ class OptionsMenuKeyBindLabel : public CBaseUILabel {
 
 
 class OptionsMenuKeyBindButton : public UIButton {
 class OptionsMenuKeyBindButton : public UIButton {
    public:
    public:
-    OptionsMenuKeyBindButton(Osu *osu, float xPos, float yPos, float xSize, float ySize, UString name, UString text)
-        : UIButton(osu, xPos, yPos, xSize, ySize, name, text) {
+    OptionsMenuKeyBindButton(float xPos, float yPos, float xSize, float ySize, UString name, UString text)
+        : UIButton(xPos, yPos, xSize, ySize, name, text) {
         m_bDisallowLeftMouseClickBinding = false;
         m_bDisallowLeftMouseClickBinding = false;
     }
     }
 
 
@@ -384,9 +372,8 @@ class OptionsMenuCategoryButton : public CBaseUIButton {
 
 
 class OptionsMenuResetButton : public CBaseUIButton {
 class OptionsMenuResetButton : public CBaseUIButton {
    public:
    public:
-    OptionsMenuResetButton(Osu *osu, float xPos, float yPos, float xSize, float ySize, UString name, UString text)
+    OptionsMenuResetButton(float xPos, float yPos, float xSize, float ySize, UString name, UString text)
         : CBaseUIButton(xPos, yPos, xSize, ySize, name, text) {
         : CBaseUIButton(xPos, yPos, xSize, ySize, name, text) {
-        m_osu = osu;
         m_fAnim = 1.0f;
         m_fAnim = 1.0f;
     }
     }
 
 
@@ -395,7 +382,7 @@ class OptionsMenuResetButton : public CBaseUIButton {
     virtual void draw(Graphics *g) {
     virtual void draw(Graphics *g) {
         if(!m_bVisible || m_fAnim <= 0.0f) return;
         if(!m_bVisible || m_fAnim <= 0.0f) return;
 
 
-        const int fullColorBlockSize = 4 * Osu::getUIScale(m_osu);
+        const int fullColorBlockSize = 4 * Osu::getUIScale();
 
 
         Color left = COLOR((int)(255 * m_fAnim), 255, 233, 50);
         Color left = COLOR((int)(255 * m_fAnim), 255, 233, 50);
         Color middle = COLOR((int)(255 * m_fAnim), 255, 211, 50);
         Color middle = COLOR((int)(255 * m_fAnim), 255, 211, 50);
@@ -410,9 +397,9 @@ class OptionsMenuResetButton : public CBaseUIButton {
         CBaseUIButton::mouse_update(propagate_clicks);
         CBaseUIButton::mouse_update(propagate_clicks);
 
 
         if(isMouseInside()) {
         if(isMouseInside()) {
-            m_osu->getTooltipOverlay()->begin();
-            { m_osu->getTooltipOverlay()->addLine("Reset"); }
-            m_osu->getTooltipOverlay()->end();
+            osu->getTooltipOverlay()->begin();
+            { osu->getTooltipOverlay()->addLine("Reset"); }
+            osu->getTooltipOverlay()->end();
         }
         }
     }
     }
 
 
@@ -427,13 +414,10 @@ class OptionsMenuResetButton : public CBaseUIButton {
         anim->moveQuadOut(&m_fAnim, 0.0f, m_fAnim * 0.15f, true);
         anim->moveQuadOut(&m_fAnim, 0.0f, m_fAnim * 0.15f, true);
     }
     }
 
 
-    Osu *m_osu;
     float m_fAnim;
     float m_fAnim;
 };
 };
 
 
-OptionsMenu::OptionsMenu(Osu *osu) : ScreenBackable(osu) {
-    m_osu = osu;
-
+OptionsMenu::OptionsMenu() : ScreenBackable() {
     m_bFullscreen = false;
     m_bFullscreen = false;
     m_fAnimation = 0.0f;
     m_fAnimation = 0.0f;
 
 
@@ -461,7 +445,7 @@ OptionsMenu::OptionsMenu(Osu *osu) : ScreenBackable(osu) {
 
 
     OSU_CONFIG_FILE_NAME = "osu";
     OSU_CONFIG_FILE_NAME = "osu";
 
 
-    m_osu->getNotificationOverlay()->addKeyListener(this);
+    osu->getNotificationOverlay()->addKeyListener(this);
 
 
     m_waitingKey = NULL;
     m_waitingKey = NULL;
     m_resolutionLabel = NULL;
     m_resolutionLabel = NULL;
@@ -530,9 +514,9 @@ OptionsMenu::OptionsMenu(Osu *osu) : ScreenBackable(osu) {
     m_categories->setScrollResistance(30);  // since all categories are always visible anyway
     m_categories->setScrollResistance(30);  // since all categories are always visible anyway
     addBaseUIElement(m_categories);
     addBaseUIElement(m_categories);
 
 
-    m_contextMenu = new UIContextMenu(m_osu, 50, 50, 150, 0, "", m_options);
+    m_contextMenu = new UIContextMenu(50, 50, 150, 0, "", m_options);
 
 
-    m_search = new UISearchOverlay(m_osu, 0, 0, 0, 0, "");
+    m_search = new UISearchOverlay(0, 0, 0, 0, "");
     m_search->setOffsetRight(20);
     m_search->setOffsetRight(20);
     addBaseUIElement(m_search);
     addBaseUIElement(m_search);
 
 
@@ -630,7 +614,7 @@ OptionsMenu::OptionsMenu(Osu *osu) : ScreenBackable(osu) {
 
 
     addSubSection("Layout");
     addSubSection("Layout");
     OPTIONS_ELEMENT resolutionSelect =
     OPTIONS_ELEMENT resolutionSelect =
-        addButton("Select Resolution", UString::format("%ix%i", m_osu->getScreenWidth(), m_osu->getScreenHeight()));
+        addButton("Select Resolution", UString::format("%ix%i", osu->getScreenWidth(), osu->getScreenHeight()));
     m_resolutionSelectButton = (CBaseUIButton *)resolutionSelect.elements[0];
     m_resolutionSelectButton = (CBaseUIButton *)resolutionSelect.elements[0];
     m_resolutionSelectButton->setClickCallback(fastdelegate::MakeDelegate(this, &OptionsMenu::onResolutionSelect));
     m_resolutionSelectButton->setClickCallback(fastdelegate::MakeDelegate(this, &OptionsMenu::onResolutionSelect));
     m_resolutionLabel = (CBaseUILabel *)resolutionSelect.elements[1];
     m_resolutionLabel = (CBaseUILabel *)resolutionSelect.elements[1];
@@ -1408,12 +1392,12 @@ void OptionsMenu::draw(Graphics *g) {
     m_sliderPreviewElement->setDrawSliderHack(!isAnimating);
     m_sliderPreviewElement->setDrawSliderHack(!isAnimating);
 
 
     if(isAnimating) {
     if(isAnimating) {
-        m_osu->getSliderFrameBuffer()->enable();
+        osu->getSliderFrameBuffer()->enable();
 
 
         g->setBlendMode(Graphics::BLEND_MODE::BLEND_MODE_PREMUL_ALPHA);
         g->setBlendMode(Graphics::BLEND_MODE::BLEND_MODE_PREMUL_ALPHA);
     }
     }
 
 
-    const bool isPlayingBeatmap = m_osu->isInPlayMode();
+    const bool isPlayingBeatmap = osu->isInPlayMode();
 
 
     // interactive sliders
     // interactive sliders
 
 
@@ -1425,7 +1409,7 @@ void OptionsMenu::draw(Graphics *g) {
             const short blue = clamp<float>(brightness * m_osu_background_color_b_ref->getFloat(), 0.0f, 255.0f);
             const short blue = clamp<float>(brightness * m_osu_background_color_b_ref->getFloat(), 0.0f, 255.0f);
             if(brightness > 0.0f) {
             if(brightness > 0.0f) {
                 g->setColor(COLOR(255, red, green, blue));
                 g->setColor(COLOR(255, red, green, blue));
-                g->fillRect(0, 0, m_osu->getScreenWidth(), m_osu->getScreenHeight());
+                g->fillRect(0, 0, osu->getScreenWidth(), osu->getScreenHeight());
             }
             }
         }
         }
     }
     }
@@ -1434,7 +1418,7 @@ void OptionsMenu::draw(Graphics *g) {
         if(!isPlayingBeatmap) {
         if(!isPlayingBeatmap) {
             const short dim = clamp<float>(m_backgroundDimSlider->getFloat(), 0.0f, 1.0f) * 255.0f;
             const short dim = clamp<float>(m_backgroundDimSlider->getFloat(), 0.0f, 1.0f) * 255.0f;
             g->setColor(COLOR(dim, 0, 0, 0));
             g->setColor(COLOR(dim, 0, 0, 0));
-            g->fillRect(0, 0, m_osu->getScreenWidth(), m_osu->getScreenHeight());
+            g->fillRect(0, 0, osu->getScreenWidth(), osu->getScreenHeight());
         }
         }
     }
     }
 
 
@@ -1446,10 +1430,9 @@ void OptionsMenu::draw(Graphics *g) {
        m_hudScoreBarScaleSlider->isActive() || m_hudScoreBoardScaleSlider->isActive() ||
        m_hudScoreBarScaleSlider->isActive() || m_hudScoreBoardScaleSlider->isActive() ||
        m_hudInputoverlayScaleSlider->isActive() || m_statisticsOverlayScaleSlider->isActive() ||
        m_hudInputoverlayScaleSlider->isActive() || m_statisticsOverlayScaleSlider->isActive() ||
        m_statisticsOverlayXOffsetSlider->isActive() || m_statisticsOverlayYOffsetSlider->isActive()) {
        m_statisticsOverlayXOffsetSlider->isActive() || m_statisticsOverlayYOffsetSlider->isActive()) {
-        if(!isPlayingBeatmap) m_osu->getHUD()->drawDummy(g);
+        if(!isPlayingBeatmap) osu->getHUD()->drawDummy(g);
     } else if(m_playfieldBorderSizeSlider->isActive()) {
     } else if(m_playfieldBorderSizeSlider->isActive()) {
-        m_osu->getHUD()->drawPlayfieldBorder(g, GameRules::getPlayfieldCenter(m_osu),
-                                             GameRules::getPlayfieldSize(m_osu), 100);
+        osu->getHUD()->drawPlayfieldBorder(g, GameRules::getPlayfieldCenter(), GameRules::getPlayfieldSize(), 100);
     } else
     } else
         ScreenBackable::draw(g);
         ScreenBackable::draw(g);
 
 
@@ -1461,7 +1444,7 @@ void OptionsMenu::draw(Graphics *g) {
 
 
         g->setBlendMode(Graphics::BLEND_MODE::BLEND_MODE_ALPHA);
         g->setBlendMode(Graphics::BLEND_MODE::BLEND_MODE_ALPHA);
 
 
-        m_osu->getSliderFrameBuffer()->disable();
+        osu->getSliderFrameBuffer()->disable();
 
 
         g->push3DScene(McRect(0, 0, m_options->getSize().x, m_options->getSize().y));
         g->push3DScene(McRect(0, 0, m_options->getSize().x, m_options->getSize().y));
         {
         {
@@ -1469,8 +1452,8 @@ void OptionsMenu::draw(Graphics *g) {
             g->translate3DScene(-(1.0f - m_fAnimation) * m_options->getSize().x * 1.25f, 0,
             g->translate3DScene(-(1.0f - m_fAnimation) * m_options->getSize().x * 1.25f, 0,
                                 -(1.0f - m_fAnimation) * 700);
                                 -(1.0f - m_fAnimation) * 700);
 
 
-            m_osu->getSliderFrameBuffer()->setColor(COLORf(m_fAnimation, 1.0f, 1.0f, 1.0f));
-            m_osu->getSliderFrameBuffer()->draw(g, 0, 0);
+            osu->getSliderFrameBuffer()->setColor(COLORf(m_fAnimation, 1.0f, 1.0f, 1.0f));
+            osu->getSliderFrameBuffer()->draw(g, 0, 0);
         }
         }
         g->pop3DScene();
         g->pop3DScene();
     }
     }
@@ -1488,7 +1471,7 @@ void OptionsMenu::mouse_update(bool *propagate_clicks) {
 
 
     if(m_bDPIScalingScrollToSliderScheduled) {
     if(m_bDPIScalingScrollToSliderScheduled) {
         m_bDPIScalingScrollToSliderScheduled = false;
         m_bDPIScalingScrollToSliderScheduled = false;
-        m_options->scrollToElement(m_uiScaleSlider, 0, 200 * Osu::getUIScale(m_osu));
+        m_options->scrollToElement(m_uiScaleSlider, 0, 200 * Osu::getUIScale());
     }
     }
 
 
     // flash osu!folder textbox red if incorrect
     // flash osu!folder textbox red if incorrect
@@ -1499,7 +1482,7 @@ void OptionsMenu::mouse_update(bool *propagate_clicks) {
         m_osuFolderTextbox->setBackgroundColor(0xff000000);
         m_osuFolderTextbox->setBackgroundColor(0xff000000);
 
 
     // hack to avoid entering search text while binding keys
     // hack to avoid entering search text while binding keys
-    if(m_osu->getNotificationOverlay()->isVisible() && m_osu->getNotificationOverlay()->isWaitingForKey())
+    if(osu->getNotificationOverlay()->isVisible() && osu->getNotificationOverlay()->isWaitingForKey())
         m_fSearchOnCharKeybindHackTime = engine->getTime() + 0.1f;
         m_fSearchOnCharKeybindHackTime = engine->getTime() + 0.1f;
 
 
     // highlight active category depending on scroll position
     // highlight active category depending on scroll position
@@ -1536,7 +1519,7 @@ void OptionsMenu::mouse_update(bool *propagate_clicks) {
 
 
     if(m_bUIScaleScrollToSliderScheduled) {
     if(m_bUIScaleScrollToSliderScheduled) {
         m_bUIScaleScrollToSliderScheduled = false;
         m_bUIScaleScrollToSliderScheduled = false;
-        m_options->scrollToElement(m_uiScaleSlider, 0, 200 * Osu::getUIScale(m_osu));
+        m_options->scrollToElement(m_uiScaleSlider, 0, 200 * Osu::getUIScale());
     }
     }
 
 
     // delayed UI scale change
     // delayed UI scale change
@@ -1544,11 +1527,11 @@ void OptionsMenu::mouse_update(bool *propagate_clicks) {
         if(!m_uiScaleSlider->isActive()) {
         if(!m_uiScaleSlider->isActive()) {
             m_bUIScaleChangeScheduled = false;
             m_bUIScaleChangeScheduled = false;
 
 
-            const float oldUIScale = Osu::getUIScale(m_osu);
+            const float oldUIScale = Osu::getUIScale();
 
 
             m_osu_ui_scale_ref->setValue(m_uiScaleSlider->getFloat());
             m_osu_ui_scale_ref->setValue(m_uiScaleSlider->getFloat());
 
 
-            const float newUIScale = Osu::getUIScale(m_osu);
+            const float newUIScale = Osu::getUIScale();
 
 
             // and update reset buttons as usual
             // and update reset buttons as usual
             onResetUpdate(m_uiScaleResetButton);
             onResetUpdate(m_uiScaleResetButton);
@@ -1750,13 +1733,13 @@ void OptionsMenu::setVisibleInt(bool visible, bool fromOnBack) {
 
 
         // save even if not closed via onBack(), e.g. if closed via setVisible(false) from outside
         // save even if not closed via onBack(), e.g. if closed via setVisible(false) from outside
         if(!visible && !fromOnBack) {
         if(!visible && !fromOnBack) {
-            m_osu->getNotificationOverlay()->stopWaitingForKey();
+            osu->getNotificationOverlay()->stopWaitingForKey();
             save();
             save();
         }
         }
     }
     }
 
 
     m_bVisible = visible;
     m_bVisible = visible;
-    m_osu->m_chat->updateVisibility();
+    osu->m_chat->updateVisibility();
 
 
     if(visible)
     if(visible)
         updateLayout();
         updateLayout();
@@ -1768,7 +1751,7 @@ void OptionsMenu::setVisibleInt(bool visible, bool fromOnBack) {
     }
     }
 
 
     // usability: auto scroll to fposu settings if opening options while in fposu gamemode
     // usability: auto scroll to fposu settings if opening options while in fposu gamemode
-    if(visible && m_osu->isInPlayMode() && m_osu_mod_fposu_ref->getBool() && !m_fposuCategoryButton->isActiveCategory())
+    if(visible && osu->isInPlayMode() && m_osu_mod_fposu_ref->getBool() && !m_fposuCategoryButton->isActiveCategory())
         onCategoryClicked(m_fposuCategoryButton);
         onCategoryClicked(m_fposuCategoryButton);
 
 
     if(visible) {
     if(visible) {
@@ -1857,29 +1840,29 @@ void OptionsMenu::updateLayout() {
 
 
     ScreenBackable::updateLayout();
     ScreenBackable::updateLayout();
 
 
-    const float dpiScale = Osu::getUIScale(m_osu);
+    const float dpiScale = Osu::getUIScale();
 
 
-    setSize(m_osu->getScreenSize());
+    setSize(osu->getScreenSize());
 
 
     // options panel
     // options panel
     const float optionsScreenWidthPercent = 0.5f;
     const float optionsScreenWidthPercent = 0.5f;
     const float categoriesOptionsPercent = 0.135f;
     const float categoriesOptionsPercent = 0.135f;
 
 
-    int optionsWidth = (int)(m_osu->getScreenWidth() * optionsScreenWidthPercent);
+    int optionsWidth = (int)(osu->getScreenWidth() * optionsScreenWidthPercent);
     if(!m_bFullscreen)
     if(!m_bFullscreen)
         optionsWidth = std::min((int)(725.0f * (1.0f - categoriesOptionsPercent)), optionsWidth) * dpiScale;
         optionsWidth = std::min((int)(725.0f * (1.0f - categoriesOptionsPercent)), optionsWidth) * dpiScale;
 
 
     const int categoriesWidth = optionsWidth * categoriesOptionsPercent;
     const int categoriesWidth = optionsWidth * categoriesOptionsPercent;
 
 
-    m_options->setRelPosX((!m_bFullscreen ? -1 : m_osu->getScreenWidth() / 2 - (optionsWidth + categoriesWidth) / 2) +
+    m_options->setRelPosX((!m_bFullscreen ? -1 : osu->getScreenWidth() / 2 - (optionsWidth + categoriesWidth) / 2) +
                           categoriesWidth);
                           categoriesWidth);
-    m_options->setSize(optionsWidth, m_osu->getScreenHeight() + 1);
+    m_options->setSize(optionsWidth, osu->getScreenHeight() + 1);
 
 
     m_search->setRelPos(m_options->getRelPos());
     m_search->setRelPos(m_options->getRelPos());
     m_search->setSize(m_options->getSize());
     m_search->setSize(m_options->getSize());
 
 
     m_categories->setRelPosX(m_options->getRelPos().x - categoriesWidth);
     m_categories->setRelPosX(m_options->getRelPos().x - categoriesWidth);
-    m_categories->setSize(categoriesWidth, m_osu->getScreenHeight() + 1);
+    m_categories->setSize(categoriesWidth, osu->getScreenHeight() + 1);
 
 
     // reset
     // reset
     m_options->getContainer()->empty();
     m_options->getContainer()->empty();
@@ -2227,13 +2210,13 @@ void OptionsMenu::updateLayout() {
 }
 }
 
 
 void OptionsMenu::onBack() {
 void OptionsMenu::onBack() {
-    m_osu->getNotificationOverlay()->stopWaitingForKey();
+    osu->getNotificationOverlay()->stopWaitingForKey();
 
 
-    engine->getSound()->play(m_osu->getSkin()->getMenuClick());
+    engine->getSound()->play(osu->getSkin()->getMenuClick());
     save();
     save();
 
 
     if(m_bFullscreen)
     if(m_bFullscreen)
-        m_osu->toggleOptionsMenu();
+        osu->toggleOptionsMenu();
     else
     else
         setVisibleInt(false, true);
         setVisibleInt(false, true);
 }
 }
@@ -2248,7 +2231,7 @@ void OptionsMenu::scheduleSearchUpdate() {
 
 
 void OptionsMenu::askForLoginDetails() {
 void OptionsMenu::askForLoginDetails() {
     setVisible(true);
     setVisible(true);
-    m_options->scrollToElement(sectionOnline, 0, 100 * m_osu->getUIScale(m_osu));
+    m_options->scrollToElement(sectionOnline, 0, 100 * osu->getUIScale());
     m_nameTextbox->focus();
     m_nameTextbox->focus();
 }
 }
 
 
@@ -2360,13 +2343,13 @@ void OptionsMenu::onDPIScalingChange(CBaseUICheckbox *checkbox) {
     for(int i = 0; i < m_elements.size(); i++) {
     for(int i = 0; i < m_elements.size(); i++) {
         for(int e = 0; e < m_elements[i].elements.size(); e++) {
         for(int e = 0; e < m_elements[i].elements.size(); e++) {
             if(m_elements[i].elements[e] == checkbox) {
             if(m_elements[i].elements[e] == checkbox) {
-                const float prevUIScale = Osu::getUIScale(m_osu);
+                const float prevUIScale = Osu::getUIScale();
 
 
                 if(m_elements[i].cvar != NULL) m_elements[i].cvar->setValue(checkbox->isChecked());
                 if(m_elements[i].cvar != NULL) m_elements[i].cvar->setValue(checkbox->isChecked());
 
 
                 onResetUpdate(m_elements[i].resetButton);
                 onResetUpdate(m_elements[i].resetButton);
 
 
-                if(Osu::getUIScale(m_osu) != prevUIScale) m_bDPIScalingScrollToSliderScheduled = true;
+                if(Osu::getUIScale() != prevUIScale) m_bDPIScalingScrollToSliderScheduled = true;
 
 
                 break;
                 break;
             }
             }
@@ -2384,7 +2367,7 @@ void OptionsMenu::onRawInputToAbsoluteWindowChange(CBaseUICheckbox *checkbox) {
 
 
                 // special case: this requires a virtual mouse offset update, but since it is an engine convar we can't
                 // special case: this requires a virtual mouse offset update, but since it is an engine convar we can't
                 // use callbacks
                 // use callbacks
-                m_osu->updateMouseSettings();
+                osu->updateMouseSettings();
 
 
                 break;
                 break;
             }
             }
@@ -2403,7 +2386,7 @@ void OptionsMenu::openSkinsFolder() {
 void OptionsMenu::onSkinSelect() {
 void OptionsMenu::onSkinSelect() {
     updateOsuFolder();
     updateOsuFolder();
 
 
-    if(m_osu->isSkinLoading()) return;
+    if(osu->isSkinLoading()) return;
 
 
     UString skinFolder = convar->getConVarByName("osu_folder")->getString();
     UString skinFolder = convar->getConVarByName("osu_folder")->getString();
     skinFolder.append(convar->getConVarByName("osu_folder_sub_skins")->getString());
     skinFolder.append(convar->getConVarByName("osu_folder_sub_skins")->getString());
@@ -2431,29 +2414,25 @@ void OptionsMenu::onSkinSelect() {
         m_contextMenu->end(false, true);
         m_contextMenu->end(false, true);
         m_contextMenu->setClickCallback(fastdelegate::MakeDelegate(this, &OptionsMenu::onSkinSelect2));
         m_contextMenu->setClickCallback(fastdelegate::MakeDelegate(this, &OptionsMenu::onSkinSelect2));
     } else {
     } else {
-        m_osu->getNotificationOverlay()->addNotification("Error: Couldn't find any skins", 0xffff0000);
+        osu->getNotificationOverlay()->addNotification("Error: Couldn't find any skins", 0xffff0000);
         m_options->scrollToTop();
         m_options->scrollToTop();
         m_fOsuFolderTextboxInvalidAnim = engine->getTime() + 3.0f;
         m_fOsuFolderTextboxInvalidAnim = engine->getTime() + 3.0f;
     }
     }
 }
 }
 
 
 void OptionsMenu::onSkinSelect2(UString skinName, int id) {
 void OptionsMenu::onSkinSelect2(UString skinName, int id) {
-    if(m_osu->getInstanceID() < 1)
-        m_osu_skin_ref->setValue(skinName);
-    else
-        m_osu->setSkin(skinName);
-
+    m_osu_skin_ref->setValue(skinName);
     updateSkinNameLabel();
     updateSkinNameLabel();
 }
 }
 
 
-void OptionsMenu::onSkinReload() { m_osu->reloadSkin(); }
+void OptionsMenu::onSkinReload() { osu->reloadSkin(); }
 
 
 void OptionsMenu::onSkinRandom() {
 void OptionsMenu::onSkinRandom() {
     const bool isRandomSkinEnabled = m_osu_skin_random_ref->getBool();
     const bool isRandomSkinEnabled = m_osu_skin_random_ref->getBool();
 
 
     if(!isRandomSkinEnabled) m_osu_skin_random_ref->setValue(1.0f);
     if(!isRandomSkinEnabled) m_osu_skin_random_ref->setValue(1.0f);
 
 
-    m_osu->reloadSkin();
+    osu->reloadSkin();
 
 
     if(!isRandomSkinEnabled) m_osu_skin_random_ref->setValue(0.0f);
     if(!isRandomSkinEnabled) m_osu_skin_random_ref->setValue(0.0f);
 }
 }
@@ -2596,7 +2575,7 @@ void OptionsMenu::onOutputDeviceRestart() { engine->getSound()->restart(); }
 
 
 void OptionsMenu::onLogInClicked() {
 void OptionsMenu::onLogInClicked() {
     if(logInButton->is_loading) return;
     if(logInButton->is_loading) return;
-    engine->getSound()->play(m_osu->getSkin()->getMenuHit());
+    engine->getSound()->play(osu->getSkin()->getMenuHit());
 
 
     if(bancho.user_id > 0) {
     if(bancho.user_id > 0) {
         disconnect();
         disconnect();
@@ -2606,17 +2585,17 @@ void OptionsMenu::onLogInClicked() {
 }
 }
 
 
 void OptionsMenu::onDownloadOsuClicked() {
 void OptionsMenu::onDownloadOsuClicked() {
-    m_osu->getNotificationOverlay()->addNotification("Opening browser, please wait ...", 0xffffffff, false, 0.75f);
+    osu->getNotificationOverlay()->addNotification("Opening browser, please wait ...", 0xffffffff, false, 0.75f);
     env->openURLInDefaultBrowser("https://osu.ppy.sh/");
     env->openURLInDefaultBrowser("https://osu.ppy.sh/");
 }
 }
 
 
 void OptionsMenu::onManuallyManageBeatmapsClicked() {
 void OptionsMenu::onManuallyManageBeatmapsClicked() {
-    m_osu->getNotificationOverlay()->addNotification("Opening browser, please wait ...", 0xffffffff, false, 0.75f);
+    osu->getNotificationOverlay()->addNotification("Opening browser, please wait ...", 0xffffffff, false, 0.75f);
     env->openURLInDefaultBrowser("https://steamcommunity.com/sharedfiles/filedetails/?id=880768265");
     env->openURLInDefaultBrowser("https://steamcommunity.com/sharedfiles/filedetails/?id=880768265");
 }
 }
 
 
 void OptionsMenu::onCM360CalculatorLinkClicked() {
 void OptionsMenu::onCM360CalculatorLinkClicked() {
-    m_osu->getNotificationOverlay()->addNotification("Opening browser, please wait ...", 0xffffffff, false, 0.75f);
+    osu->getNotificationOverlay()->addNotification("Opening browser, please wait ...", 0xffffffff, false, 0.75f);
     env->openURLInDefaultBrowser("https://www.mouse-sensitivity.com/");
     env->openURLInDefaultBrowser("https://www.mouse-sensitivity.com/");
 }
 }
 
 
@@ -2885,8 +2864,8 @@ void OptionsMenu::onKeyBindingButtonPressed(CBaseUIButton *button) {
                     notificationText.append(":");
                     notificationText.append(":");
 
 
                     const bool waitForKey = true;
                     const bool waitForKey = true;
-                    m_osu->getNotificationOverlay()->addNotification(notificationText, 0xffffffff, waitForKey);
-                    m_osu->getNotificationOverlay()->setDisallowWaitForKeyLeftClick(
+                    osu->getNotificationOverlay()->addNotification(notificationText, 0xffffffff, waitForKey);
+                    osu->getNotificationOverlay()->setDisallowWaitForKeyLeftClick(
                         !(dynamic_cast<OptionsMenuKeyBindButton *>(button)->isLeftMouseClickBindingAllowed()));
                         !(dynamic_cast<OptionsMenuKeyBindButton *>(button)->isLeftMouseClickBindingAllowed()));
                 }
                 }
                 break;
                 break;
@@ -2896,7 +2875,7 @@ void OptionsMenu::onKeyBindingButtonPressed(CBaseUIButton *button) {
 }
 }
 
 
 void OptionsMenu::onKeyUnbindButtonPressed(CBaseUIButton *button) {
 void OptionsMenu::onKeyUnbindButtonPressed(CBaseUIButton *button) {
-    engine->getSound()->play(m_osu->getSkin()->getCheckOff());
+    engine->getSound()->play(osu->getSkin()->getCheckOff());
 
 
     for(int i = 0; i < m_elements.size(); i++) {
     for(int i = 0; i < m_elements.size(); i++) {
         for(int e = 0; e < m_elements[i].elements.size(); e++) {
         for(int e = 0; e < m_elements[i].elements.size(); e++) {
@@ -2923,13 +2902,13 @@ void OptionsMenu::onKeyBindingsResetAllPressed(CBaseUIButton *button) {
             bind->setValue(bind->getDefaultFloat());
             bind->setValue(bind->getDefaultFloat());
         }
         }
 
 
-        m_osu->getNotificationOverlay()->addNotification("All key bindings have been reset.", 0xff00ff00);
+        osu->getNotificationOverlay()->addNotification("All key bindings have been reset.", 0xff00ff00);
     } else {
     } else {
         if(remainingUntilReset > 1)
         if(remainingUntilReset > 1)
-            m_osu->getNotificationOverlay()->addNotification(
+            osu->getNotificationOverlay()->addNotification(
                 UString::format("Press %i more times to confirm.", remainingUntilReset));
                 UString::format("Press %i more times to confirm.", remainingUntilReset));
         else
         else
-            m_osu->getNotificationOverlay()->addNotification(
+            osu->getNotificationOverlay()->addNotification(
                 UString::format("Press %i more time to confirm!", remainingUntilReset), 0xffffff00);
                 UString::format("Press %i more time to confirm!", remainingUntilReset), 0xffffff00);
     }
     }
 }
 }
@@ -3093,13 +3072,13 @@ void OptionsMenu::onWASAPIPeriodChange(CBaseUISlider *slider) {
 void OptionsMenu::onLoudnessNormalizationToggle(CBaseUICheckbox *checkbox) {
 void OptionsMenu::onLoudnessNormalizationToggle(CBaseUICheckbox *checkbox) {
     onCheckboxChange(checkbox);
     onCheckboxChange(checkbox);
 
 
-    auto music = m_osu->getSelectedBeatmap()->getMusic();
+    auto music = osu->getSelectedBeatmap()->getMusic();
     if(music != nullptr) {
     if(music != nullptr) {
-        music->setVolume(m_osu->getSelectedBeatmap()->getIdealVolume());
+        music->setVolume(osu->getSelectedBeatmap()->getIdealVolume());
     }
     }
 }
 }
 
 
-void OptionsMenu::onUseSkinsSoundSamplesChange(UString oldValue, UString newValue) { m_osu->reloadSkin(); }
+void OptionsMenu::onUseSkinsSoundSamplesChange(UString oldValue, UString newValue) { osu->reloadSkin(); }
 
 
 void OptionsMenu::onHighQualitySlidersCheckboxChange(CBaseUICheckbox *checkbox) {
 void OptionsMenu::onHighQualitySlidersCheckboxChange(CBaseUICheckbox *checkbox) {
     onCheckboxChange(checkbox);
     onCheckboxChange(checkbox);
@@ -3153,8 +3132,7 @@ void OptionsMenu::onCategoryClicked(CBaseUIButton *button) {
 
 
     // scroll to category
     // scroll to category
     OptionsMenuCategoryButton *categoryButton = dynamic_cast<OptionsMenuCategoryButton *>(button);
     OptionsMenuCategoryButton *categoryButton = dynamic_cast<OptionsMenuCategoryButton *>(button);
-    if(categoryButton != NULL)
-        m_options->scrollToElement(categoryButton->getSection(), 0, 100 * Osu::getUIScale(m_osu));
+    if(categoryButton != NULL) m_options->scrollToElement(categoryButton->getSection(), 0, 100 * Osu::getUIScale());
 }
 }
 
 
 void OptionsMenu::onResetUpdate(CBaseUIButton *button) {
 void OptionsMenu::onResetUpdate(CBaseUIButton *button) {
@@ -3229,13 +3207,13 @@ void OptionsMenu::onResetEverythingClicked(CBaseUIButton *button) {
             bind->setValue(bind->getDefaultFloat());
             bind->setValue(bind->getDefaultFloat());
         }
         }
 
 
-        m_osu->getNotificationOverlay()->addNotification("All settings have been reset.", 0xff00ff00);
+        osu->getNotificationOverlay()->addNotification("All settings have been reset.", 0xff00ff00);
     } else {
     } else {
         if(remainingUntilReset > 1)
         if(remainingUntilReset > 1)
-            m_osu->getNotificationOverlay()->addNotification(
+            osu->getNotificationOverlay()->addNotification(
                 UString::format("Press %i more times to confirm.", remainingUntilReset));
                 UString::format("Press %i more times to confirm.", remainingUntilReset));
         else
         else
-            m_osu->getNotificationOverlay()->addNotification(
+            osu->getNotificationOverlay()->addNotification(
                 UString::format("Press %i more time to confirm!", remainingUntilReset), 0xffffff00);
                 UString::format("Press %i more time to confirm!", remainingUntilReset), 0xffffff00);
     }
     }
 }
 }
@@ -3250,7 +3228,7 @@ void OptionsMenu::addSpacer() {
 CBaseUILabel *OptionsMenu::addSection(UString text) {
 CBaseUILabel *OptionsMenu::addSection(UString text) {
     CBaseUILabel *label = new CBaseUILabel(0, 0, m_options->getSize().x, 25, text, text);
     CBaseUILabel *label = new CBaseUILabel(0, 0, m_options->getSize().x, 25, text, text);
     // label->setTextColor(0xff58dafe);
     // label->setTextColor(0xff58dafe);
-    label->setFont(m_osu->getTitleFont());
+    label->setFont(osu->getTitleFont());
     label->setSizeToContent(0, 0);
     label->setSizeToContent(0, 0);
     label->setTextJustification(CBaseUILabel::TEXT_JUSTIFICATION_RIGHT);
     label->setTextJustification(CBaseUILabel::TEXT_JUSTIFICATION_RIGHT);
     label->setDrawFrame(false);
     label->setDrawFrame(false);
@@ -3268,7 +3246,7 @@ CBaseUILabel *OptionsMenu::addSection(UString text) {
 
 
 CBaseUILabel *OptionsMenu::addSubSection(UString text, UString searchTags) {
 CBaseUILabel *OptionsMenu::addSubSection(UString text, UString searchTags) {
     CBaseUILabel *label = new CBaseUILabel(0, 0, m_options->getSize().x, 25, text, text);
     CBaseUILabel *label = new CBaseUILabel(0, 0, m_options->getSize().x, 25, text, text);
-    label->setFont(m_osu->getSubTitleFont());
+    label->setFont(osu->getSubTitleFont());
     label->setSizeToContent(0, 0);
     label->setSizeToContent(0, 0);
     label->setDrawFrame(false);
     label->setDrawFrame(false);
     label->setDrawBackground(false);
     label->setDrawBackground(false);
@@ -3301,7 +3279,7 @@ CBaseUILabel *OptionsMenu::addLabel(UString text) {
 }
 }
 
 
 UIButton *OptionsMenu::addButton(UString text) {
 UIButton *OptionsMenu::addButton(UString text) {
-    UIButton *button = new UIButton(m_osu, 0, 0, m_options->getSize().x, 50, text, text);
+    UIButton *button = new UIButton(0, 0, m_options->getSize().x, 50, text, text);
     button->setColor(0xff0e94b5);
     button->setColor(0xff0e94b5);
     button->setUseDefaultSkin();
     button->setUseDefaultSkin();
     m_options->getContainer()->addBaseUIElement(button);
     m_options->getContainer()->addBaseUIElement(button);
@@ -3315,7 +3293,7 @@ UIButton *OptionsMenu::addButton(UString text) {
 }
 }
 
 
 OptionsMenu::OPTIONS_ELEMENT OptionsMenu::addButton(UString text, UString labelText, bool withResetButton) {
 OptionsMenu::OPTIONS_ELEMENT OptionsMenu::addButton(UString text, UString labelText, bool withResetButton) {
-    UIButton *button = new UIButton(m_osu, 0, 0, m_options->getSize().x, 50, text, text);
+    UIButton *button = new UIButton(0, 0, m_options->getSize().x, 50, text, text);
     button->setColor(0xff0e94b5);
     button->setColor(0xff0e94b5);
     button->setUseDefaultSkin();
     button->setUseDefaultSkin();
     m_options->getContainer()->addBaseUIElement(button);
     m_options->getContainer()->addBaseUIElement(button);
@@ -3327,7 +3305,7 @@ OptionsMenu::OPTIONS_ELEMENT OptionsMenu::addButton(UString text, UString labelT
 
 
     OPTIONS_ELEMENT e;
     OPTIONS_ELEMENT e;
     if(withResetButton) {
     if(withResetButton) {
-        e.resetButton = new OptionsMenuResetButton(m_osu, 0, 0, 35, 50, "", "");
+        e.resetButton = new OptionsMenuResetButton(0, 0, 35, 50, "", "");
     }
     }
     e.elements.push_back(button);
     e.elements.push_back(button);
     e.elements.push_back(label);
     e.elements.push_back(label);
@@ -3338,12 +3316,12 @@ OptionsMenu::OPTIONS_ELEMENT OptionsMenu::addButton(UString text, UString labelT
 }
 }
 
 
 OptionsMenu::OPTIONS_ELEMENT OptionsMenu::addButtonButton(UString text1, UString text2) {
 OptionsMenu::OPTIONS_ELEMENT OptionsMenu::addButtonButton(UString text1, UString text2) {
-    UIButton *button = new UIButton(m_osu, 0, 0, m_options->getSize().x, 50, text1, text1);
+    UIButton *button = new UIButton(0, 0, m_options->getSize().x, 50, text1, text1);
     button->setColor(0xff0e94b5);
     button->setColor(0xff0e94b5);
     button->setUseDefaultSkin();
     button->setUseDefaultSkin();
     m_options->getContainer()->addBaseUIElement(button);
     m_options->getContainer()->addBaseUIElement(button);
 
 
-    UIButton *button2 = new UIButton(m_osu, 0, 0, m_options->getSize().x, 50, text2, text2);
+    UIButton *button2 = new UIButton(0, 0, m_options->getSize().x, 50, text2, text2);
     button2->setColor(0xff0e94b5);
     button2->setColor(0xff0e94b5);
     button2->setUseDefaultSkin();
     button2->setUseDefaultSkin();
     m_options->getContainer()->addBaseUIElement(button2);
     m_options->getContainer()->addBaseUIElement(button2);
@@ -3359,12 +3337,12 @@ OptionsMenu::OPTIONS_ELEMENT OptionsMenu::addButtonButton(UString text1, UString
 
 
 OptionsMenu::OPTIONS_ELEMENT OptionsMenu::addButtonButtonLabel(UString text1, UString text2, UString labelText,
 OptionsMenu::OPTIONS_ELEMENT OptionsMenu::addButtonButtonLabel(UString text1, UString text2, UString labelText,
                                                                bool withResetButton) {
                                                                bool withResetButton) {
-    UIButton *button = new UIButton(m_osu, 0, 0, m_options->getSize().x, 50, text1, text1);
+    UIButton *button = new UIButton(0, 0, m_options->getSize().x, 50, text1, text1);
     button->setColor(0xff0e94b5);
     button->setColor(0xff0e94b5);
     button->setUseDefaultSkin();
     button->setUseDefaultSkin();
     m_options->getContainer()->addBaseUIElement(button);
     m_options->getContainer()->addBaseUIElement(button);
 
 
-    UIButton *button2 = new UIButton(m_osu, 0, 0, m_options->getSize().x, 50, text2, text2);
+    UIButton *button2 = new UIButton(0, 0, m_options->getSize().x, 50, text2, text2);
     button2->setColor(0xff0e94b5);
     button2->setColor(0xff0e94b5);
     button2->setUseDefaultSkin();
     button2->setUseDefaultSkin();
     m_options->getContainer()->addBaseUIElement(button2);
     m_options->getContainer()->addBaseUIElement(button2);
@@ -3376,7 +3354,7 @@ OptionsMenu::OPTIONS_ELEMENT OptionsMenu::addButtonButtonLabel(UString text1, US
 
 
     OPTIONS_ELEMENT e;
     OPTIONS_ELEMENT e;
     if(withResetButton) {
     if(withResetButton) {
-        e.resetButton = new OptionsMenuResetButton(m_osu, 0, 0, 35, 50, "", "");
+        e.resetButton = new OptionsMenuResetButton(0, 0, 35, 50, "", "");
     }
     }
     e.elements.push_back(button);
     e.elements.push_back(button);
     e.elements.push_back(button2);
     e.elements.push_back(button2);
@@ -3389,16 +3367,15 @@ OptionsMenu::OPTIONS_ELEMENT OptionsMenu::addButtonButtonLabel(UString text1, US
 
 
 OptionsMenuKeyBindButton *OptionsMenu::addKeyBindButton(UString text, ConVar *cvar) {
 OptionsMenuKeyBindButton *OptionsMenu::addKeyBindButton(UString text, ConVar *cvar) {
     /// UString unbindIconString; unbindIconString.insert(0, Icons::UNDO);
     /// UString unbindIconString; unbindIconString.insert(0, Icons::UNDO);
-    UIButton *unbindButton = new UIButton(m_osu, 0, 0, m_options->getSize().x, 50, text, "");
+    UIButton *unbindButton = new UIButton(0, 0, m_options->getSize().x, 50, text, "");
     unbindButton->setTooltipText("Unbind");
     unbindButton->setTooltipText("Unbind");
     unbindButton->setColor(0x77ff0000);
     unbindButton->setColor(0x77ff0000);
     unbindButton->setUseDefaultSkin();
     unbindButton->setUseDefaultSkin();
     unbindButton->setClickCallback(fastdelegate::MakeDelegate(this, &OptionsMenu::onKeyUnbindButtonPressed));
     unbindButton->setClickCallback(fastdelegate::MakeDelegate(this, &OptionsMenu::onKeyUnbindButtonPressed));
-    /// unbindButton->setFont(m_osu->getFontIcons());
+    /// unbindButton->setFont(osu->getFontIcons());
     m_options->getContainer()->addBaseUIElement(unbindButton);
     m_options->getContainer()->addBaseUIElement(unbindButton);
 
 
-    OptionsMenuKeyBindButton *bindButton =
-        new OptionsMenuKeyBindButton(m_osu, 0, 0, m_options->getSize().x, 50, text, text);
+    OptionsMenuKeyBindButton *bindButton = new OptionsMenuKeyBindButton(0, 0, m_options->getSize().x, 50, text, text);
     bindButton->setColor(0xff0e94b5);
     bindButton->setColor(0xff0e94b5);
     bindButton->setUseDefaultSkin();
     bindButton->setUseDefaultSkin();
     bindButton->setClickCallback(fastdelegate::MakeDelegate(this, &OptionsMenu::onKeyBindingButtonPressed));
     bindButton->setClickCallback(fastdelegate::MakeDelegate(this, &OptionsMenu::onKeyBindingButtonPressed));
@@ -3424,7 +3401,7 @@ OptionsMenuKeyBindButton *OptionsMenu::addKeyBindButton(UString text, ConVar *cv
 CBaseUICheckbox *OptionsMenu::addCheckbox(UString text, ConVar *cvar) { return addCheckbox(text, "", cvar); }
 CBaseUICheckbox *OptionsMenu::addCheckbox(UString text, ConVar *cvar) { return addCheckbox(text, "", cvar); }
 
 
 CBaseUICheckbox *OptionsMenu::addCheckbox(UString text, UString tooltipText, ConVar *cvar) {
 CBaseUICheckbox *OptionsMenu::addCheckbox(UString text, UString tooltipText, ConVar *cvar) {
-    UICheckbox *checkbox = new UICheckbox(m_osu, 0, 0, m_options->getSize().x, 50, text, text);
+    UICheckbox *checkbox = new UICheckbox(0, 0, m_options->getSize().x, 50, text, text);
     checkbox->setDrawFrame(false);
     checkbox->setDrawFrame(false);
     checkbox->setDrawBackground(false);
     checkbox->setDrawBackground(false);
 
 
@@ -3439,7 +3416,7 @@ CBaseUICheckbox *OptionsMenu::addCheckbox(UString text, UString tooltipText, Con
 
 
     OPTIONS_ELEMENT e;
     OPTIONS_ELEMENT e;
     if(cvar != NULL) {
     if(cvar != NULL) {
-        e.resetButton = new OptionsMenuResetButton(m_osu, 0, 0, 35, 50, "", "");
+        e.resetButton = new OptionsMenuResetButton(0, 0, 35, 50, "", "");
         e.resetButton->setClickCallback(fastdelegate::MakeDelegate(this, &OptionsMenu::onResetClicked));
         e.resetButton->setClickCallback(fastdelegate::MakeDelegate(this, &OptionsMenu::onResetClicked));
     }
     }
     e.elements.push_back(checkbox);
     e.elements.push_back(checkbox);
@@ -3452,7 +3429,7 @@ CBaseUICheckbox *OptionsMenu::addCheckbox(UString text, UString tooltipText, Con
 
 
 UISlider *OptionsMenu::addSlider(UString text, float min, float max, ConVar *cvar, float label1Width,
 UISlider *OptionsMenu::addSlider(UString text, float min, float max, ConVar *cvar, float label1Width,
                                  bool allowOverscale, bool allowUnderscale) {
                                  bool allowOverscale, bool allowUnderscale) {
-    UISlider *slider = new UISlider(m_osu, 0, 0, 100, 50, text);
+    UISlider *slider = new UISlider(0, 0, 100, 50, text);
     slider->setAllowMouseWheel(false);
     slider->setAllowMouseWheel(false);
     slider->setBounds(min, max);
     slider->setBounds(min, max);
     slider->setLiveUpdate(true);
     slider->setLiveUpdate(true);
@@ -3479,7 +3456,7 @@ UISlider *OptionsMenu::addSlider(UString text, float min, float max, ConVar *cva
 
 
     OPTIONS_ELEMENT e;
     OPTIONS_ELEMENT e;
     if(cvar != NULL) {
     if(cvar != NULL) {
-        e.resetButton = new OptionsMenuResetButton(m_osu, 0, 0, 35, 50, "", "");
+        e.resetButton = new OptionsMenuResetButton(0, 0, 35, 50, "", "");
         e.resetButton->setClickCallback(fastdelegate::MakeDelegate(this, &OptionsMenu::onResetClicked));
         e.resetButton->setClickCallback(fastdelegate::MakeDelegate(this, &OptionsMenu::onResetClicked));
     }
     }
     e.elements.push_back(label1);
     e.elements.push_back(label1);
@@ -3532,8 +3509,7 @@ CBaseUITextbox *OptionsMenu::addTextbox(UString text, UString labelText, ConVar
 }
 }
 
 
 CBaseUIElement *OptionsMenu::addSkinPreview() {
 CBaseUIElement *OptionsMenu::addSkinPreview() {
-    CBaseUIElement *skinPreview =
-        new OptionsMenuSkinPreviewElement(m_osu, 0, 0, 0, 200, "skincirclenumberhitresultpreview");
+    CBaseUIElement *skinPreview = new OptionsMenuSkinPreviewElement(0, 0, 0, 200, "skincirclenumberhitresultpreview");
     m_options->getContainer()->addBaseUIElement(skinPreview);
     m_options->getContainer()->addBaseUIElement(skinPreview);
 
 
     OPTIONS_ELEMENT e;
     OPTIONS_ELEMENT e;
@@ -3546,7 +3522,7 @@ CBaseUIElement *OptionsMenu::addSkinPreview() {
 }
 }
 
 
 CBaseUIElement *OptionsMenu::addSliderPreview() {
 CBaseUIElement *OptionsMenu::addSliderPreview() {
-    CBaseUIElement *sliderPreview = new OptionsMenuSliderPreviewElement(m_osu, 0, 0, 0, 200, "skinsliderpreview");
+    CBaseUIElement *sliderPreview = new OptionsMenuSliderPreviewElement(0, 0, 0, 200, "skinsliderpreview");
     m_options->getContainer()->addBaseUIElement(sliderPreview);
     m_options->getContainer()->addBaseUIElement(sliderPreview);
 
 
     OPTIONS_ELEMENT e;
     OPTIONS_ELEMENT e;
@@ -3562,7 +3538,7 @@ OptionsMenuCategoryButton *OptionsMenu::addCategory(CBaseUIElement *section, wch
     UString iconString;
     UString iconString;
     iconString.insert(0, icon);
     iconString.insert(0, icon);
     OptionsMenuCategoryButton *button = new OptionsMenuCategoryButton(section, 0, 0, 50, 50, "", iconString);
     OptionsMenuCategoryButton *button = new OptionsMenuCategoryButton(section, 0, 0, 50, 50, "", iconString);
-    button->setFont(m_osu->getFontIcons());
+    button->setFont(osu->getFontIcons());
     button->setDrawBackground(false);
     button->setDrawBackground(false);
     button->setDrawFrame(false);
     button->setDrawFrame(false);
     button->setClickCallback(fastdelegate::MakeDelegate(this, &OptionsMenu::onCategoryClicked));
     button->setClickCallback(fastdelegate::MakeDelegate(this, &OptionsMenu::onCategoryClicked));
@@ -3721,21 +3697,21 @@ void OptionsMenu::save() {
 
 
 void OptionsMenu::openAndScrollToSkinSection() {
 void OptionsMenu::openAndScrollToSkinSection() {
     const bool wasVisible = isVisible();
     const bool wasVisible = isVisible();
-    if(!wasVisible) m_osu->toggleOptionsMenu();
+    if(!wasVisible) osu->toggleOptionsMenu();
 
 
     if(!m_skinSelectLocalButton->isVisible() || !wasVisible)
     if(!m_skinSelectLocalButton->isVisible() || !wasVisible)
-        m_options->scrollToElement(m_skinSection, 0, 100 * Osu::getUIScale(m_osu));
+        m_options->scrollToElement(m_skinSection, 0, 100 * Osu::getUIScale());
 }
 }
 
 
 void OptionsMenu::onNightcorePreferenceChange(CBaseUICheckbox *checkbox) {
 void OptionsMenu::onNightcorePreferenceChange(CBaseUICheckbox *checkbox) {
     onCheckboxChange(checkbox);
     onCheckboxChange(checkbox);
 
 
-    int prev_state = m_osu->m_modSelector->m_modButtonHalftime->getState();
+    int prev_state = osu->m_modSelector->m_modButtonHalftime->getState();
 
 
-    m_osu->m_modSelector->updateButtons();
+    osu->m_modSelector->updateButtons();
 
 
-    if(m_osu->m_modSelector->m_modButtonHalftime->isOn() || m_osu->m_modSelector->m_modButtonDoubletime->isOn()) {
-        m_osu->m_modSelector->m_modButtonHalftime->setState(prev_state ? 0 : 1);
-        m_osu->m_modSelector->m_modButtonDoubletime->setState(prev_state ? 0 : 1);
+    if(osu->m_modSelector->m_modButtonHalftime->isOn() || osu->m_modSelector->m_modButtonDoubletime->isOn()) {
+        osu->m_modSelector->m_modButtonHalftime->setState(prev_state ? 0 : 1);
+        osu->m_modSelector->m_modButtonDoubletime->setState(prev_state ? 0 : 1);
     }
     }
 }
 }

+ 2 - 16
src/App/Osu/OptionsMenu.h

@@ -1,18 +1,7 @@
-//================ Copyright (c) 2016, PG, All rights reserved. =================//
-//
-// Purpose:		settings
-//
-// $NoKeywords: $
-//===============================================================================//
-
-#ifndef OSUOPTIONSMENU_H
-#define OSUOPTIONSMENU_H
-
+#pragma once
 #include "NotificationOverlay.h"
 #include "NotificationOverlay.h"
 #include "ScreenBackable.h"
 #include "ScreenBackable.h"
 
 
-class Osu;
-
 class UIButton;
 class UIButton;
 class UISlider;
 class UISlider;
 class UIContextMenu;
 class UIContextMenu;
@@ -36,7 +25,7 @@ class ConVar;
 
 
 class OptionsMenu : public ScreenBackable, public NotificationOverlayKeyListener {
 class OptionsMenu : public ScreenBackable, public NotificationOverlayKeyListener {
    public:
    public:
-    OptionsMenu(Osu *osu);
+    OptionsMenu();
     ~OptionsMenu();
     ~OptionsMenu();
 
 
     virtual void draw(Graphics *g);
     virtual void draw(Graphics *g);
@@ -206,7 +195,6 @@ class OptionsMenu : public ScreenBackable, public NotificationOverlayKeyListener
     OptionsMenuCategoryButton *addCategory(CBaseUIElement *section, wchar_t icon);
     OptionsMenuCategoryButton *addCategory(CBaseUIElement *section, wchar_t icon);
 
 
     // vars
     // vars
-    Osu *m_osu;
     CBaseUIScrollView *m_categories;
     CBaseUIScrollView *m_categories;
     CBaseUIScrollView *m_options;
     CBaseUIScrollView *m_options;
     UIContextMenu *m_contextMenu;
     UIContextMenu *m_contextMenu;
@@ -318,5 +306,3 @@ class OptionsMenu : public ScreenBackable, public NotificationOverlayKeyListener
 
 
     bool m_updating_layout = false;
     bool m_updating_layout = false;
 };
 };
-
-#endif

+ 76 - 161
src/App/Osu/Osu.cpp

@@ -1,10 +1,3 @@
-//================ Copyright (c) 2015, PG, All rights reserved. =================//
-//
-// Purpose:		yet another ouendan clone, because why not
-//
-// $NoKeywords: $osu
-//===============================================================================//
-
 #include "Osu.h"
 #include "Osu.h"
 
 
 #include <sstream>
 #include <sstream>
@@ -62,6 +55,8 @@
 #include "VolumeOverlay.h"
 #include "VolumeOverlay.h"
 #include "score.h"
 #include "score.h"
 
 
+Osu *osu = nullptr;
+
 // release configuration
 // release configuration
 ConVar auto_update("auto_update", true, FCVAR_DEFAULT);
 ConVar auto_update("auto_update", true, FCVAR_DEFAULT);
 ConVar osu_version("osu_version", 35.01f, FCVAR_DEFAULT | FCVAR_HIDDEN);
 ConVar osu_version("osu_version", 35.01f, FCVAR_DEFAULT | FCVAR_HIDDEN);
@@ -171,15 +166,15 @@ Vector2 Osu::osuBaseResolution = Vector2(640.0f, 480.0f);
 
 
 Shader *flashlight_shader = nullptr;
 Shader *flashlight_shader = nullptr;
 
 
-Osu::Osu(int instanceID) {
+Osu::Osu() {
+    osu = this;
+
     srand(time(NULL));
     srand(time(NULL));
 
 
     bancho.neosu_version = UString::format("%.2f-" NEOSU_STREAM, osu_version.getFloat());
     bancho.neosu_version = UString::format("%.2f-" NEOSU_STREAM, osu_version.getFloat());
     bancho.user_agent =
     bancho.user_agent =
         UString::format("Mozilla/5.0 (compatible; neosu/%s; +" NEOSU_UPDATE_URL "/)", bancho.neosu_version.toUtf8());
         UString::format("Mozilla/5.0 (compatible; neosu/%s; +" NEOSU_UPDATE_URL "/)", bancho.neosu_version.toUtf8());
 
 
-    m_iInstanceID = instanceID;
-
     // convar refs
     // convar refs
     m_osu_folder_ref = convar->getConVarByName("osu_folder");
     m_osu_folder_ref = convar->getConVarByName("osu_folder");
     m_osu_folder_sub_skins_ref = convar->getConVarByName("osu_folder_sub_skins");
     m_osu_folder_sub_skins_ref = convar->getConVarByName("osu_folder_sub_skins");
@@ -235,7 +230,7 @@ Osu::Osu(int instanceID) {
     env->setCursorVisible(false);
     env->setCursorVisible(false);
 
 
     engine->getConsoleBox()->setRequireShiftToActivate(true);
     engine->getConsoleBox()->setRequireShiftToActivate(true);
-    if(m_iInstanceID < 2) engine->getMouse()->addListener(this);
+    engine->getMouse()->addListener(this);
 
 
     convar->getConVarByName("vsync")->setValue(0.0f);
     convar->getConVarByName("vsync")->setValue(0.0f);
     convar->getConVarByName("fps_max")->setValue(420.0f);
     convar->getConVarByName("fps_max")->setValue(420.0f);
@@ -362,16 +357,14 @@ Osu::Osu(int instanceID) {
     m_frameBuffer2 = engine->getResourceManager()->createRenderTarget(0, 0, 64, 64);
     m_frameBuffer2 = engine->getResourceManager()->createRenderTarget(0, 0, 64, 64);
 
 
     // load a few select subsystems very early
     // load a few select subsystems very early
-    m_notificationOverlay = new NotificationOverlay(this);
-    m_score = new LiveScore(this);
+    m_notificationOverlay = new NotificationOverlay();
+    m_score = new LiveScore();
     m_updateHandler = new UpdateHandler();
     m_updateHandler = new UpdateHandler();
 
 
     // exec the main config file (this must be right here!)
     // exec the main config file (this must be right here!)
-    if(m_iInstanceID < 2) {
-        Console::execConfigFile("underride");  // same as override, but for defaults
-        Console::execConfigFile("osu");
-        Console::execConfigFile("override");  // used for quickfixing live builds without redeploying/recompiling
-    }
+    Console::execConfigFile("underride");  // same as override, but for defaults
+    Console::execConfigFile("osu");
+    Console::execConfigFile("override");  // used for quickfixing live builds without redeploying/recompiling
 
 
     // Initialize sound here so we can load the preferred device from config
     // Initialize sound here so we can load the preferred device from config
     // Avoids initializing the sound device twice, which can take a while depending on the driver
     // Avoids initializing the sound device twice, which can take a while depending on the driver
@@ -394,7 +387,7 @@ Osu::Osu(int instanceID) {
 
 
     // load global resources
     // load global resources
     const int baseDPI = 96;
     const int baseDPI = 96;
-    const int newDPI = Osu::getUIScale(this) * baseDPI;
+    const int newDPI = Osu::getUIScale() * baseDPI;
 
 
     McFont *defaultFont =
     McFont *defaultFont =
         engine->getResourceManager()->loadFont("weblysleekuisb.ttf", "FONT_DEFAULT", 15, true, newDPI);
         engine->getResourceManager()->loadFont("weblysleekuisb.ttf", "FONT_DEFAULT", 15, true, newDPI);
@@ -443,24 +436,24 @@ Osu::Osu(int instanceID) {
     }
     }
 
 
     // load subsystems, add them to the screens array
     // load subsystems, add them to the screens array
-    m_songBrowser2 = new SongBrowser(this);
-    m_volumeOverlay = new VolumeOverlay(this);
-    m_tooltipOverlay = new TooltipOverlay(this);
-    m_mainMenu = new MainMenu(this);
-    m_optionsMenu = new OptionsMenu(this);
+    m_songBrowser2 = new SongBrowser();
+    m_volumeOverlay = new VolumeOverlay();
+    m_tooltipOverlay = new TooltipOverlay();
+    m_mainMenu = new MainMenu();
+    m_optionsMenu = new OptionsMenu();
     m_backgroundImageHandler = new BackgroundImageHandler();
     m_backgroundImageHandler = new BackgroundImageHandler();
-    m_modSelector = new ModSelector(this);
-    m_rankingScreen = new RankingScreen(this);
-    m_userStatsScreen = new UserStatsScreen(this);
-    m_pauseMenu = new PauseMenu(this);
-    m_hud = new HUD(this);
-    m_changelog = new Changelog(this);
-    m_fposu = new ModFPoSu(this);
-    m_chat = new Chat(this);
-    m_lobby = new Lobby(this);
-    m_room = new RoomScreen(this);
-    m_prompt = new PromptScreen(this);
-    m_user_actions = new UIUserContextMenuScreen(this);
+    m_modSelector = new ModSelector();
+    m_rankingScreen = new RankingScreen();
+    m_userStatsScreen = new UserStatsScreen();
+    m_pauseMenu = new PauseMenu();
+    m_hud = new HUD();
+    m_changelog = new Changelog();
+    m_fposu = new ModFPoSu();
+    m_chat = new Chat();
+    m_lobby = new Lobby();
+    m_room = new RoomScreen();
+    m_prompt = new PromptScreen();
+    m_user_actions = new UIUserContextMenuScreen();
 
 
     // the order in this vector will define in which order events are handled/consumed
     // the order in this vector will define in which order events are handled/consumed
     m_screens.push_back(m_volumeOverlay);
     m_screens.push_back(m_volumeOverlay);
@@ -485,7 +478,6 @@ Osu::Osu(int instanceID) {
     updateMods();
     updateMods();
 
 
     // Init online functionality (multiplayer/leaderboards/etc)
     // Init online functionality (multiplayer/leaderboards/etc)
-    bancho.osu = this;
     init_networking_thread();
     init_networking_thread();
     if(mp_autologin.getBool()) {
     if(mp_autologin.getBool()) {
         reconnect();
         reconnect();
@@ -522,7 +514,7 @@ Osu::Osu(int instanceID) {
 }
 }
 
 
 Osu::~Osu() {
 Osu::~Osu() {
-    bancho.osu = nullptr;
+    osu = nullptr;
 
 
     // "leak" UpdateHandler object, but not relevant since shutdown:
     // "leak" UpdateHandler object, but not relevant since shutdown:
     // this is the only way of handling instant user shutdown requests properly, there is no solution for active working
     // this is the only way of handling instant user shutdown requests properly, there is no solution for active working
@@ -551,9 +543,8 @@ void Osu::draw(Graphics *g) {
         return;
         return;
     }
     }
 
 
-    // if we are not using the native window resolution, or in vr mode, or multiple instances are active,
-    // draw into the buffer
-    const bool isBufferedDraw = osu_resolution_enabled.getBool() || m_iInstanceID > 0;
+    // if we are not using the native window resolution, draw into the buffer
+    const bool isBufferedDraw = osu_resolution_enabled.getBool();
 
 
     if(isBufferedDraw) m_backBuffer->enable();
     if(isBufferedDraw) m_backBuffer->enable();
 
 
@@ -575,8 +566,8 @@ void Osu::draw(Graphics *g) {
 
 
             // Convert screen mouse -> osu mouse pos
             // Convert screen mouse -> osu mouse pos
             Vector2 cursorPos = beatmap->getCursorPos();
             Vector2 cursorPos = beatmap->getCursorPos();
-            Vector2 mouse_position = cursorPos - GameRules::getPlayfieldOffset(this);
-            mouse_position /= GameRules::getPlayfieldScaleFactor(this);
+            Vector2 mouse_position = cursorPos - GameRules::getPlayfieldOffset();
+            mouse_position /= GameRules::getPlayfieldScaleFactor();
 
 
             // Update flashlight position
             // Update flashlight position
             double follow_delay = flashlight_follow_delay.getFloat();
             double follow_delay = flashlight_follow_delay.getFloat();
@@ -585,9 +576,9 @@ void Osu::draw(Graphics *g) {
             t = t * (2.f - t);
             t = t * (2.f - t);
             flashlight_position += t * (mouse_position - flashlight_position);
             flashlight_position += t * (mouse_position - flashlight_position);
             Vector2 flashlightPos =
             Vector2 flashlightPos =
-                flashlight_position * GameRules::getPlayfieldScaleFactor(this) + GameRules::getPlayfieldOffset(this);
+                flashlight_position * GameRules::getPlayfieldScaleFactor() + GameRules::getPlayfieldOffset();
 
 
-            float fl_radius = flashlight_radius.getFloat() * GameRules::getPlayfieldScaleFactor(this);
+            float fl_radius = flashlight_radius.getFloat() * GameRules::getPlayfieldScaleFactor();
             if(getScore()->getCombo() >= 200 || convar->getConVarByName("flashlight_always_hard")->getBool()) {
             if(getScore()->getCombo() >= 200 || convar->getConVarByName("flashlight_always_hard")->getBool()) {
                 fl_radius *= 0.625f;
                 fl_radius *= 0.625f;
             } else if(getScore()->getCombo() >= 100) {
             } else if(getScore()->getCombo() >= 100) {
@@ -686,50 +677,8 @@ void Osu::draw(Graphics *g) {
         // draw a scaled version from the buffer to the screen
         // draw a scaled version from the buffer to the screen
         m_backBuffer->disable();
         m_backBuffer->disable();
 
 
-        // TODO: move this shit to Osu2
         Vector2 offset = Vector2(engine->getGraphics()->getResolution().x / 2 - g_vInternalResolution.x / 2,
         Vector2 offset = Vector2(engine->getGraphics()->getResolution().x / 2 - g_vInternalResolution.x / 2,
                                  engine->getGraphics()->getResolution().y / 2 - g_vInternalResolution.y / 2);
                                  engine->getGraphics()->getResolution().y / 2 - g_vInternalResolution.y / 2);
-        if(m_iInstanceID > 0) {
-            const int numHorizontalInstances = 2;
-            const int numVerticalInstances = 1;
-
-            float emptySpaceX =
-                engine->getGraphics()->getResolution().x - numHorizontalInstances * g_vInternalResolution.x;
-            float emptySpaceY =
-                engine->getGraphics()->getResolution().y - numVerticalInstances * g_vInternalResolution.y;
-
-            switch(m_iInstanceID) {
-                case 1:
-                    offset.x = emptySpaceX / 2.0f / numHorizontalInstances;
-                    offset.y = emptySpaceY / 2.0f / numVerticalInstances;
-                    break;
-                case 2:
-                    offset.x = emptySpaceX / 2.0f / numHorizontalInstances;
-                    offset.y = emptySpaceY / 2.0f / numVerticalInstances + engine->getGraphics()->getResolution().y / 2;
-                    break;
-                case 3:
-                    offset.x =
-                        emptySpaceX / 2.0f / numHorizontalInstances + engine->getGraphics()->getResolution().x / 2;
-                    offset.y = emptySpaceY / 2.0f / numVerticalInstances;
-                    break;
-                case 4:
-                    offset.x =
-                        emptySpaceX / 2.0f / numHorizontalInstances + engine->getGraphics()->getResolution().x / 2;
-                    offset.y = emptySpaceY / 2.0f / numVerticalInstances + engine->getGraphics()->getResolution().y / 2;
-                    break;
-                case 5:
-                    offset.x =
-                        emptySpaceX / 2.0f / numHorizontalInstances + engine->getGraphics()->getResolution().x / 2;
-                    offset.y = emptySpaceY / 2.0f / numVerticalInstances + engine->getGraphics()->getResolution().y / 2;
-                    break;
-                case 6:
-                    offset.x =
-                        emptySpaceX / 2.0f / numHorizontalInstances + engine->getGraphics()->getResolution().x / 2;
-                    offset.y = emptySpaceY / 2.0f / numVerticalInstances + engine->getGraphics()->getResolution().y / 2;
-                    break;
-            }
-        }
-
         g->setBlending(false);
         g->setBlending(false);
         if(osu_letterboxing.getBool()) {
         if(osu_letterboxing.getBool()) {
             m_backBuffer->draw(g, offset.x * (1.0f + osu_letterboxing_offset_x.getFloat()),
             m_backBuffer->draw(g, offset.x * (1.0f + osu_letterboxing_offset_x.getFloat()),
@@ -932,12 +881,9 @@ void Osu::update() {
     }
     }
     if(m_bToggleUserStatsScreenScheduled) {
     if(m_bToggleUserStatsScreenScheduled) {
         m_bToggleUserStatsScreenScheduled = false;
         m_bToggleUserStatsScreenScheduled = false;
+        m_userStatsScreen->setVisible(true);
 
 
-        if(m_iInstanceID < 2) {
-            m_userStatsScreen->setVisible(true);
-
-            if(m_songBrowser2 != NULL && m_songBrowser2->isVisible()) m_songBrowser2->setVisible(false);
-        }
+        if(m_songBrowser2 != NULL && m_songBrowser2->isVisible()) m_songBrowser2->setVisible(false);
     }
     }
     if(m_bToggleChangelogScheduled) {
     if(m_bToggleChangelogScheduled) {
         m_bToggleChangelogScheduled = false;
         m_bToggleChangelogScheduled = false;
@@ -954,7 +900,7 @@ void Osu::update() {
     // handle cursor visibility if outside of internal resolution
     // handle cursor visibility if outside of internal resolution
     // TODO: not a critical bug, but the real cursor gets visible way too early if sensitivity is > 1.0f, due to this
     // TODO: not a critical bug, but the real cursor gets visible way too early if sensitivity is > 1.0f, due to this
     // using scaled/offset getMouse()->getPos()
     // using scaled/offset getMouse()->getPos()
-    if(osu_resolution_enabled.getBool() && m_iInstanceID < 1) {
+    if(osu_resolution_enabled.getBool()) {
         McRect internalWindow = McRect(0, 0, g_vInternalResolution.x, g_vInternalResolution.y);
         McRect internalWindow = McRect(0, 0, g_vInternalResolution.x, g_vInternalResolution.y);
         bool cursorVisible = env->isCursorVisible();
         bool cursorVisible = env->isCursorVisible();
         if(!internalWindow.contains(engine->getMouse()->getPos())) {
         if(!internalWindow.contains(engine->getMouse()->getPos())) {
@@ -1688,28 +1634,6 @@ void Osu::saveScreenshot() {
                        screenshot_path);
                        screenshot_path);
 }
 }
 
 
-void Osu::onPlayStart() {
-    m_snd_change_check_interval_ref->setValue(0.0f);
-
-    if(m_bModAuto || m_bModAutopilot || getSelectedBeatmap()->m_bIsWatchingReplay) {
-        m_bShouldCursorBeVisible = true;
-        env->setCursorVisible(m_bShouldCursorBeVisible);
-    }
-
-    if(getSelectedBeatmap()->getSelectedDifficulty2()->getLocalOffset() != 0)
-        m_notificationOverlay->addNotification(
-            UString::format("Using local beatmap offset (%ld ms)",
-                            getSelectedBeatmap()->getSelectedDifficulty2()->getLocalOffset()),
-            0xffffffff, false, 0.75f);
-
-    m_fQuickSaveTime = 0.0f;  // reset
-
-    updateConfineCursor();
-    updateWindowsKeyDisable();
-
-    RichPresence::onPlayStart(this);
-}
-
 void Osu::onPlayEnd(bool quit, bool aborted) {
 void Osu::onPlayEnd(bool quit, bool aborted) {
     m_snd_change_check_interval_ref->setValue(m_snd_change_check_interval_ref->getDefaultFloat());
     m_snd_change_check_interval_ref->setValue(m_snd_change_check_interval_ref->getDefaultFloat());
 
 
@@ -1739,11 +1663,7 @@ void Osu::onPlayEnd(bool quit, bool aborted) {
     // When playing in multiplayer, screens are toggled in Room
     // When playing in multiplayer, screens are toggled in Room
     if(!bancho.is_playing_a_multi_map()) {
     if(!bancho.is_playing_a_multi_map()) {
         if(quit) {
         if(quit) {
-            if(m_iInstanceID < 2) {
-                toggleSongBrowser();
-            } else {
-                m_mainMenu->setVisible(true);
-            }
+            toggleSongBrowser();
         } else {
         } else {
             m_rankingScreen->setVisible(true);
             m_rankingScreen->setVisible(true);
         }
         }
@@ -1849,40 +1769,37 @@ void Osu::onResolutionChanged(Vector2 newResolution) {
 
 
     if(engine->isMinimized()) return;  // ignore if minimized
     if(engine->isMinimized()) return;  // ignore if minimized
 
 
-    const float prevUIScale = getUIScale(this);
+    const float prevUIScale = getUIScale();
 
 
-    if(m_iInstanceID < 1) {
-        if(!osu_resolution_enabled.getBool())
-            g_vInternalResolution = newResolution;
-        else if(!engine->isMinimized())  // if we just got minimized, ignore the resolution change (for the internal
+    if(!osu_resolution_enabled.getBool()) {
+        g_vInternalResolution = newResolution;
+    } else if(!engine->isMinimized()) {  // if we just got minimized, ignore the resolution change (for the internal
                                          // stuff)
                                          // stuff)
-        {
-            // clamp upwards to internal resolution (osu_resolution)
-            if(g_vInternalResolution.x < m_vInternalResolution.x) g_vInternalResolution.x = m_vInternalResolution.x;
-            if(g_vInternalResolution.y < m_vInternalResolution.y) g_vInternalResolution.y = m_vInternalResolution.y;
-
-            // clamp downwards to engine resolution
-            if(newResolution.x < g_vInternalResolution.x) g_vInternalResolution.x = newResolution.x;
-            if(newResolution.y < g_vInternalResolution.y) g_vInternalResolution.y = newResolution.y;
-
-            // disable internal resolution on specific conditions
-            bool windowsBorderlessHackCondition =
-                (env->getOS() == Environment::OS::OS_WINDOWS && env->isFullscreen() &&
-                 env->isFullscreenWindowedBorderless() &&
-                 (int)g_vInternalResolution.y == (int)env->getNativeScreenSize().y);  // HACKHACK
-            if(((int)g_vInternalResolution.x == engine->getScreenWidth() &&
-                (int)g_vInternalResolution.y == engine->getScreenHeight()) ||
-               !env->isFullscreen() || windowsBorderlessHackCondition) {
-                debugLog("Internal resolution == Engine resolution || !Fullscreen, disabling resampler (%i, %i)\n",
-                         (int)(g_vInternalResolution == engine->getScreenSize()), (int)(!env->isFullscreen()));
-                osu_resolution_enabled.setValue(0.0f);
-                g_vInternalResolution = engine->getScreenSize();
-            }
+        // clamp upwards to internal resolution (osu_resolution)
+        if(g_vInternalResolution.x < m_vInternalResolution.x) g_vInternalResolution.x = m_vInternalResolution.x;
+        if(g_vInternalResolution.y < m_vInternalResolution.y) g_vInternalResolution.y = m_vInternalResolution.y;
+
+        // clamp downwards to engine resolution
+        if(newResolution.x < g_vInternalResolution.x) g_vInternalResolution.x = newResolution.x;
+        if(newResolution.y < g_vInternalResolution.y) g_vInternalResolution.y = newResolution.y;
+
+        // disable internal resolution on specific conditions
+        bool windowsBorderlessHackCondition =
+            (env->getOS() == Environment::OS::OS_WINDOWS && env->isFullscreen() &&
+             env->isFullscreenWindowedBorderless() &&
+             (int)g_vInternalResolution.y == (int)env->getNativeScreenSize().y);  // HACKHACK
+        if(((int)g_vInternalResolution.x == engine->getScreenWidth() &&
+            (int)g_vInternalResolution.y == engine->getScreenHeight()) ||
+           !env->isFullscreen() || windowsBorderlessHackCondition) {
+            debugLog("Internal resolution == Engine resolution || !Fullscreen, disabling resampler (%i, %i)\n",
+                     (int)(g_vInternalResolution == engine->getScreenSize()), (int)(!env->isFullscreen()));
+            osu_resolution_enabled.setValue(0.0f);
+            g_vInternalResolution = engine->getScreenSize();
         }
         }
     }
     }
 
 
     // update dpi specific engine globals
     // update dpi specific engine globals
-    m_ui_scrollview_scrollbarwidth_ref->setValue(15.0f * Osu::getUIScale(this));  // not happy with this as a convar
+    m_ui_scrollview_scrollbarwidth_ref->setValue(15.0f * Osu::getUIScale());  // not happy with this as a convar
 
 
     // interfaces
     // interfaces
     for(int i = 0; i < m_screens.size(); i++) {
     for(int i = 0; i < m_screens.size(); i++) {
@@ -1905,7 +1822,7 @@ void Osu::onResolutionChanged(Vector2 newResolution) {
 
 
     // a bit hacky, but detect resolution-specific-dpi-scaling changes and force a font and layout reload after a 1
     // a bit hacky, but detect resolution-specific-dpi-scaling changes and force a font and layout reload after a 1
     // frame delay (1/2)
     // frame delay (1/2)
-    if(!LossyComparisonToFixExcessFPUPrecisionBugBecauseFuckYou::equalEpsilon(getUIScale(this), prevUIScale))
+    if(!LossyComparisonToFixExcessFPUPrecisionBugBecauseFuckYou::equalEpsilon(getUIScale(), prevUIScale))
         m_bFireDelayedFontReloadAndResolutionChangeToFixDesyncedUIScaleScheduled = true;
         m_bFireDelayedFontReloadAndResolutionChangeToFixDesyncedUIScaleScheduled = true;
 }
 }
 
 
@@ -1916,7 +1833,7 @@ void Osu::onDPIChanged() {
 }
 }
 
 
 void Osu::rebuildRenderTargets() {
 void Osu::rebuildRenderTargets() {
-    debugLog("Osu(%i)::rebuildRenderTargets: %fx%f\n", m_iInstanceID, g_vInternalResolution.x, g_vInternalResolution.y);
+    debugLog("Osu::rebuildRenderTargets: %fx%f\n", g_vInternalResolution.x, g_vInternalResolution.y);
 
 
     m_backBuffer->rebuild(0, 0, g_vInternalResolution.x, g_vInternalResolution.y);
     m_backBuffer->rebuild(0, 0, g_vInternalResolution.x, g_vInternalResolution.y);
 
 
@@ -1939,7 +1856,7 @@ void Osu::rebuildRenderTargets() {
 
 
 void Osu::reloadFonts() {
 void Osu::reloadFonts() {
     const int baseDPI = 96;
     const int baseDPI = 96;
-    const int newDPI = Osu::getUIScale(this) * baseDPI;
+    const int newDPI = Osu::getUIScale() * baseDPI;
 
 
     for(McFont *font : m_fonts) {
     for(McFont *font : m_fonts) {
         if(font->getDPI() != newDPI) {
         if(font->getDPI() != newDPI) {
@@ -1991,7 +1908,7 @@ void Osu::fireResolutionChanged() { onResolutionChanged(g_vInternalResolution);
 void Osu::onInternalResolutionChanged(UString oldValue, UString args) {
 void Osu::onInternalResolutionChanged(UString oldValue, UString args) {
     if(args.length() < 7) return;
     if(args.length() < 7) return;
 
 
-    const float prevUIScale = getUIScale(this);
+    const float prevUIScale = getUIScale();
 
 
     std::vector<UString> resolution = args.split("x");
     std::vector<UString> resolution = args.split("x");
     if(resolution.size() != 2)
     if(resolution.size() != 2)
@@ -2029,7 +1946,7 @@ void Osu::onInternalResolutionChanged(UString oldValue, UString args) {
 
 
     // a bit hacky, but detect resolution-specific-dpi-scaling changes and force a font and layout reload after a 1
     // a bit hacky, but detect resolution-specific-dpi-scaling changes and force a font and layout reload after a 1
     // frame delay (2/2)
     // frame delay (2/2)
-    if(getUIScale(this) != prevUIScale) m_bFireDelayedFontReloadAndResolutionChangeToFixDesyncedUIScaleScheduled = true;
+    if(getUIScale() != prevUIScale) m_bFireDelayedFontReloadAndResolutionChangeToFixDesyncedUIScaleScheduled = true;
 }
 }
 
 
 void Osu::onFocusGained() {
 void Osu::onFocusGained() {
@@ -2098,7 +2015,7 @@ void Osu::onSkinChange(UString oldValue, UString newValue) {
     skinFolder.append("/");
     skinFolder.append("/");
     std::string sf = skinFolder.toUtf8();
     std::string sf = skinFolder.toUtf8();
 
 
-    m_skinScheduledToLoad = new Skin(this, newValue, sf, (newValue == UString("default")));
+    m_skinScheduledToLoad = new Skin(newValue, sf, (newValue == UString("default")));
 
 
     // initial load
     // initial load
     if(m_skin == NULL) m_skin = m_skinScheduledToLoad;
     if(m_skin == NULL) m_skin = m_skinScheduledToLoad;
@@ -2189,8 +2106,6 @@ void Osu::onLetterboxingChange(UString oldValue, UString newValue) {
 void Osu::updateConfineCursor() {
 void Osu::updateConfineCursor() {
     if(debug->getBool()) debugLog("Osu::updateConfineCursor()\n");
     if(debug->getBool()) debugLog("Osu::updateConfineCursor()\n");
 
 
-    if(m_iInstanceID > 0) return;
-
     if((osu_confine_cursor_fullscreen.getBool() && env->isFullscreen()) ||
     if((osu_confine_cursor_fullscreen.getBool() && env->isFullscreen()) ||
        (osu_confine_cursor_windowed.getBool() && !env->isFullscreen()) ||
        (osu_confine_cursor_windowed.getBool() && !env->isFullscreen()) ||
        (isInPlayMode() && !m_pauseMenu->isVisible() && !getModAuto() && !getModAutopilot() &&
        (isInPlayMode() && !m_pauseMenu->isVisible() && !getModAuto() && !getModAutopilot() &&
@@ -2316,7 +2231,7 @@ float Osu::getImageScaleToFillResolution(Image *img, Vector2 resolution) {
     return getImageScaleToFillResolution(Vector2(img->getWidth(), img->getHeight()), resolution);
     return getImageScaleToFillResolution(Vector2(img->getWidth(), img->getHeight()), resolution);
 }
 }
 
 
-float Osu::getImageScale(Osu *osu, Vector2 size, float osuSize) {
+float Osu::getImageScale(Vector2 size, float osuSize) {
     int swidth = osu->getScreenWidth();
     int swidth = osu->getScreenWidth();
     int sheight = osu->getScreenHeight();
     int sheight = osu->getScreenHeight();
 
 
@@ -2334,11 +2249,11 @@ float Osu::getImageScale(Osu *osu, Vector2 size, float osuSize) {
     return xDiameter / size.x > yDiameter / size.y ? xDiameter / size.x : yDiameter / size.y;
     return xDiameter / size.x > yDiameter / size.y ? xDiameter / size.x : yDiameter / size.y;
 }
 }
 
 
-float Osu::getImageScale(Osu *osu, Image *img, float osuSize) {
-    return getImageScale(osu, Vector2(img->getWidth(), img->getHeight()), osuSize);
+float Osu::getImageScale(Image *img, float osuSize) {
+    return getImageScale(Vector2(img->getWidth(), img->getHeight()), osuSize);
 }
 }
 
 
-float Osu::getUIScale(Osu *osu, float osuResolutionRatio) {
+float Osu::getUIScale(float osuResolutionRatio) {
     int swidth = osu->getScreenWidth();
     int swidth = osu->getScreenWidth();
     int sheight = osu->getScreenHeight();
     int sheight = osu->getScreenHeight();
 
 
@@ -2356,7 +2271,7 @@ float Osu::getUIScale(Osu *osu, float osuResolutionRatio) {
     return xDiameter > yDiameter ? xDiameter : yDiameter;
     return xDiameter > yDiameter ? xDiameter : yDiameter;
 }
 }
 
 
-float Osu::getUIScale(Osu *osu) {
+float Osu::getUIScale() {
     if(osu != NULL) {
     if(osu != NULL) {
         if(osu->getScreenWidth() < osu_ui_scale_to_dpi_minimum_width.getInt() ||
         if(osu->getScreenWidth() < osu_ui_scale_to_dpi_minimum_width.getInt() ||
            osu->getScreenHeight() < osu_ui_scale_to_dpi_minimum_height.getInt())
            osu->getScreenHeight() < osu_ui_scale_to_dpi_minimum_height.getInt())

+ 43 - 55
src/App/Osu/Osu.h

@@ -1,13 +1,4 @@
-//================ Copyright (c) 2015, PG, All rights reserved. =================//
-//
-// Purpose:		yet another ouendan clone, because why not
-//
-// $NoKeywords: $osu
-//===============================================================================//
-
-#ifndef OSU_H
-#define OSU_H
-
+#pragma once
 #include "App.h"
 #include "App.h"
 #include "BanchoNetworking.h"
 #include "BanchoNetworking.h"
 #include "MouseListener.h"
 #include "MouseListener.h"
@@ -57,14 +48,14 @@ class Osu : public App, public MouseListener {
     static float getImageScaleToFitResolution(Vector2 size, Vector2 resolution);
     static float getImageScaleToFitResolution(Vector2 size, Vector2 resolution);
     static float getImageScaleToFillResolution(Vector2 size, Vector2 resolution);
     static float getImageScaleToFillResolution(Vector2 size, Vector2 resolution);
     static float getImageScaleToFillResolution(Image *img, Vector2 resolution);
     static float getImageScaleToFillResolution(Image *img, Vector2 resolution);
-    static float getImageScale(Osu *osu, Vector2 size, float osuSize);
-    static float getImageScale(Osu *osu, Image *img, float osuSize);
-    static float getUIScale(Osu *osu, float osuResolutionRatio);
-    static float getUIScale(Osu *osu);  // NOTE: includes premultiplied dpi scale!
+    static float getImageScale(Vector2 size, float osuSize);
+    static float getImageScale(Image *img, float osuSize);
+    static float getUIScale(float osuResolutionRatio);
+    static float getUIScale();  // NOTE: includes premultiplied dpi scale!
 
 
     static bool findIgnoreCase(const std::string &haystack, const std::string &needle);
     static bool findIgnoreCase(const std::string &haystack, const std::string &needle);
 
 
-    Osu(int instanceID = 0);
+    Osu();
     virtual ~Osu();
     virtual ~Osu();
 
 
     virtual void draw(Graphics *g);
     virtual void draw(Graphics *g);
@@ -90,7 +81,6 @@ class Osu : public App, public MouseListener {
     virtual void onMinimized();
     virtual void onMinimized();
     virtual bool onShutdown();
     virtual bool onShutdown();
 
 
-    void onPlayStart();  // called when a beatmap has successfully started playing
     void onPlayEnd(bool quit = true,
     void onPlayEnd(bool quit = true,
                    bool aborted = false);  // called when a beatmap is finished playing (or the player quit)
                    bool aborted = false);  // called when a beatmap is finished playing (or the player quit)
 
 
@@ -106,8 +96,6 @@ class Osu : public App, public MouseListener {
     void setSkin(UString skin) { onSkinChange("", skin); }
     void setSkin(UString skin) { onSkinChange("", skin); }
     void reloadSkin() { onSkinReload(); }
     void reloadSkin() { onSkinReload(); }
 
 
-    inline int getInstanceID() const { return m_iInstanceID; }
-
     inline Vector2 getScreenSize() const { return g_vInternalResolution; }
     inline Vector2 getScreenSize() const { return g_vInternalResolution; }
     inline int getScreenWidth() const { return (int)g_vInternalResolution.x; }
     inline int getScreenWidth() const { return (int)g_vInternalResolution.x; }
     inline int getScreenHeight() const { return (int)g_vInternalResolution.y; }
     inline int getScreenHeight() const { return (int)g_vInternalResolution.y; }
@@ -253,28 +241,28 @@ class Osu : public App, public MouseListener {
     ConVar *m_win_disable_windows_key_ref;
     ConVar *m_win_disable_windows_key_ref;
 
 
     // interfaces
     // interfaces
-    VolumeOverlay *m_volumeOverlay;
-    MainMenu *m_mainMenu;
-    OptionsMenu *m_optionsMenu;
+    VolumeOverlay *m_volumeOverlay = nullptr;
+    MainMenu *m_mainMenu = nullptr;
+    OptionsMenu *m_optionsMenu = nullptr;
     Chat *m_chat = nullptr;
     Chat *m_chat = nullptr;
     Lobby *m_lobby = nullptr;
     Lobby *m_lobby = nullptr;
     RoomScreen *m_room = nullptr;
     RoomScreen *m_room = nullptr;
     PromptScreen *m_prompt = nullptr;
     PromptScreen *m_prompt = nullptr;
     UIUserContextMenuScreen *m_user_actions = nullptr;
     UIUserContextMenuScreen *m_user_actions = nullptr;
     SongBrowser *m_songBrowser2 = nullptr;
     SongBrowser *m_songBrowser2 = nullptr;
-    BackgroundImageHandler *m_backgroundImageHandler;
-    ModSelector *m_modSelector;
-    RankingScreen *m_rankingScreen;
-    UserStatsScreen *m_userStatsScreen;
-    PauseMenu *m_pauseMenu;
-    Skin *m_skin;
-    HUD *m_hud;
-    TooltipOverlay *m_tooltipOverlay;
-    NotificationOverlay *m_notificationOverlay;
-    LiveScore *m_score;
-    Changelog *m_changelog;
-    UpdateHandler *m_updateHandler;
-    ModFPoSu *m_fposu;
+    BackgroundImageHandler *m_backgroundImageHandler = nullptr;
+    ModSelector *m_modSelector = nullptr;
+    RankingScreen *m_rankingScreen = nullptr;
+    UserStatsScreen *m_userStatsScreen = nullptr;
+    PauseMenu *m_pauseMenu = nullptr;
+    Skin *m_skin = nullptr;
+    HUD *m_hud = nullptr;
+    TooltipOverlay *m_tooltipOverlay = nullptr;
+    NotificationOverlay *m_notificationOverlay = nullptr;
+    LiveScore *m_score = nullptr;
+    Changelog *m_changelog = nullptr;
+    UpdateHandler *m_updateHandler = nullptr;
+    ModFPoSu *m_fposu = nullptr;
 
 
     std::vector<OsuScreen *> m_screens;
     std::vector<OsuScreen *> m_screens;
 
 
@@ -289,25 +277,25 @@ class Osu : public App, public MouseListener {
     bool holding_slider = false;
     bool holding_slider = false;
 
 
     // mods
     // mods
-    bool m_bModAuto;
-    bool m_bModAutopilot;
-    bool m_bModRelax;
-    bool m_bModSpunout;
-    bool m_bModTarget;
-    bool m_bModScorev2;
+    bool m_bModAuto = false;
+    bool m_bModAutopilot = false;
+    bool m_bModRelax = false;
+    bool m_bModSpunout = false;
+    bool m_bModTarget = false;
+    bool m_bModScorev2 = false;
     bool m_bModFlashlight = false;
     bool m_bModFlashlight = false;
-    bool m_bModDT;
-    bool m_bModNC;
-    bool m_bModNF;
-    bool m_bModHT;
-    bool m_bModDC;
-    bool m_bModHD;
-    bool m_bModHR;
-    bool m_bModEZ;
-    bool m_bModSD;
-    bool m_bModSS;
-    bool m_bModNightmare;
-    bool m_bModTD;
+    bool m_bModDT = false;
+    bool m_bModNC = false;
+    bool m_bModNF = false;
+    bool m_bModHT = false;
+    bool m_bModDC = false;
+    bool m_bModHD = false;
+    bool m_bModHR = false;
+    bool m_bModEZ = false;
+    bool m_bModSD = false;
+    bool m_bModSS = false;
+    bool m_bModNightmare = false;
+    bool m_bModTD = false;
 
 
     std::vector<ConVar *> m_experimentalMods;
     std::vector<ConVar *> m_experimentalMods;
 
 
@@ -356,12 +344,12 @@ class Osu : public App, public MouseListener {
     CWindowManager *m_windowManager;
     CWindowManager *m_windowManager;
 
 
     // replay
     // replay
-    FinishedScore replay_score;
+    UString watched_user_name;
+    u32 watched_user_id = 0;
 
 
     // custom
     // custom
     bool m_bScheduleEndlessModNextBeatmap;
     bool m_bScheduleEndlessModNextBeatmap;
     int m_iMultiplayerClientNumEscPresses;
     int m_iMultiplayerClientNumEscPresses;
-    int m_iInstanceID;
     bool m_bWasBossKeyPaused;
     bool m_bWasBossKeyPaused;
     bool m_bSkinLoadScheduled;
     bool m_bSkinLoadScheduled;
     bool m_bSkinLoadWasReload;
     bool m_bSkinLoadWasReload;
@@ -371,4 +359,4 @@ class Osu : public App, public MouseListener {
     bool m_bFireDelayedFontReloadAndResolutionChangeToFixDesyncedUIScaleScheduled;
     bool m_bFireDelayedFontReloadAndResolutionChangeToFixDesyncedUIScaleScheduled;
 };
 };
 
 
-#endif
+extern Osu *osu;

+ 2 - 19
src/App/Osu/OsuScreen.h

@@ -1,29 +1,12 @@
-//================ Copyright (c) 2016, PG, All rights reserved. =================//
-//
-// Purpose:		baseclass for any drawable screen state object of the game
-//
-// $NoKeywords: $
-//===============================================================================//
-
-#ifndef OSUSCREEN_H
-#define OSUSCREEN_H
-
+#pragma once
 #include "CBaseUIContainer.h"
 #include "CBaseUIContainer.h"
 #include "cbase.h"
 #include "cbase.h"
 
 
-class Osu;
 class KeyboardEvent;
 class KeyboardEvent;
 
 
 class OsuScreen : public CBaseUIContainer {
 class OsuScreen : public CBaseUIContainer {
    public:
    public:
-    OsuScreen(Osu *osu) {
-        m_osu = osu;
-        m_bVisible = false;
-    }
+    OsuScreen() { m_bVisible = false; }
 
 
     virtual void onResolutionChange(Vector2 newResolution) { (void)newResolution; }
     virtual void onResolutionChange(Vector2 newResolution) { (void)newResolution; }
-
-    Osu *m_osu;
 };
 };
-
-#endif

+ 66 - 52
src/App/Osu/PauseMenu.cpp

@@ -1,13 +1,7 @@
-//================ Copyright (c) 2016, PG, All rights reserved. =================//
-//
-// Purpose:		pause menu (while playing)
-//
-// $NoKeywords: $
-//===============================================================================//
-
 #include "PauseMenu.h"
 #include "PauseMenu.h"
 
 
 #include "AnimationHandler.h"
 #include "AnimationHandler.h"
+#include "Bancho.h"
 #include "Beatmap.h"
 #include "Beatmap.h"
 #include "CBaseUIContainer.h"
 #include "CBaseUIContainer.h"
 #include "Chat.h"
 #include "Chat.h"
@@ -31,7 +25,7 @@ ConVar osu_pause_dim_background("osu_pause_dim_background", true, FCVAR_DEFAULT)
 ConVar osu_pause_dim_alpha("osu_pause_dim_alpha", 0.58f, FCVAR_DEFAULT);
 ConVar osu_pause_dim_alpha("osu_pause_dim_alpha", 0.58f, FCVAR_DEFAULT);
 ConVar osu_pause_anim_duration("osu_pause_anim_duration", 0.15f, FCVAR_DEFAULT);
 ConVar osu_pause_anim_duration("osu_pause_anim_duration", 0.15f, FCVAR_DEFAULT);
 
 
-PauseMenu::PauseMenu(Osu *osu) : OsuScreen(osu) {
+PauseMenu::PauseMenu() : OsuScreen() {
     m_bScheduledVisibility = false;
     m_bScheduledVisibility = false;
     m_bScheduledVisibilityChange = false;
     m_bScheduledVisibilityChange = false;
 
 
@@ -48,11 +42,11 @@ PauseMenu::PauseMenu(Osu *osu) : OsuScreen(osu) {
 
 
     m_fDimAnim = 0.0f;
     m_fDimAnim = 0.0f;
 
 
-    setSize(m_osu->getScreenWidth(), m_osu->getScreenHeight());
+    setSize(osu->getScreenWidth(), osu->getScreenHeight());
 
 
-    UIPauseMenuButton *continueButton = addButton([this]() -> Image * { return m_osu->getSkin()->getPauseContinue(); });
-    UIPauseMenuButton *retryButton = addButton([this]() -> Image * { return m_osu->getSkin()->getPauseRetry(); });
-    UIPauseMenuButton *backButton = addButton([this]() -> Image * { return m_osu->getSkin()->getPauseBack(); });
+    UIPauseMenuButton *continueButton = addButton([]() -> Image * { return osu->getSkin()->getPauseContinue(); });
+    UIPauseMenuButton *retryButton = addButton([]() -> Image * { return osu->getSkin()->getPauseRetry(); });
+    UIPauseMenuButton *backButton = addButton([]() -> Image * { return osu->getSkin()->getPauseBack(); });
 
 
     continueButton->setClickCallback(fastdelegate::MakeDelegate(this, &PauseMenu::onContinueClicked));
     continueButton->setClickCallback(fastdelegate::MakeDelegate(this, &PauseMenu::onContinueClicked));
     retryButton->setClickCallback(fastdelegate::MakeDelegate(this, &PauseMenu::onRetryClicked));
     retryButton->setClickCallback(fastdelegate::MakeDelegate(this, &PauseMenu::onRetryClicked));
@@ -68,20 +62,20 @@ void PauseMenu::draw(Graphics *g) {
     // draw dim
     // draw dim
     if(osu_pause_dim_background.getBool()) {
     if(osu_pause_dim_background.getBool()) {
         g->setColor(COLORf(m_fDimAnim * osu_pause_dim_alpha.getFloat(), 0.078f, 0.078f, 0.078f));
         g->setColor(COLORf(m_fDimAnim * osu_pause_dim_alpha.getFloat(), 0.078f, 0.078f, 0.078f));
-        g->fillRect(0, 0, m_osu->getScreenWidth(), m_osu->getScreenHeight());
+        g->fillRect(0, 0, osu->getScreenWidth(), osu->getScreenHeight());
     }
     }
 
 
     // draw background image
     // draw background image
     if((m_bVisible || isAnimating)) {
     if((m_bVisible || isAnimating)) {
         Image *image = NULL;
         Image *image = NULL;
         if(m_bContinueEnabled)
         if(m_bContinueEnabled)
-            image = m_osu->getSkin()->getPauseOverlay();
+            image = osu->getSkin()->getPauseOverlay();
         else
         else
-            image = m_osu->getSkin()->getFailBackground();
+            image = osu->getSkin()->getFailBackground();
 
 
-        if(image != m_osu->getSkin()->getMissingTexture()) {
-            const float scale = Osu::getImageScaleToFillResolution(image, m_osu->getScreenSize());
-            const Vector2 centerTrans = (m_osu->getScreenSize() / 2);
+        if(image != osu->getSkin()->getMissingTexture()) {
+            const float scale = Osu::getImageScaleToFillResolution(image, osu->getScreenSize());
+            const Vector2 centerTrans = (osu->getScreenSize() / 2);
 
 
             g->setColor(COLORf(m_fDimAnim, 1.0f, 1.0f, 1.0f));
             g->setColor(COLORf(m_fDimAnim, 1.0f, 1.0f, 1.0f));
             g->pushTransform();
             g->pushTransform();
@@ -107,19 +101,18 @@ void PauseMenu::draw(Graphics *g) {
         if(animation > 1.0f) animation = 2.0f - animation;
         if(animation > 1.0f) animation = 2.0f - animation;
 
 
         animation = -animation * (animation - 2);  // quad out
         animation = -animation * (animation - 2);  // quad out
-        const float offset = m_osu->getUIScale(m_osu, 20.0f + 45.0f * animation);
+        const float offset = osu->getUIScale(20.0f + 45.0f * animation);
 
 
         g->setColor(arrowColor);
         g->setColor(arrowColor);
         g->setAlpha(m_fWarningArrowsAnimAlpha * m_fDimAnim);
         g->setAlpha(m_fWarningArrowsAnimAlpha * m_fDimAnim);
-        m_osu->getHUD()->drawWarningArrow(g,
-                                          Vector2(m_fWarningArrowsAnimX, m_fWarningArrowsAnimY) +
-                                              Vector2(0, m_selectedButton->getSize().y / 2) - Vector2(offset, 0),
-                                          false, false);
-        m_osu->getHUD()->drawWarningArrow(
-            g,
-            Vector2(m_osu->getScreenWidth() - m_fWarningArrowsAnimX, m_fWarningArrowsAnimY) +
-                Vector2(0, m_selectedButton->getSize().y / 2) + Vector2(offset, 0),
-            true, false);
+        osu->getHUD()->drawWarningArrow(g,
+                                        Vector2(m_fWarningArrowsAnimX, m_fWarningArrowsAnimY) +
+                                            Vector2(0, m_selectedButton->getSize().y / 2) - Vector2(offset, 0),
+                                        false, false);
+        osu->getHUD()->drawWarningArrow(g,
+                                        Vector2(osu->getScreenWidth() - m_fWarningArrowsAnimX, m_fWarningArrowsAnimY) +
+                                            Vector2(0, m_selectedButton->getSize().y / 2) + Vector2(offset, 0),
+                                        true, false);
     }
     }
 }
 }
 
 
@@ -141,8 +134,8 @@ void PauseMenu::onContinueClicked() {
     if(!m_bContinueEnabled) return;
     if(!m_bContinueEnabled) return;
     if(anim->isAnimating(&m_fDimAnim)) return;
     if(anim->isAnimating(&m_fDimAnim)) return;
 
 
-    engine->getSound()->play(m_osu->getSkin()->getMenuHit());
-    m_osu->getSelectedBeatmap()->pause();
+    engine->getSound()->play(osu->getSkin()->getMenuHit());
+    osu->getSelectedBeatmap()->pause();
 
 
     scheduleVisibilityChange(false);
     scheduleVisibilityChange(false);
 }
 }
@@ -150,8 +143,8 @@ void PauseMenu::onContinueClicked() {
 void PauseMenu::onRetryClicked() {
 void PauseMenu::onRetryClicked() {
     if(anim->isAnimating(&m_fDimAnim)) return;
     if(anim->isAnimating(&m_fDimAnim)) return;
 
 
-    engine->getSound()->play(m_osu->getSkin()->getMenuHit());
-    m_osu->getSelectedBeatmap()->restart();
+    engine->getSound()->play(osu->getSkin()->getMenuHit());
+    osu->getSelectedBeatmap()->restart();
 
 
     scheduleVisibilityChange(false);
     scheduleVisibilityChange(false);
 }
 }
@@ -159,8 +152,8 @@ void PauseMenu::onRetryClicked() {
 void PauseMenu::onBackClicked() {
 void PauseMenu::onBackClicked() {
     if(anim->isAnimating(&m_fDimAnim)) return;
     if(anim->isAnimating(&m_fDimAnim)) return;
 
 
-    engine->getSound()->play(m_osu->getSkin()->getMenuHit());
-    m_osu->getSelectedBeatmap()->stop();
+    engine->getSound()->play(osu->getSkin()->getMenuHit());
+    osu->getSelectedBeatmap()->stop();
 
 
     scheduleVisibilityChange(false);
     scheduleVisibilityChange(false);
 }
 }
@@ -171,7 +164,7 @@ void PauseMenu::onSelectionChange() {
             m_bInitialWarningArrowFlyIn = false;
             m_bInitialWarningArrowFlyIn = false;
 
 
             m_fWarningArrowsAnimY = m_selectedButton->getPos().y;
             m_fWarningArrowsAnimY = m_selectedButton->getPos().y;
-            m_fWarningArrowsAnimX = m_selectedButton->getPos().x - m_osu->getUIScale(m_osu, 170.0f);
+            m_fWarningArrowsAnimX = m_selectedButton->getPos().x - osu->getUIScale(170.0f);
 
 
             anim->moveLinear(&m_fWarningArrowsAnimAlpha, 1.0f, 0.3f);
             anim->moveLinear(&m_fWarningArrowsAnimAlpha, 1.0f, 0.3f);
             anim->moveQuadIn(&m_fWarningArrowsAnimX, m_selectedButton->getPos().x, 0.3f);
             anim->moveQuadIn(&m_fWarningArrowsAnimX, m_selectedButton->getPos().x, 0.3f);
@@ -180,7 +173,7 @@ void PauseMenu::onSelectionChange() {
 
 
         anim->moveQuadOut(&m_fWarningArrowsAnimY, m_selectedButton->getPos().y, 0.1f);
         anim->moveQuadOut(&m_fWarningArrowsAnimY, m_selectedButton->getPos().y, 0.1f);
 
 
-        engine->getSound()->play(m_osu->getSkin()->getMenuClick());
+        engine->getSound()->play(osu->getSkin()->getMenuClick());
     }
     }
 }
 }
 
 
@@ -301,17 +294,16 @@ void PauseMenu::scheduleVisibilityChange(bool visible) {
 }
 }
 
 
 void PauseMenu::updateLayout() {
 void PauseMenu::updateLayout() {
-    const float height = (m_osu->getScreenHeight() / (float)m_buttons.size());
+    const float height = (osu->getScreenHeight() / (float)m_buttons.size());
     const float half = (m_buttons.size() - 1) / 2.0f;
     const float half = (m_buttons.size() - 1) / 2.0f;
 
 
     float maxWidth = 0.0f;
     float maxWidth = 0.0f;
     float maxHeight = 0.0f;
     float maxHeight = 0.0f;
     for(int i = 0; i < m_buttons.size(); i++) {
     for(int i = 0; i < m_buttons.size(); i++) {
         Image *img = m_buttons[i]->getImage();
         Image *img = m_buttons[i]->getImage();
-        if(img == NULL) img = m_osu->getSkin()->getMissingTexture();
+        if(img == NULL) img = osu->getSkin()->getMissingTexture();
 
 
-        const float scale =
-            m_osu->getUIScale(m_osu, 256) / (411.0f * (m_osu->getSkin()->isPauseContinue2x() ? 2.0f : 1.0f));
+        const float scale = osu->getUIScale(256) / (411.0f * (osu->getSkin()->isPauseContinue2x() ? 2.0f : 1.0f));
 
 
         m_buttons[i]->setBaseScale(scale, scale);
         m_buttons[i]->setBaseScale(scale, scale);
         m_buttons[i]->setSize(img->getWidth() * scale, img->getHeight() * scale);
         m_buttons[i]->setSize(img->getWidth() * scale, img->getHeight() * scale);
@@ -322,7 +314,7 @@ void PauseMenu::updateLayout() {
 
 
     for(int i = 0; i < m_buttons.size(); i++) {
     for(int i = 0; i < m_buttons.size(); i++) {
         Vector2 newPos =
         Vector2 newPos =
-            Vector2(m_osu->getScreenWidth() / 2.0f - maxWidth / 2, (i + 1) * height - height / 2.0f - maxHeight / 2.0f);
+            Vector2(osu->getScreenWidth() / 2.0f - maxWidth / 2, (i + 1) * height - height / 2.0f - maxHeight / 2.0f);
 
 
         const float pinch = std::max(0.0f, (height / 2.0f - maxHeight / 2.0f));
         const float pinch = std::max(0.0f, (height / 2.0f - maxHeight / 2.0f));
         if((float)i < half)
         if((float)i < half)
@@ -345,24 +337,46 @@ void PauseMenu::onResolutionChange(Vector2 newResolution) {
 CBaseUIContainer *PauseMenu::setVisible(bool visible) {
 CBaseUIContainer *PauseMenu::setVisible(bool visible) {
     m_bVisible = visible;
     m_bVisible = visible;
 
 
-    if(m_osu->isInPlayMode())
-        setContinueEnabled(!m_osu->getSelectedBeatmap()->hasFailed());
+    if(osu->isInPlayMode())
+        setContinueEnabled(!osu->getSelectedBeatmap()->hasFailed());
     else
     else
         setContinueEnabled(true);
         setContinueEnabled(true);
 
 
     if(visible) {
     if(visible) {
         if(m_bContinueEnabled) {
         if(m_bContinueEnabled) {
-            RichPresence::setStatus(m_osu, "Paused");
-            RichPresence::setBanchoStatus(m_osu, "Taking a break", PAUSED);
+            RichPresence::setStatus("Paused");
+            RichPresence::setBanchoStatus("Taking a break", PAUSED);
+
+            if(!bancho.spectators.empty()) {
+                Packet packet;
+                packet.id = SPECTATE_FRAMES;
+                write<i32>(&packet, 0);
+                write<u16>(&packet, 0);
+                write<u8>(&packet, LiveReplayBundle::Action::PAUSE);
+                write<ScoreFrame>(&packet, ScoreFrame::get());
+                write<u16>(&packet, osu->getSelectedBeatmap()->spectator_sequence++);
+                send_packet(packet);
+            }
         } else {
         } else {
-            RichPresence::setBanchoStatus(m_osu, "Failed", SUBMITTING);
+            RichPresence::setBanchoStatus("Failed", SUBMITTING);
         }
         }
     } else {
     } else {
-        RichPresence::onPlayStart(m_osu);
+        RichPresence::onPlayStart();
+
+        if(!bancho.spectators.empty()) {
+            Packet packet;
+            packet.id = SPECTATE_FRAMES;
+            write<i32>(&packet, 0);
+            write<u16>(&packet, 0);
+            write<u8>(&packet, LiveReplayBundle::Action::UNPAUSE);
+            write<ScoreFrame>(&packet, ScoreFrame::get());
+            write<u16>(&packet, osu->getSelectedBeatmap()->spectator_sequence++);
+            send_packet(packet);
+        }
     }
     }
 
 
     // HACKHACK: force disable mod selection screen in case it was open and the beatmap ended/failed
     // HACKHACK: force disable mod selection screen in case it was open and the beatmap ended/failed
-    m_osu->getModSelector()->setVisible(false);
+    osu->getModSelector()->setVisible(false);
 
 
     // reset
     // reset
     m_selectedButton = NULL;
     m_selectedButton = NULL;
@@ -373,12 +387,12 @@ CBaseUIContainer *PauseMenu::setVisible(bool visible) {
 
 
     if(m_bVisible) updateLayout();
     if(m_bVisible) updateLayout();
 
 
-    m_osu->updateConfineCursor();
-    m_osu->updateWindowsKeyDisable();
+    osu->updateConfineCursor();
+    osu->updateWindowsKeyDisable();
 
 
     anim->moveQuadOut(&m_fDimAnim, (m_bVisible ? 1.0f : 0.0f),
     anim->moveQuadOut(&m_fDimAnim, (m_bVisible ? 1.0f : 0.0f),
                       osu_pause_anim_duration.getFloat() * (m_bVisible ? 1.0f - m_fDimAnim : m_fDimAnim), true);
                       osu_pause_anim_duration.getFloat() * (m_bVisible ? 1.0f - m_fDimAnim : m_fDimAnim), true);
-    m_osu->m_chat->updateVisibility();
+    osu->m_chat->updateVisibility();
     return this;
     return this;
 }
 }
 
 
@@ -388,7 +402,7 @@ void PauseMenu::setContinueEnabled(bool continueEnabled) {
 }
 }
 
 
 UIPauseMenuButton *PauseMenu::addButton(std::function<Image *()> getImageFunc) {
 UIPauseMenuButton *PauseMenu::addButton(std::function<Image *()> getImageFunc) {
-    UIPauseMenuButton *button = new UIPauseMenuButton(m_osu, getImageFunc, 0, 0, 0, 0, "");
+    UIPauseMenuButton *button = new UIPauseMenuButton(getImageFunc, 0, 0, 0, 0, "");
     addBaseUIElement(button);
     addBaseUIElement(button);
     m_buttons.push_back(button);
     m_buttons.push_back(button);
     return button;
     return button;

+ 2 - 14
src/App/Osu/PauseMenu.h

@@ -1,23 +1,13 @@
-//================ Copyright (c) 2016, PG, All rights reserved. =================//
-//
-// Purpose:		pause menu (while playing)
-//
-// $NoKeywords: $
-//===============================================================================//
-
-#ifndef OSUPAUSEMENU_H
-#define OSUPAUSEMENU_H
-
+#pragma once
 #include "OsuScreen.h"
 #include "OsuScreen.h"
 
 
-class Osu;
 class SongBrowser;
 class SongBrowser;
 class CBaseUIContainer;
 class CBaseUIContainer;
 class UIPauseMenuButton;
 class UIPauseMenuButton;
 
 
 class PauseMenu : public OsuScreen {
 class PauseMenu : public OsuScreen {
    public:
    public:
-    PauseMenu(Osu *osu);
+    PauseMenu();
 
 
     virtual void draw(Graphics *g);
     virtual void draw(Graphics *g);
     virtual void mouse_update(bool *propagate_clicks);
     virtual void mouse_update(bool *propagate_clicks);
@@ -62,5 +52,3 @@ class PauseMenu : public OsuScreen {
 
 
     float m_fDimAnim;
     float m_fDimAnim;
 };
 };
-
-#endif

+ 4 - 4
src/App/Osu/PromptScreen.cpp

@@ -6,7 +6,7 @@
 #include "Osu.h"
 #include "Osu.h"
 #include "UIButton.h"
 #include "UIButton.h"
 
 
-PromptScreen::PromptScreen(Osu *osu) : OsuScreen(osu) {
+PromptScreen::PromptScreen() : OsuScreen() {
     m_prompt_label = new CBaseUILabel(0, 0, 0, 0, "", "");
     m_prompt_label = new CBaseUILabel(0, 0, 0, 0, "", "");
     m_prompt_label->setDrawFrame(false);
     m_prompt_label->setDrawFrame(false);
     m_prompt_label->setDrawBackground(false);
     m_prompt_label->setDrawBackground(false);
@@ -15,13 +15,13 @@ PromptScreen::PromptScreen(Osu *osu) : OsuScreen(osu) {
     m_prompt_input = new CBaseUITextbox(0, 0, 400, 40, "");
     m_prompt_input = new CBaseUITextbox(0, 0, 400, 40, "");
     addBaseUIElement(m_prompt_input);
     addBaseUIElement(m_prompt_input);
 
 
-    m_ok_btn = new UIButton(osu, 0, 0, 110, 35, "ok_btn", "OK");
+    m_ok_btn = new UIButton(0, 0, 110, 35, "ok_btn", "OK");
     m_ok_btn->setColor(0xff00ff00);
     m_ok_btn->setColor(0xff00ff00);
     m_ok_btn->setUseDefaultSkin();
     m_ok_btn->setUseDefaultSkin();
     m_ok_btn->setClickCallback(fastdelegate::MakeDelegate(this, &PromptScreen::on_ok));
     m_ok_btn->setClickCallback(fastdelegate::MakeDelegate(this, &PromptScreen::on_ok));
     addBaseUIElement(m_ok_btn);
     addBaseUIElement(m_ok_btn);
 
 
-    m_cancel_btn = new UIButton(osu, 0, 0, 110, 35, "cancel_btn", "Cancel");
+    m_cancel_btn = new UIButton(0, 0, 110, 35, "cancel_btn", "Cancel");
     m_cancel_btn->setColor(0xff0e94b5);
     m_cancel_btn->setColor(0xff0e94b5);
     m_cancel_btn->setUseDefaultSkin();
     m_cancel_btn->setUseDefaultSkin();
     m_cancel_btn->setClickCallback(fastdelegate::MakeDelegate(this, &PromptScreen::on_cancel));
     m_cancel_btn->setClickCallback(fastdelegate::MakeDelegate(this, &PromptScreen::on_cancel));
@@ -97,7 +97,7 @@ void PromptScreen::prompt(UString msg, PromptResponseCallback callback) {
     m_callback = callback;
     m_callback = callback;
     m_bVisible = true;
     m_bVisible = true;
 
 
-    onResolutionChange(m_osu->getScreenSize());
+    onResolutionChange(osu->getScreenSize());
 }
 }
 
 
 void PromptScreen::on_ok() {
 void PromptScreen::on_ok() {

+ 1 - 2
src/App/Osu/PromptScreen.h

@@ -4,12 +4,11 @@
 class CBaseUILabel;
 class CBaseUILabel;
 class CBaseUITextbox;
 class CBaseUITextbox;
 class Graphics;
 class Graphics;
-class Osu;
 class UIButton;
 class UIButton;
 
 
 class PromptScreen : public OsuScreen {
 class PromptScreen : public OsuScreen {
    public:
    public:
-    PromptScreen(Osu *osu);
+    PromptScreen();
     virtual void onResolutionChange(Vector2 newResolution);
     virtual void onResolutionChange(Vector2 newResolution);
 
 
     virtual void draw(Graphics *g);
     virtual void draw(Graphics *g);

+ 113 - 114
src/App/Osu/RankingScreen.cpp

@@ -154,7 +154,7 @@ class RankingScreenScrollDownInfoButton : public CBaseUIButton {
     float m_fAlpha;
     float m_fAlpha;
 };
 };
 
 
-RankingScreen::RankingScreen(Osu *osu) : ScreenBackable(osu) {
+RankingScreen::RankingScreen() : ScreenBackable() {
     m_osu_scores_enabled = convar->getConVarByName("osu_scores_enabled");
     m_osu_scores_enabled = convar->getConVarByName("osu_scores_enabled");
 
 
     m_rankings = new CBaseUIScrollView(-1, 0, 0, 0, "");
     m_rankings = new CBaseUIScrollView(-1, 0, 0, 0, "");
@@ -165,20 +165,20 @@ RankingScreen::RankingScreen(Osu *osu) : ScreenBackable(osu) {
     m_rankings->setDrawScrollbars(true);
     m_rankings->setDrawScrollbars(true);
     addBaseUIElement(m_rankings);
     addBaseUIElement(m_rankings);
 
 
-    m_songInfo = new UIRankingScreenInfoLabel(m_osu, 5, 5, 0, 0, "");
+    m_songInfo = new UIRankingScreenInfoLabel(5, 5, 0, 0, "");
     addBaseUIElement(m_songInfo);
     addBaseUIElement(m_songInfo);
 
 
-    m_rankingTitle = new CBaseUIImage(m_osu->getSkin()->getRankingTitle()->getName(), 0, 0, 0, 0, "");
+    m_rankingTitle = new CBaseUIImage(osu->getSkin()->getRankingTitle()->getName(), 0, 0, 0, 0, "");
     m_rankingTitle->setDrawBackground(false);
     m_rankingTitle->setDrawBackground(false);
     m_rankingTitle->setDrawFrame(false);
     m_rankingTitle->setDrawFrame(false);
     addBaseUIElement(m_rankingTitle);
     addBaseUIElement(m_rankingTitle);
 
 
-    m_rankingPanel = new UIRankingScreenRankingPanel(osu);
+    m_rankingPanel = new UIRankingScreenRankingPanel();
     m_rankingPanel->setDrawBackground(false);
     m_rankingPanel->setDrawBackground(false);
     m_rankingPanel->setDrawFrame(false);
     m_rankingPanel->setDrawFrame(false);
     m_rankings->getContainer()->addBaseUIElement(m_rankingPanel);
     m_rankings->getContainer()->addBaseUIElement(m_rankingPanel);
 
 
-    m_rankingGrade = new CBaseUIImage(m_osu->getSkin()->getRankingA()->getName(), 0, 0, 0, 0, "");
+    m_rankingGrade = new CBaseUIImage(osu->getSkin()->getRankingA()->getName(), 0, 0, 0, 0, "");
     m_rankingGrade->setDrawBackground(false);
     m_rankingGrade->setDrawBackground(false);
     m_rankingGrade->setDrawFrame(false);
     m_rankingGrade->setDrawFrame(false);
     m_rankings->getContainer()->addBaseUIElement(m_rankingGrade);
     m_rankings->getContainer()->addBaseUIElement(m_rankingGrade);
@@ -189,12 +189,12 @@ RankingScreen::RankingScreen(Osu *osu) : ScreenBackable(osu) {
     m_rankingIndex = new RankingScreenIndexLabel();
     m_rankingIndex = new RankingScreenIndexLabel();
     m_rankingIndex->setDrawFrame(false);
     m_rankingIndex->setDrawFrame(false);
     m_rankingIndex->setCenterText(true);
     m_rankingIndex->setCenterText(true);
-    m_rankingIndex->setFont(m_osu->getSongBrowserFont());
+    m_rankingIndex->setFont(osu->getSongBrowserFont());
     m_rankingIndex->setTextColor(0xffffcb21);
     m_rankingIndex->setTextColor(0xffffcb21);
     m_rankings->getContainer()->addBaseUIElement(m_rankingIndex);
     m_rankings->getContainer()->addBaseUIElement(m_rankingIndex);
 
 
     m_rankingScrollDownInfoButton = new RankingScreenScrollDownInfoButton();
     m_rankingScrollDownInfoButton = new RankingScreenScrollDownInfoButton();
-    m_rankingScrollDownInfoButton->setFont(m_osu->getFontIcons());
+    m_rankingScrollDownInfoButton->setFont(osu->getFontIcons());
     m_rankingScrollDownInfoButton->setClickCallback(
     m_rankingScrollDownInfoButton->setClickCallback(
         fastdelegate::MakeDelegate(this, &RankingScreen::onScrollDownClicked));
         fastdelegate::MakeDelegate(this, &RankingScreen::onScrollDownClicked));
     UString iconString;
     UString iconString;
@@ -251,40 +251,40 @@ void RankingScreen::draw(Graphics *g) {
     if(!m_bVisible) return;
     if(!m_bVisible) return;
 
 
     // draw background image
     // draw background image
-    if(osu_draw_rankingscreen_background_image.getBool()) SongBrowser::drawSelectedBeatmapBackgroundImage(g, m_osu);
+    if(osu_draw_rankingscreen_background_image.getBool()) SongBrowser::drawSelectedBeatmapBackgroundImage(g);
 
 
     m_rankings->draw(g);
     m_rankings->draw(g);
 
 
     // draw active mods
     // draw active mods
-    const Vector2 modPosStart = Vector2(m_rankings->getSize().x - m_osu->getUIScale(m_osu, 20),
-                                        m_rankings->getScrollPosY() + m_osu->getUIScale(m_osu, 260));
+    const Vector2 modPosStart =
+        Vector2(m_rankings->getSize().x - osu->getUIScale(20), m_rankings->getScrollPosY() + osu->getUIScale(260));
     Vector2 modPos = modPosStart;
     Vector2 modPos = modPosStart;
     Vector2 modPosMax;
     Vector2 modPosMax;
-    if(m_bModTD) drawModImage(g, m_osu->getSkin()->getSelectionModTD(), modPos, modPosMax);
+    if(m_bModTD) drawModImage(g, osu->getSkin()->getSelectionModTD(), modPos, modPosMax);
     if(m_bModSS)
     if(m_bModSS)
-        drawModImage(g, m_osu->getSkin()->getSelectionModPerfect(), modPos, modPosMax);
+        drawModImage(g, osu->getSkin()->getSelectionModPerfect(), modPos, modPosMax);
     else if(m_bModSD)
     else if(m_bModSD)
-        drawModImage(g, m_osu->getSkin()->getSelectionModSuddenDeath(), modPos, modPosMax);
-    if(m_bModEZ) drawModImage(g, m_osu->getSkin()->getSelectionModEasy(), modPos, modPosMax);
-    if(m_bModHD) drawModImage(g, m_osu->getSkin()->getSelectionModHidden(), modPos, modPosMax);
-    if(m_bModHR) drawModImage(g, m_osu->getSkin()->getSelectionModHardRock(), modPos, modPosMax);
+        drawModImage(g, osu->getSkin()->getSelectionModSuddenDeath(), modPos, modPosMax);
+    if(m_bModEZ) drawModImage(g, osu->getSkin()->getSelectionModEasy(), modPos, modPosMax);
+    if(m_bModHD) drawModImage(g, osu->getSkin()->getSelectionModHidden(), modPos, modPosMax);
+    if(m_bModHR) drawModImage(g, osu->getSkin()->getSelectionModHardRock(), modPos, modPosMax);
     if(m_bModNC)
     if(m_bModNC)
-        drawModImage(g, m_osu->getSkin()->getSelectionModNightCore(), modPos, modPosMax);
+        drawModImage(g, osu->getSkin()->getSelectionModNightCore(), modPos, modPosMax);
     else if(m_bModDT)
     else if(m_bModDT)
-        drawModImage(g, m_osu->getSkin()->getSelectionModDoubleTime(), modPos, modPosMax);
-    if(m_bModNightmare) drawModImage(g, m_osu->getSkin()->getSelectionModNightmare(), modPos, modPosMax);
-    if(m_bModScorev2) drawModImage(g, m_osu->getSkin()->getSelectionModScorev2(), modPos, modPosMax);
-    if(m_bModTarget) drawModImage(g, m_osu->getSkin()->getSelectionModTarget(), modPos, modPosMax);
-    if(m_bModSpunout) drawModImage(g, m_osu->getSkin()->getSelectionModSpunOut(), modPos, modPosMax);
-    if(m_bModRelax) drawModImage(g, m_osu->getSkin()->getSelectionModRelax(), modPos, modPosMax);
-    if(m_bModNF) drawModImage(g, m_osu->getSkin()->getSelectionModNoFail(), modPos, modPosMax);
-    if(m_bModHT) drawModImage(g, m_osu->getSkin()->getSelectionModHalfTime(), modPos, modPosMax);
-    if(m_bModAutopilot) drawModImage(g, m_osu->getSkin()->getSelectionModAutopilot(), modPos, modPosMax);
-    if(m_bModAuto) drawModImage(g, m_osu->getSkin()->getSelectionModAutoplay(), modPos, modPosMax);
+        drawModImage(g, osu->getSkin()->getSelectionModDoubleTime(), modPos, modPosMax);
+    if(m_bModNightmare) drawModImage(g, osu->getSkin()->getSelectionModNightmare(), modPos, modPosMax);
+    if(m_bModScorev2) drawModImage(g, osu->getSkin()->getSelectionModScorev2(), modPos, modPosMax);
+    if(m_bModTarget) drawModImage(g, osu->getSkin()->getSelectionModTarget(), modPos, modPosMax);
+    if(m_bModSpunout) drawModImage(g, osu->getSkin()->getSelectionModSpunOut(), modPos, modPosMax);
+    if(m_bModRelax) drawModImage(g, osu->getSkin()->getSelectionModRelax(), modPos, modPosMax);
+    if(m_bModNF) drawModImage(g, osu->getSkin()->getSelectionModNoFail(), modPos, modPosMax);
+    if(m_bModHT) drawModImage(g, osu->getSkin()->getSelectionModHalfTime(), modPos, modPosMax);
+    if(m_bModAutopilot) drawModImage(g, osu->getSkin()->getSelectionModAutopilot(), modPos, modPosMax);
+    if(m_bModAuto) drawModImage(g, osu->getSkin()->getSelectionModAutoplay(), modPos, modPosMax);
 
 
     // draw experimental mods
     // draw experimental mods
     if(m_enabledExperimentalMods.size() > 0) {
     if(m_enabledExperimentalMods.size() > 0) {
-        McFont *experimentalModFont = m_osu->getSubTitleFont();
+        McFont *experimentalModFont = osu->getSubTitleFont();
         const UString prefix = "+ ";
         const UString prefix = "+ ";
 
 
         float maxStringWidth = 0.0f;
         float maxStringWidth = 0.0f;
@@ -299,7 +299,7 @@ void RankingScreen::draw(Graphics *g) {
         const float heightMultiplier = 1.25f;
         const float heightMultiplier = 1.25f;
         const int experimentalModHeight = (experimentalModFont->getHeight() * heightMultiplier);
         const int experimentalModHeight = (experimentalModFont->getHeight() * heightMultiplier);
         const Vector2 experimentalModPos = Vector2(modPosStart.x - maxStringWidth - backgroundMargin,
         const Vector2 experimentalModPos = Vector2(modPosStart.x - maxStringWidth - backgroundMargin,
-                                                   std::max(modPosStart.y, modPosMax.y) + m_osu->getUIScale(m_osu, 10) +
+                                                   std::max(modPosStart.y, modPosMax.y) + osu->getUIScale(10) +
                                                        experimentalModFont->getHeight() * heightMultiplier);
                                                        experimentalModFont->getHeight() * heightMultiplier);
         const int backgroundWidth = maxStringWidth + 2 * backgroundMargin;
         const int backgroundWidth = maxStringWidth + 2 * backgroundMargin;
         const int backgroundHeight = experimentalModHeight * m_enabledExperimentalMods.size() + 2 * backgroundMargin;
         const int backgroundHeight = experimentalModHeight * m_enabledExperimentalMods.size() + 2 * backgroundMargin;
@@ -339,10 +339,10 @@ void RankingScreen::draw(Graphics *g) {
         {
         {
             g->translate((int)ppPos.x + 2, (int)ppPos.y + 2);
             g->translate((int)ppPos.x + 2, (int)ppPos.y + 2);
             g->setColor(0xff000000);
             g->setColor(0xff000000);
-            g->drawString(m_osu->getTitleFont(), ppString);
+            g->drawString(osu->getTitleFont(), ppString);
             g->translate(-2, -2);
             g->translate(-2, -2);
             g->setColor(0xffffffff);
             g->setColor(0xffffffff);
-            g->drawString(m_osu->getTitleFont(), ppString);
+            g->drawString(osu->getTitleFont(), ppString);
         }
         }
         g->popTransform();
         g->popTransform();
     }
     }
@@ -351,7 +351,7 @@ void RankingScreen::draw(Graphics *g) {
 
 
     // draw top black bar
     // draw top black bar
     g->setColor(0xff000000);
     g->setColor(0xff000000);
-    g->fillRect(0, 0, m_osu->getScreenWidth(),
+    g->fillRect(0, 0, osu->getScreenWidth(),
                 m_rankingTitle->getSize().y * osu_rankingscreen_topbar_height_percent.getFloat());
                 m_rankingTitle->getSize().y * osu_rankingscreen_topbar_height_percent.getFloat());
 
 
     m_rankingTitle->draw(g);
     m_rankingTitle->draw(g);
@@ -364,7 +364,7 @@ void RankingScreen::drawModImage(Graphics *g, SkinImage *image, Vector2 &pos, Ve
     g->setColor(0xffffffff);
     g->setColor(0xffffffff);
     image->draw(g, Vector2(pos.x - image->getSize().x / 2.0f, pos.y));
     image->draw(g, Vector2(pos.x - image->getSize().x / 2.0f, pos.y));
 
 
-    pos.x -= m_osu->getUIScale(m_osu, 20);
+    pos.x -= osu->getUIScale(20);
 
 
     if(pos.y + image->getSize().y / 2 > max.y) max.y = pos.y + image->getSize().y / 2;
     if(pos.y + image->getSize().y / 2 > max.y) max.y = pos.y + image->getSize().y / 2;
 }
 }
@@ -374,32 +374,32 @@ void RankingScreen::mouse_update(bool *propagate_clicks) {
     ScreenBackable::mouse_update(propagate_clicks);
     ScreenBackable::mouse_update(propagate_clicks);
 
 
     // HACKHACK:
     // HACKHACK:
-    if(m_osu->getOptionsMenu()->isMouseInside()) engine->getMouse()->resetWheelDelta();
+    if(osu->getOptionsMenu()->isMouseInside()) engine->getMouse()->resetWheelDelta();
 
 
     // tooltip (pp + accuracy + unstable rate)
     // tooltip (pp + accuracy + unstable rate)
-    if(!m_osu->getOptionsMenu()->isMouseInside() && !m_bIsLegacyScore &&
-       engine->getMouse()->getPos().x < m_osu->getScreenWidth() * 0.5f) {
-        m_osu->getTooltipOverlay()->begin();
+    if(!osu->getOptionsMenu()->isMouseInside() && !m_bIsLegacyScore &&
+       engine->getMouse()->getPos().x < osu->getScreenWidth() * 0.5f) {
+        osu->getTooltipOverlay()->begin();
         {
         {
-            m_osu->getTooltipOverlay()->addLine(UString::format("%.2fpp", m_fPPv2));
-            m_osu->getTooltipOverlay()->addLine("Difficulty:");
-            m_osu->getTooltipOverlay()->addLine(UString::format("Stars: %.2f (%.2f aim, %.2f speed)", m_fStarsTomTotal,
-                                                                m_fStarsTomAim, m_fStarsTomSpeed));
-            m_osu->getTooltipOverlay()->addLine(UString::format("Speed: %.3gx", m_fSpeedMultiplier));
-            m_osu->getTooltipOverlay()->addLine(
+            osu->getTooltipOverlay()->addLine(UString::format("%.2fpp", m_fPPv2));
+            osu->getTooltipOverlay()->addLine("Difficulty:");
+            osu->getTooltipOverlay()->addLine(UString::format("Stars: %.2f (%.2f aim, %.2f speed)", m_fStarsTomTotal,
+                                                              m_fStarsTomAim, m_fStarsTomSpeed));
+            osu->getTooltipOverlay()->addLine(UString::format("Speed: %.3gx", m_fSpeedMultiplier));
+            osu->getTooltipOverlay()->addLine(
                 UString::format("CS:%.4g AR:%.4g OD:%.4g HP:%.4g", m_fCS, m_fAR, m_fOD, m_fHP));
                 UString::format("CS:%.4g AR:%.4g OD:%.4g HP:%.4g", m_fCS, m_fAR, m_fOD, m_fHP));
 
 
-            if(m_sMods.length() > 0) m_osu->getTooltipOverlay()->addLine(m_sMods);
+            if(m_sMods.length() > 0) osu->getTooltipOverlay()->addLine(m_sMods);
 
 
             if(!m_bIsImportedLegacyScore) {
             if(!m_bIsImportedLegacyScore) {
-                m_osu->getTooltipOverlay()->addLine("Accuracy:");
-                m_osu->getTooltipOverlay()->addLine(
+                osu->getTooltipOverlay()->addLine("Accuracy:");
+                osu->getTooltipOverlay()->addLine(
                     UString::format("Error: %.2fms - %.2fms avg", m_fHitErrorAvgMin, m_fHitErrorAvgMax));
                     UString::format("Error: %.2fms - %.2fms avg", m_fHitErrorAvgMin, m_fHitErrorAvgMax));
-                m_osu->getTooltipOverlay()->addLine(UString::format("Unstable Rate: %.2f", m_fUnstableRate));
+                osu->getTooltipOverlay()->addLine(UString::format("Unstable Rate: %.2f", m_fUnstableRate));
             } else
             } else
-                m_osu->getTooltipOverlay()->addLine("This score was imported from osu!");
+                osu->getTooltipOverlay()->addLine("This score was imported from osu!");
         }
         }
-        m_osu->getTooltipOverlay()->end();
+        osu->getTooltipOverlay()->end();
     }
     }
 
 
     // frustration multiplier
     // frustration multiplier
@@ -440,11 +440,11 @@ CBaseUIContainer *RankingScreen::setVisible(bool visible) {
         updateLayout();
         updateLayout();
     } else if(bancho.is_in_a_multi_room()) {
     } else if(bancho.is_in_a_multi_room()) {
         // We backed out of the ranking screen, display the room again
         // We backed out of the ranking screen, display the room again
-        m_osu->m_room->setVisible(true);
-        m_osu->m_chat->updateVisibility();
+        osu->m_room->setVisible(true);
+        osu->m_chat->updateVisibility();
 
 
         // Since we prevented on_map_change() from running while the ranking screen was visible, run it now.
         // Since we prevented on_map_change() from running while the ranking screen was visible, run it now.
-        m_osu->m_room->on_map_change(true);
+        osu->m_room->on_map_change(true);
     }
     }
 
 
     return this;
     return this;
@@ -470,26 +470,26 @@ void RankingScreen::setScore(LiveScore *score) {
     } else
     } else
         m_sMods = "";
         m_sMods = "";
 
 
-    m_bModSS = m_osu->getModSS();
-    m_bModSD = m_osu->getModSD();
-    m_bModEZ = m_osu->getModEZ();
-    m_bModHD = m_osu->getModHD();
-    m_bModHR = m_osu->getModHR();
-    m_bModNC = m_osu->getModNC();
-    m_bModDT = m_osu->getModDT();
-    m_bModNightmare = m_osu->getModNightmare();
-    m_bModScorev2 = m_osu->getModScorev2();
-    m_bModTarget = m_osu->getModTarget();
-    m_bModSpunout = m_osu->getModSpunout();
-    m_bModRelax = m_osu->getModRelax();
-    m_bModNF = m_osu->getModNF();
-    m_bModHT = m_osu->getModHT();
-    m_bModAutopilot = m_osu->getModAutopilot();
-    m_bModAuto = m_osu->getModAuto();
-    m_bModTD = m_osu->getModTD();
+    m_bModSS = osu->getModSS();
+    m_bModSD = osu->getModSD();
+    m_bModEZ = osu->getModEZ();
+    m_bModHD = osu->getModHD();
+    m_bModHR = osu->getModHR();
+    m_bModNC = osu->getModNC();
+    m_bModDT = osu->getModDT();
+    m_bModNightmare = osu->getModNightmare();
+    m_bModScorev2 = osu->getModScorev2();
+    m_bModTarget = osu->getModTarget();
+    m_bModSpunout = osu->getModSpunout();
+    m_bModRelax = osu->getModRelax();
+    m_bModNF = osu->getModNF();
+    m_bModHT = osu->getModHT();
+    m_bModAutopilot = osu->getModAutopilot();
+    m_bModAuto = osu->getModAuto();
+    m_bModTD = osu->getModTD();
 
 
     m_enabledExperimentalMods.clear();
     m_enabledExperimentalMods.clear();
-    std::vector<ConVar *> allExperimentalMods = m_osu->getExperimentalMods();
+    std::vector<ConVar *> allExperimentalMods = osu->getExperimentalMods();
     for(int i = 0; i < allExperimentalMods.size(); i++) {
     for(int i = 0; i < allExperimentalMods.size(); i++) {
         if(allExperimentalMods[i]->getBool()) m_enabledExperimentalMods.push_back(allExperimentalMods[i]);
         if(allExperimentalMods[i]->getBool()) m_enabledExperimentalMods.push_back(allExperimentalMods[i]);
     }
     }
@@ -577,7 +577,7 @@ void RankingScreen::setBeatmapInfo(Beatmap *beatmap, DatabaseBeatmap *diff2) {
     m_songInfo->setPlayer(m_bIsUnranked ? "neosu" : local_name.toUtf8());
     m_songInfo->setPlayer(m_bIsUnranked ? "neosu" : local_name.toUtf8());
 
 
     // round all here to 2 decimal places
     // round all here to 2 decimal places
-    m_fSpeedMultiplier = std::round(m_osu->getSpeedMultiplier() * 100.0f) / 100.0f;
+    m_fSpeedMultiplier = std::round(osu->getSpeedMultiplier() * 100.0f) / 100.0f;
     m_fCS = std::round(beatmap->getCS() * 100.0f) / 100.0f;
     m_fCS = std::round(beatmap->getCS() * 100.0f) / 100.0f;
     m_fAR = std::round(GameRules::getApproachRateForSpeedMultiplier(beatmap) * 100.0f) / 100.0f;
     m_fAR = std::round(GameRules::getApproachRateForSpeedMultiplier(beatmap) * 100.0f) / 100.0f;
     m_fOD = std::round(GameRules::getOverallDifficultyForSpeedMultiplier(beatmap) * 100.0f) / 100.0f;
     m_fOD = std::round(GameRules::getOverallDifficultyForSpeedMultiplier(beatmap) * 100.0f) / 100.0f;
@@ -589,39 +589,39 @@ void RankingScreen::updateLayout() {
 
 
     const float uiScale = Osu::ui_scale->getFloat();
     const float uiScale = Osu::ui_scale->getFloat();
 
 
-    setSize(m_osu->getScreenSize());
+    setSize(osu->getScreenSize());
 
 
-    m_rankingTitle->setImage(m_osu->getSkin()->getRankingTitle());
-    m_rankingTitle->setScale(Osu::getImageScale(m_osu, m_rankingTitle->getImage(), 75.0f) * uiScale,
-                             Osu::getImageScale(m_osu, m_rankingTitle->getImage(), 75.0f) * uiScale);
+    m_rankingTitle->setImage(osu->getSkin()->getRankingTitle());
+    m_rankingTitle->setScale(Osu::getImageScale(m_rankingTitle->getImage(), 75.0f) * uiScale,
+                             Osu::getImageScale(m_rankingTitle->getImage(), 75.0f) * uiScale);
     m_rankingTitle->setSize(m_rankingTitle->getImage()->getWidth() * m_rankingTitle->getScale().x,
     m_rankingTitle->setSize(m_rankingTitle->getImage()->getWidth() * m_rankingTitle->getScale().x,
                             m_rankingTitle->getImage()->getHeight() * m_rankingTitle->getScale().y);
                             m_rankingTitle->getImage()->getHeight() * m_rankingTitle->getScale().y);
-    m_rankingTitle->setRelPos(getSize().x - m_rankingTitle->getSize().x - m_osu->getUIScale(m_osu, 20.0f), 0);
+    m_rankingTitle->setRelPos(getSize().x - m_rankingTitle->getSize().x - osu->getUIScale(20.0f), 0);
 
 
-    m_songInfo->setSize(m_osu->getScreenWidth(),
+    m_songInfo->setSize(osu->getScreenWidth(),
                         std::max(m_songInfo->getMinimumHeight(),
                         std::max(m_songInfo->getMinimumHeight(),
                                  m_rankingTitle->getSize().y * osu_rankingscreen_topbar_height_percent.getFloat()));
                                  m_rankingTitle->getSize().y * osu_rankingscreen_topbar_height_percent.getFloat()));
 
 
-    m_rankings->setSize(m_osu->getScreenSize().x + 2, m_osu->getScreenSize().y - m_songInfo->getSize().y + 3);
+    m_rankings->setSize(osu->getScreenSize().x + 2, osu->getScreenSize().y - m_songInfo->getSize().y + 3);
     m_rankings->setRelPosY(m_songInfo->getSize().y - 1);
     m_rankings->setRelPosY(m_songInfo->getSize().y - 1);
     update_pos();
     update_pos();
 
 
     // NOTE: no uiScale for rankingPanel and rankingGrade, doesn't really work due to legacy layout expectations
     // NOTE: no uiScale for rankingPanel and rankingGrade, doesn't really work due to legacy layout expectations
     const Vector2 hardcodedOsuRankingPanelImageSize =
     const Vector2 hardcodedOsuRankingPanelImageSize =
-        Vector2(622, 505) * (m_osu->getSkin()->isRankingPanel2x() ? 2.0f : 1.0f);
-    m_rankingPanel->setImage(m_osu->getSkin()->getRankingPanel());
-    m_rankingPanel->setScale(Osu::getImageScale(m_osu, hardcodedOsuRankingPanelImageSize, 317.0f),
-                             Osu::getImageScale(m_osu, hardcodedOsuRankingPanelImageSize, 317.0f));
+        Vector2(622, 505) * (osu->getSkin()->isRankingPanel2x() ? 2.0f : 1.0f);
+    m_rankingPanel->setImage(osu->getSkin()->getRankingPanel());
+    m_rankingPanel->setScale(Osu::getImageScale(hardcodedOsuRankingPanelImageSize, 317.0f),
+                             Osu::getImageScale(hardcodedOsuRankingPanelImageSize, 317.0f));
     m_rankingPanel->setSize(std::max(hardcodedOsuRankingPanelImageSize.x * m_rankingPanel->getScale().x,
     m_rankingPanel->setSize(std::max(hardcodedOsuRankingPanelImageSize.x * m_rankingPanel->getScale().x,
                                      m_rankingPanel->getImage()->getWidth() * m_rankingPanel->getScale().x),
                                      m_rankingPanel->getImage()->getWidth() * m_rankingPanel->getScale().x),
                             std::max(hardcodedOsuRankingPanelImageSize.y * m_rankingPanel->getScale().y,
                             std::max(hardcodedOsuRankingPanelImageSize.y * m_rankingPanel->getScale().y,
                                      m_rankingPanel->getImage()->getHeight() * m_rankingPanel->getScale().y));
                                      m_rankingPanel->getImage()->getHeight() * m_rankingPanel->getScale().y));
 
 
-    m_rankingIndex->setSize(m_rankings->getSize().x + 2, m_osu->getScreenHeight() * 0.07f * uiScale);
+    m_rankingIndex->setSize(m_rankings->getSize().x + 2, osu->getScreenHeight() * 0.07f * uiScale);
     m_rankingIndex->setBackgroundColor(0xff745e13);
     m_rankingIndex->setBackgroundColor(0xff745e13);
     m_rankingIndex->setRelPosY(m_rankings->getSize().y + 1);
     m_rankingIndex->setRelPosY(m_rankings->getSize().y + 1);
 
 
-    m_rankingBottom->setSize(m_rankings->getSize().x + 2, m_osu->getScreenHeight() * 0.2f);
+    m_rankingBottom->setSize(m_rankings->getSize().x + 2, osu->getScreenHeight() * 0.2f);
     m_rankingBottom->setRelPosY(m_rankingIndex->getRelPos().y + m_rankingIndex->getSize().y);
     m_rankingBottom->setRelPosY(m_rankingIndex->getRelPos().y + m_rankingIndex->getSize().y);
 
 
     m_rankingScrollDownInfoButton->setSize(getSize().x * 0.2f * uiScale, getSize().y * 0.1f * uiScale);
     m_rankingScrollDownInfoButton->setSize(getSize().x * 0.2f * uiScale, getSize().y * 0.1f * uiScale);
@@ -637,15 +637,15 @@ void RankingScreen::updateLayout() {
 }
 }
 
 
 void RankingScreen::onBack() {
 void RankingScreen::onBack() {
-    engine->getSound()->play(m_osu->getSkin()->getMenuClick());
+    engine->getSound()->play(osu->getSkin()->getMenuClick());
 
 
     // stop applause sound
     // stop applause sound
-    if(m_osu->getSkin()->getApplause() != NULL && m_osu->getSkin()->getApplause()->isPlaying())
-        engine->getSound()->stop(m_osu->getSkin()->getApplause());
+    if(osu->getSkin()->getApplause() != NULL && osu->getSkin()->getApplause()->isPlaying())
+        engine->getSound()->stop(osu->getSkin()->getApplause());
 
 
     setVisible(false);
     setVisible(false);
-    if(!bancho.is_in_a_multi_room()) {
-        if(m_osu->m_songBrowser2 != NULL && m_osu->m_iInstanceID < 2) m_osu->m_songBrowser2->setVisible(true);
+    if(!bancho.is_in_a_multi_room() && osu->m_songBrowser2 != NULL) {
+        osu->m_songBrowser2->setVisible(true);
     }
     }
 }
 }
 
 
@@ -657,50 +657,50 @@ void RankingScreen::setGrade(FinishedScore::Grade grade) {
     Vector2 hardcodedOsuRankingGradeImageSize = Vector2(369, 422);
     Vector2 hardcodedOsuRankingGradeImageSize = Vector2(369, 422);
     switch(grade) {
     switch(grade) {
         case FinishedScore::Grade::XH:
         case FinishedScore::Grade::XH:
-            hardcodedOsuRankingGradeImageSize *= (m_osu->getSkin()->isRankingXH2x() ? 2.0f : 1.0f);
-            m_rankingGrade->setImage(m_osu->getSkin()->getRankingXH());
+            hardcodedOsuRankingGradeImageSize *= (osu->getSkin()->isRankingXH2x() ? 2.0f : 1.0f);
+            m_rankingGrade->setImage(osu->getSkin()->getRankingXH());
             break;
             break;
         case FinishedScore::Grade::SH:
         case FinishedScore::Grade::SH:
-            hardcodedOsuRankingGradeImageSize *= (m_osu->getSkin()->isRankingSH2x() ? 2.0f : 1.0f);
-            m_rankingGrade->setImage(m_osu->getSkin()->getRankingSH());
+            hardcodedOsuRankingGradeImageSize *= (osu->getSkin()->isRankingSH2x() ? 2.0f : 1.0f);
+            m_rankingGrade->setImage(osu->getSkin()->getRankingSH());
             break;
             break;
         case FinishedScore::Grade::X:
         case FinishedScore::Grade::X:
-            hardcodedOsuRankingGradeImageSize *= (m_osu->getSkin()->isRankingX2x() ? 2.0f : 1.0f);
-            m_rankingGrade->setImage(m_osu->getSkin()->getRankingX());
+            hardcodedOsuRankingGradeImageSize *= (osu->getSkin()->isRankingX2x() ? 2.0f : 1.0f);
+            m_rankingGrade->setImage(osu->getSkin()->getRankingX());
             break;
             break;
         case FinishedScore::Grade::S:
         case FinishedScore::Grade::S:
-            hardcodedOsuRankingGradeImageSize *= (m_osu->getSkin()->isRankingS2x() ? 2.0f : 1.0f);
-            m_rankingGrade->setImage(m_osu->getSkin()->getRankingS());
+            hardcodedOsuRankingGradeImageSize *= (osu->getSkin()->isRankingS2x() ? 2.0f : 1.0f);
+            m_rankingGrade->setImage(osu->getSkin()->getRankingS());
             break;
             break;
         case FinishedScore::Grade::A:
         case FinishedScore::Grade::A:
-            hardcodedOsuRankingGradeImageSize *= (m_osu->getSkin()->isRankingA2x() ? 2.0f : 1.0f);
-            m_rankingGrade->setImage(m_osu->getSkin()->getRankingA());
+            hardcodedOsuRankingGradeImageSize *= (osu->getSkin()->isRankingA2x() ? 2.0f : 1.0f);
+            m_rankingGrade->setImage(osu->getSkin()->getRankingA());
             break;
             break;
         case FinishedScore::Grade::B:
         case FinishedScore::Grade::B:
-            hardcodedOsuRankingGradeImageSize *= (m_osu->getSkin()->isRankingB2x() ? 2.0f : 1.0f);
-            m_rankingGrade->setImage(m_osu->getSkin()->getRankingB());
+            hardcodedOsuRankingGradeImageSize *= (osu->getSkin()->isRankingB2x() ? 2.0f : 1.0f);
+            m_rankingGrade->setImage(osu->getSkin()->getRankingB());
             break;
             break;
         case FinishedScore::Grade::C:
         case FinishedScore::Grade::C:
-            hardcodedOsuRankingGradeImageSize *= (m_osu->getSkin()->isRankingC2x() ? 2.0f : 1.0f);
-            m_rankingGrade->setImage(m_osu->getSkin()->getRankingC());
+            hardcodedOsuRankingGradeImageSize *= (osu->getSkin()->isRankingC2x() ? 2.0f : 1.0f);
+            m_rankingGrade->setImage(osu->getSkin()->getRankingC());
             break;
             break;
         default:
         default:
-            hardcodedOsuRankingGradeImageSize *= (m_osu->getSkin()->isRankingD2x() ? 2.0f : 1.0f);
-            m_rankingGrade->setImage(m_osu->getSkin()->getRankingD());
+            hardcodedOsuRankingGradeImageSize *= (osu->getSkin()->isRankingD2x() ? 2.0f : 1.0f);
+            m_rankingGrade->setImage(osu->getSkin()->getRankingD());
             break;
             break;
     }
     }
 
 
     const float uiScale = /*Osu::ui_scale->getFloat()*/ 1.0f;  // NOTE: no uiScale for rankingPanel and rankingGrade,
     const float uiScale = /*Osu::ui_scale->getFloat()*/ 1.0f;  // NOTE: no uiScale for rankingPanel and rankingGrade,
                                                                // doesn't really work due to legacy layout expectations
                                                                // doesn't really work due to legacy layout expectations
 
 
-    const float rankingGradeImageScale = Osu::getImageScale(m_osu, hardcodedOsuRankingGradeImageSize, 230.0f) * uiScale;
+    const float rankingGradeImageScale = Osu::getImageScale(hardcodedOsuRankingGradeImageSize, 230.0f) * uiScale;
     m_rankingGrade->setScale(rankingGradeImageScale, rankingGradeImageScale);
     m_rankingGrade->setScale(rankingGradeImageScale, rankingGradeImageScale);
     m_rankingGrade->setSize(m_rankingGrade->getImage()->getWidth() * m_rankingGrade->getScale().x,
     m_rankingGrade->setSize(m_rankingGrade->getImage()->getWidth() * m_rankingGrade->getScale().x,
                             m_rankingGrade->getImage()->getHeight() * m_rankingGrade->getScale().y);
                             m_rankingGrade->getImage()->getHeight() * m_rankingGrade->getScale().y);
-    m_rankingGrade->setRelPos(m_rankings->getSize().x - m_osu->getUIScale(m_osu, 120) -
+    m_rankingGrade->setRelPos(m_rankings->getSize().x - osu->getUIScale(120) -
                                   m_rankingGrade->getImage()->getWidth() * m_rankingGrade->getScale().x / 2.0f,
                                   m_rankingGrade->getImage()->getWidth() * m_rankingGrade->getScale().x / 2.0f,
                               -m_rankings->getRelPos().y +
                               -m_rankings->getRelPos().y +
-                                  m_osu->getUIScale(m_osu, m_osu->getSkin()->getVersion() > 1.0f ? 200 : 170) -
+                                  osu->getUIScale(osu->getSkin()->getVersion() > 1.0f ? 200 : 170) -
                                   m_rankingGrade->getImage()->getHeight() * m_rankingGrade->getScale().x / 2.0f);
                                   m_rankingGrade->getImage()->getHeight() * m_rankingGrade->getScale().x / 2.0f);
 }
 }
 
 
@@ -723,15 +723,14 @@ UString RankingScreen::getPPString() { return UString::format("%ipp", (int)(std:
 
 
 Vector2 RankingScreen::getPPPosRaw() {
 Vector2 RankingScreen::getPPPosRaw() {
     const UString ppString = getPPString();
     const UString ppString = getPPString();
-    float ppStringWidth = m_osu->getTitleFont()->getStringWidth(ppString);
+    float ppStringWidth = osu->getTitleFont()->getStringWidth(ppString);
     return Vector2(m_rankingGrade->getPos().x, 0) +
     return Vector2(m_rankingGrade->getPos().x, 0) +
-           Vector2(
-               m_rankingGrade->getSize().x / 2 - ppStringWidth / 2,
-               m_rankings->getScrollPosY() + m_osu->getUIScale(m_osu, 400) + m_osu->getTitleFont()->getHeight() / 2);
+           Vector2(m_rankingGrade->getSize().x / 2 - ppStringWidth / 2,
+                   m_rankings->getScrollPosY() + osu->getUIScale(400) + osu->getTitleFont()->getHeight() / 2);
 }
 }
 
 
 Vector2 RankingScreen::getPPPosCenterRaw() {
 Vector2 RankingScreen::getPPPosCenterRaw() {
     return Vector2(m_rankingGrade->getPos().x, 0) +
     return Vector2(m_rankingGrade->getPos().x, 0) +
-           Vector2(m_rankingGrade->getSize().x / 2, m_rankings->getScrollPosY() + m_osu->getUIScale(m_osu, 400) +
-                                                        m_osu->getTitleFont()->getHeight() / 2);
+           Vector2(m_rankingGrade->getSize().x / 2,
+                   m_rankings->getScrollPosY() + osu->getUIScale(400) + osu->getTitleFont()->getHeight() / 2);
 }
 }

+ 1 - 1
src/App/Osu/RankingScreen.h

@@ -32,7 +32,7 @@ class ConVar;
 
 
 class RankingScreen : public ScreenBackable {
 class RankingScreen : public ScreenBackable {
    public:
    public:
-    RankingScreen(Osu *osu);
+    RankingScreen();
 
 
     virtual void draw(Graphics *g);
     virtual void draw(Graphics *g);
     virtual void mouse_update(bool *propagate_clicks);
     virtual void mouse_update(bool *propagate_clicks);

+ 8 - 8
src/App/Osu/Replay.cpp

@@ -219,7 +219,7 @@ bool Replay::load_from_disk(FinishedScore* score) {
         delete[] compressed_replay;
         delete[] compressed_replay;
     }
     }
 
 
-    auto& map_scores = (*(bancho.osu->getSongBrowser()->getDatabase()->getScores()))[score->md5hash];
+    auto& map_scores = (*(osu->getSongBrowser()->getDatabase()->getScores()))[score->md5hash];
     for(auto& db_score : map_scores) {
     for(auto& db_score : map_scores) {
         if(db_score.unixTimestamp != score->unixTimestamp) continue;
         if(db_score.unixTimestamp != score->unixTimestamp) continue;
         if(&db_score != score) {
         if(&db_score != score) {
@@ -238,7 +238,7 @@ void Replay::load_and_watch(FinishedScore score) {
         if(!load_from_disk(&score)) {
         if(!load_from_disk(&score)) {
             if(strcmp(score.server.c_str(), bancho.endpoint.toUtf8()) != 0) {
             if(strcmp(score.server.c_str(), bancho.endpoint.toUtf8()) != 0) {
                 auto msg = UString::format("Please connect to %s to view this replay!", score.server.c_str());
                 auto msg = UString::format("Please connect to %s to view this replay!", score.server.c_str());
-                bancho.osu->m_notificationOverlay->addNotification(msg);
+                osu->m_notificationOverlay->addNotification(msg);
             }
             }
 
 
             // Need to allocate with calloc since APIRequests free() the .extra
             // Need to allocate with calloc since APIRequests free() the .extra
@@ -254,23 +254,23 @@ void Replay::load_and_watch(FinishedScore score) {
             request.extra = (u8*)score_cpy;
             request.extra = (u8*)score_cpy;
             send_api_request(request);
             send_api_request(request);
 
 
-            bancho.osu->m_notificationOverlay->addNotification("Downloading replay...");
+            osu->m_notificationOverlay->addNotification("Downloading replay...");
             return;
             return;
         }
         }
     }
     }
 
 
     // We tried loading from memory, we tried loading from file, we tried loading from server... RIP
     // We tried loading from memory, we tried loading from file, we tried loading from server... RIP
     if(score.replay.empty()) {
     if(score.replay.empty()) {
-        bancho.osu->m_notificationOverlay->addNotification("Failed to load replay");
+        osu->m_notificationOverlay->addNotification("Failed to load replay");
         return;
         return;
     }
     }
 
 
-    auto beatmap = bancho.osu->getSongBrowser()->getDatabase()->getBeatmapDifficulty(score.md5hash.hash);
+    auto beatmap = osu->getSongBrowser()->getDatabase()->getBeatmapDifficulty(score.md5hash.hash);
     if(beatmap == nullptr) {
     if(beatmap == nullptr) {
         // XXX: Auto-download beatmap
         // XXX: Auto-download beatmap
-        bancho.osu->m_notificationOverlay->addNotification("Missing beatmap for this replay");
+        osu->m_notificationOverlay->addNotification("Missing beatmap for this replay");
     } else {
     } else {
-        bancho.osu->getSongBrowser()->onDifficultySelected(beatmap, false);
-        bancho.osu->getSelectedBeatmap()->watch(score, 0.f);
+        osu->getSongBrowser()->onDifficultySelected(beatmap, false);
+        osu->getSelectedBeatmap()->watch(score, 0.f);
     }
     }
 }
 }

+ 22 - 29
src/App/Osu/RichPresence.cpp

@@ -1,10 +1,3 @@
-//================ Copyright (c) 2018, PG, All rights reserved. =================//
-//
-// Purpose:		generalized rich presence handler
-//
-// $NoKeywords: $rpt
-//===============================================================================//
-
 #include "RichPresence.h"
 #include "RichPresence.h"
 
 
 #include "Bancho.h"
 #include "Bancho.h"
@@ -38,7 +31,7 @@ const UString RichPresence::KEY_DISCORD_DETAILS = "details";
 UString last_status = "[neosu]\nWaking up";
 UString last_status = "[neosu]\nWaking up";
 Action last_action = IDLE;
 Action last_action = IDLE;
 
 
-void RichPresence::setBanchoStatus(Osu *osu, const char *info_text, Action action) {
+void RichPresence::setBanchoStatus(const char *info_text, Action action) {
     if(osu == NULL) return;
     if(osu == NULL) return;
 
 
     MD5Hash map_md5("");
     MD5Hash map_md5("");
@@ -74,7 +67,7 @@ void RichPresence::updateBanchoMods() {
     MD5Hash map_md5("");
     MD5Hash map_md5("");
     u32 map_id = 0;
     u32 map_id = 0;
 
 
-    auto selected_beatmap = bancho.osu->getSelectedBeatmap();
+    auto selected_beatmap = osu->getSelectedBeatmap();
     if(selected_beatmap != nullptr) {
     if(selected_beatmap != nullptr) {
         auto diff = selected_beatmap->getSelectedDifficulty2();
         auto diff = selected_beatmap->getSelectedDifficulty2();
         if(diff != nullptr) {
         if(diff != nullptr) {
@@ -88,36 +81,36 @@ void RichPresence::updateBanchoMods() {
     write<u8>(&packet, last_action);
     write<u8>(&packet, last_action);
     write_string(&packet, last_status.toUtf8());
     write_string(&packet, last_status.toUtf8());
     write_string(&packet, map_md5.hash);
     write_string(&packet, map_md5.hash);
-    write<u32>(&packet, bancho.osu->m_modSelector->getModFlags());
+    write<u32>(&packet, osu->m_modSelector->getModFlags());
     write<u8>(&packet, 0);  // osu!std
     write<u8>(&packet, 0);  // osu!std
     write<u32>(&packet, map_id);
     write<u32>(&packet, map_id);
     send_packet(packet);
     send_packet(packet);
 
 
     // Servers like akatsuki send different leaderboards based on what mods
     // Servers like akatsuki send different leaderboards based on what mods
     // you have selected. Reset leaderboard when switching mods.
     // you have selected. Reset leaderboard when switching mods.
-    bancho.osu->m_songBrowser2->m_db->m_online_scores.clear();
-    bancho.osu->m_songBrowser2->rebuildScoreButtons();
+    osu->m_songBrowser2->m_db->m_online_scores.clear();
+    osu->m_songBrowser2->rebuildScoreButtons();
 }
 }
 
 
-void RichPresence::onMainMenu(Osu *osu) {
-    setStatus(osu, "Main Menu");
-    setBanchoStatus(osu, "Main Menu", AFK);
+void RichPresence::onMainMenu() {
+    setStatus("Main Menu");
+    setBanchoStatus("Main Menu", AFK);
 }
 }
 
 
-void RichPresence::onSongBrowser(Osu *osu) {
-    setStatus(osu, "Song Selection");
+void RichPresence::onSongBrowser() {
+    setStatus("Song Selection");
 
 
     if(osu->m_room->isVisible()) {
     if(osu->m_room->isVisible()) {
-        setBanchoStatus(osu, "Picking a map", MULTIPLAYER);
+        setBanchoStatus("Picking a map", MULTIPLAYER);
     } else {
     } else {
-        setBanchoStatus(osu, "Song selection", IDLE);
+        setBanchoStatus("Song selection", IDLE);
     }
     }
 
 
     // also update window title
     // also update window title
     if(osu_rich_presence_dynamic_windowtitle.getBool()) env->setWindowTitle("neosu");
     if(osu_rich_presence_dynamic_windowtitle.getBool()) env->setWindowTitle("neosu");
 }
 }
 
 
-void RichPresence::onPlayStart(Osu *osu) {
+void RichPresence::onPlayStart() {
     UString playingInfo /*= "Playing "*/;
     UString playingInfo /*= "Playing "*/;
     playingInfo.append(osu->getSelectedBeatmap()->getSelectedDifficulty2()->getArtist().c_str());
     playingInfo.append(osu->getSelectedBeatmap()->getSelectedDifficulty2()->getArtist().c_str());
     playingInfo.append(" - ");
     playingInfo.append(" - ");
@@ -126,8 +119,8 @@ void RichPresence::onPlayStart(Osu *osu) {
     playingInfo.append(osu->getSelectedBeatmap()->getSelectedDifficulty2()->getDifficultyName().c_str());
     playingInfo.append(osu->getSelectedBeatmap()->getSelectedDifficulty2()->getDifficultyName().c_str());
     playingInfo.append("]");
     playingInfo.append("]");
 
 
-    setStatus(osu, playingInfo);
-    setBanchoStatus(osu, playingInfo.toUtf8(), bancho.is_in_a_multi_room() ? MULTIPLAYER : PLAYING);
+    setStatus(playingInfo);
+    setBanchoStatus(playingInfo.toUtf8(), bancho.is_in_a_multi_room() ? MULTIPLAYER : PLAYING);
 
 
     // also update window title
     // also update window title
     if(osu_rich_presence_dynamic_windowtitle.getBool()) {
     if(osu_rich_presence_dynamic_windowtitle.getBool()) {
@@ -137,7 +130,7 @@ void RichPresence::onPlayStart(Osu *osu) {
     }
     }
 }
 }
 
 
-void RichPresence::onPlayEnd(Osu *osu, bool quit) {
+void RichPresence::onPlayEnd(bool quit) {
     if(!quit && osu_rich_presence_show_recentplaystats.getBool()) {
     if(!quit && osu_rich_presence_show_recentplaystats.getBool()) {
         // e.g.: 230pp 900x 95.50% HDHRDT 6*
         // e.g.: 230pp 900x 95.50% HDHRDT 6*
 
 
@@ -160,12 +153,12 @@ void RichPresence::onPlayEnd(Osu *osu, bool quit) {
         // stars
         // stars
         scoreInfo.append(UString::format(" %.2f*", osu->getScore()->getStarsTomTotal()));
         scoreInfo.append(UString::format(" %.2f*", osu->getScore()->getStarsTomTotal()));
 
 
-        setStatus(osu, scoreInfo);
-        setBanchoStatus(osu, scoreInfo.toUtf8(), SUBMITTING);
+        setStatus(scoreInfo);
+        setBanchoStatus(scoreInfo.toUtf8(), SUBMITTING);
     }
     }
 }
 }
 
 
-void RichPresence::setStatus(Osu *osu, UString status, bool force) {
+void RichPresence::setStatus(UString status, bool force) {
     if(!osu_rich_presence.getBool() && !force) return;
     if(!osu_rich_presence.getBool() && !force) return;
 
 
     // discord
     // discord
@@ -183,7 +176,7 @@ void RichPresence::setStatus(Osu *osu, UString status, bool force) {
                              true);
                              true);
     discord->setRichPresence(KEY_DISCORD_DETAILS, status);
     discord->setRichPresence(KEY_DISCORD_DETAILS, status);
 
 
-    if(osu != NULL) {
+    if(osu->getSongBrowser() != nullptr) {
         if(osu_rich_presence_discord_show_totalpp.getBool()) {
         if(osu_rich_presence_discord_show_totalpp.getBool()) {
             if(m_name_ref == NULL) m_name_ref = convar->getConVarByName("name");
             if(m_name_ref == NULL) m_name_ref = convar->getConVarByName("name");
 
 
@@ -202,6 +195,6 @@ void RichPresence::onRichPresenceChange(UString oldValue, UString newValue) {
         onRichPresenceEnable();
         onRichPresenceEnable();
 }
 }
 
 
-void RichPresence::onRichPresenceEnable() { setStatus(NULL, "..."); }
+void RichPresence::onRichPresenceEnable() { setStatus("..."); }
 
 
-void RichPresence::onRichPresenceDisable() { setStatus(NULL, "", true); }
+void RichPresence::onRichPresenceDisable() { setStatus("", true); }

+ 7 - 20
src/App/Osu/RichPresence.h

@@ -1,30 +1,19 @@
-//================ Copyright (c) 2018, PG, All rights reserved. =================//
-//
-// Purpose:		generalized rich presence handler
-//
-// $NoKeywords: $rpt
-//===============================================================================//
-
-#ifndef OSURICHPRESENCE_H
-#define OSURICHPRESENCE_H
-
+#pragma once
 #include "BanchoProtocol.h"
 #include "BanchoProtocol.h"
 #include "cbase.h"
 #include "cbase.h"
 
 
 class ConVar;
 class ConVar;
 
 
-class Osu;
-
 class RichPresence {
 class RichPresence {
    public:
    public:
-    static void onMainMenu(Osu *osu);
-    static void onSongBrowser(Osu *osu);
-    static void onPlayStart(Osu *osu);
-    static void onPlayEnd(Osu *osu, bool quit);
+    static void onMainMenu();
+    static void onSongBrowser();
+    static void onPlayStart();
+    static void onPlayEnd(bool quit);
 
 
     static void onRichPresenceChange(UString oldValue, UString newValue);
     static void onRichPresenceChange(UString oldValue, UString newValue);
-    static void setStatus(Osu *osu, UString status, bool force = false);
-    static void setBanchoStatus(Osu *osu, const char *info_text, Action action);
+    static void setStatus(UString status, bool force = false);
+    static void setBanchoStatus(const char *info_text, Action action);
     static void updateBanchoMods();
     static void updateBanchoMods();
 
 
    private:
    private:
@@ -37,5 +26,3 @@ class RichPresence {
     static void onRichPresenceEnable();
     static void onRichPresenceEnable();
     static void onRichPresenceDisable();
     static void onRichPresenceDisable();
 };
 };
-
-#endif

+ 110 - 112
src/App/Osu/RoomScreen.cpp

@@ -42,32 +42,32 @@ void UIModList::draw(Graphics *g) {
     std::vector<SkinImage *> mods;
     std::vector<SkinImage *> mods;
 
 
     if(*m_flags & ModFlags::Nightcore)
     if(*m_flags & ModFlags::Nightcore)
-        mods.push_back(bancho.osu->getSkin()->getSelectionModNightCore());
+        mods.push_back(osu->getSkin()->getSelectionModNightCore());
     else if(*m_flags & ModFlags::DoubleTime)
     else if(*m_flags & ModFlags::DoubleTime)
-        mods.push_back(bancho.osu->getSkin()->getSelectionModDoubleTime());
+        mods.push_back(osu->getSkin()->getSelectionModDoubleTime());
 
 
     bool ht_enabled = *m_flags & ModFlags::HalfTime;
     bool ht_enabled = *m_flags & ModFlags::HalfTime;
     if(ht_enabled && bancho.prefer_daycore)
     if(ht_enabled && bancho.prefer_daycore)
-        mods.push_back(bancho.osu->getSkin()->getSelectionModDayCore());
+        mods.push_back(osu->getSkin()->getSelectionModDayCore());
     else if(ht_enabled)
     else if(ht_enabled)
-        mods.push_back(bancho.osu->getSkin()->getSelectionModHalfTime());
+        mods.push_back(osu->getSkin()->getSelectionModHalfTime());
 
 
     if(*m_flags & ModFlags::Perfect)
     if(*m_flags & ModFlags::Perfect)
-        mods.push_back(bancho.osu->getSkin()->getSelectionModPerfect());
+        mods.push_back(osu->getSkin()->getSelectionModPerfect());
     else if(*m_flags & ModFlags::SuddenDeath)
     else if(*m_flags & ModFlags::SuddenDeath)
-        mods.push_back(bancho.osu->getSkin()->getSelectionModSuddenDeath());
-
-    if(*m_flags & ModFlags::NoFail) mods.push_back(bancho.osu->getSkin()->getSelectionModNoFail());
-    if(*m_flags & ModFlags::Easy) mods.push_back(bancho.osu->getSkin()->getSelectionModEasy());
-    if(*m_flags & ModFlags::TouchDevice) mods.push_back(bancho.osu->getSkin()->getSelectionModTD());
-    if(*m_flags & ModFlags::Hidden) mods.push_back(bancho.osu->getSkin()->getSelectionModHidden());
-    if(*m_flags & ModFlags::HardRock) mods.push_back(bancho.osu->getSkin()->getSelectionModHardRock());
-    if(*m_flags & ModFlags::Relax) mods.push_back(bancho.osu->getSkin()->getSelectionModRelax());
-    if(*m_flags & ModFlags::Autoplay) mods.push_back(bancho.osu->getSkin()->getSelectionModAutoplay());
-    if(*m_flags & ModFlags::SpunOut) mods.push_back(bancho.osu->getSkin()->getSelectionModSpunOut());
-    if(*m_flags & ModFlags::Autopilot) mods.push_back(bancho.osu->getSkin()->getSelectionModAutopilot());
-    if(*m_flags & ModFlags::Target) mods.push_back(bancho.osu->getSkin()->getSelectionModTarget());
-    if(*m_flags & ModFlags::ScoreV2) mods.push_back(bancho.osu->getSkin()->getSelectionModScorev2());
+        mods.push_back(osu->getSkin()->getSelectionModSuddenDeath());
+
+    if(*m_flags & ModFlags::NoFail) mods.push_back(osu->getSkin()->getSelectionModNoFail());
+    if(*m_flags & ModFlags::Easy) mods.push_back(osu->getSkin()->getSelectionModEasy());
+    if(*m_flags & ModFlags::TouchDevice) mods.push_back(osu->getSkin()->getSelectionModTD());
+    if(*m_flags & ModFlags::Hidden) mods.push_back(osu->getSkin()->getSelectionModHidden());
+    if(*m_flags & ModFlags::HardRock) mods.push_back(osu->getSkin()->getSelectionModHardRock());
+    if(*m_flags & ModFlags::Relax) mods.push_back(osu->getSkin()->getSelectionModRelax());
+    if(*m_flags & ModFlags::Autoplay) mods.push_back(osu->getSkin()->getSelectionModAutoplay());
+    if(*m_flags & ModFlags::SpunOut) mods.push_back(osu->getSkin()->getSelectionModSpunOut());
+    if(*m_flags & ModFlags::Autopilot) mods.push_back(osu->getSkin()->getSelectionModAutopilot());
+    if(*m_flags & ModFlags::Target) mods.push_back(osu->getSkin()->getSelectionModTarget());
+    if(*m_flags & ModFlags::ScoreV2) mods.push_back(osu->getSkin()->getSelectionModScorev2());
 
 
     g->setColor(0xffffffff);
     g->setColor(0xffffffff);
     Vector2 modPos = m_vPos;
     Vector2 modPos = m_vPos;
@@ -110,7 +110,7 @@ bool UIModList::isVisible() { return *m_flags != 0; }
         m_settings->getContainer()->addBaseUIElement(button);           \
         m_settings->getContainer()->addBaseUIElement(button);           \
     } while(0)
     } while(0)
 
 
-RoomScreen::RoomScreen(Osu *osu) : OsuScreen(osu) {
+RoomScreen::RoomScreen() : OsuScreen() {
     font = engine->getResourceManager()->getFont("FONT_DEFAULT");
     font = engine->getResourceManager()->getFont("FONT_DEFAULT");
     lfont = osu->getSubTitleFont();
     lfont = osu->getSubTitleFont();
 
 
@@ -132,20 +132,20 @@ RoomScreen::RoomScreen(Osu *osu) : OsuScreen(osu) {
     m_room_name_ipt = new CBaseUITextbox(0, 0, m_settings->getSize().x, 40, "");
     m_room_name_ipt = new CBaseUITextbox(0, 0, m_settings->getSize().x, 40, "");
     m_room_name_ipt->setText("Multiplayer room");
     m_room_name_ipt->setText("Multiplayer room");
 
 
-    m_change_password_btn = new UIButton(osu, 0, 0, 190, 40, "change_password_btn", "Change password");
+    m_change_password_btn = new UIButton(0, 0, 190, 40, "change_password_btn", "Change password");
     m_change_password_btn->setColor(0xff0e94b5);
     m_change_password_btn->setColor(0xff0e94b5);
     m_change_password_btn->setUseDefaultSkin();
     m_change_password_btn->setUseDefaultSkin();
     m_change_password_btn->setClickCallback(fastdelegate::MakeDelegate(this, &RoomScreen::onChangePasswordClicked));
     m_change_password_btn->setClickCallback(fastdelegate::MakeDelegate(this, &RoomScreen::onChangePasswordClicked));
 
 
     INIT_LABEL(m_win_condition, "Win condition: Score", false);
     INIT_LABEL(m_win_condition, "Win condition: Score", false);
-    m_change_win_condition_btn = new UIButton(osu, 0, 0, 240, 40, "change_win_condition_btn", "Win condition: Score");
+    m_change_win_condition_btn = new UIButton(0, 0, 240, 40, "change_win_condition_btn", "Win condition: Score");
     m_change_win_condition_btn->setColor(0xff00ff00);
     m_change_win_condition_btn->setColor(0xff00ff00);
     m_change_win_condition_btn->setUseDefaultSkin();
     m_change_win_condition_btn->setUseDefaultSkin();
     m_change_win_condition_btn->setClickCallback(
     m_change_win_condition_btn->setClickCallback(
         fastdelegate::MakeDelegate(this, &RoomScreen::onChangeWinConditionClicked));
         fastdelegate::MakeDelegate(this, &RoomScreen::onChangeWinConditionClicked));
 
 
     INIT_LABEL(map_label, "Beatmap", true);
     INIT_LABEL(map_label, "Beatmap", true);
-    m_select_map_btn = new UIButton(osu, 0, 0, 130, 40, "select_map_btn", "Select map");
+    m_select_map_btn = new UIButton(0, 0, 130, 40, "select_map_btn", "Select map");
     m_select_map_btn->setColor(0xff0e94b5);
     m_select_map_btn->setColor(0xff0e94b5);
     m_select_map_btn->setUseDefaultSkin();
     m_select_map_btn->setUseDefaultSkin();
     m_select_map_btn->setClickCallback(fastdelegate::MakeDelegate(this, &RoomScreen::onSelectMapClicked));
     m_select_map_btn->setClickCallback(fastdelegate::MakeDelegate(this, &RoomScreen::onSelectMapClicked));
@@ -156,18 +156,18 @@ RoomScreen::RoomScreen(Osu *osu) : OsuScreen(osu) {
     INIT_LABEL(m_map_attributes2, "", false);
     INIT_LABEL(m_map_attributes2, "", false);
 
 
     INIT_LABEL(mods_label, "Mods", true);
     INIT_LABEL(mods_label, "Mods", true);
-    m_select_mods_btn = new UIButton(osu, 0, 0, 180, 40, "select_mods_btn", "Select mods [F1]");
+    m_select_mods_btn = new UIButton(0, 0, 180, 40, "select_mods_btn", "Select mods [F1]");
     m_select_mods_btn->setColor(0xff0e94b5);
     m_select_mods_btn->setColor(0xff0e94b5);
     m_select_mods_btn->setUseDefaultSkin();
     m_select_mods_btn->setUseDefaultSkin();
     m_select_mods_btn->setClickCallback(fastdelegate::MakeDelegate(this, &RoomScreen::onSelectModsClicked));
     m_select_mods_btn->setClickCallback(fastdelegate::MakeDelegate(this, &RoomScreen::onSelectModsClicked));
-    m_freemod = new UICheckbox(m_osu, 0, 0, 200, 50, "allow_freemod", "Freemod");
+    m_freemod = new UICheckbox(0, 0, 200, 50, "allow_freemod", "Freemod");
     m_freemod->setDrawFrame(false);
     m_freemod->setDrawFrame(false);
     m_freemod->setDrawBackground(false);
     m_freemod->setDrawBackground(false);
     m_freemod->setChangeCallback(fastdelegate::MakeDelegate(this, &RoomScreen::onFreemodCheckboxChanged));
     m_freemod->setChangeCallback(fastdelegate::MakeDelegate(this, &RoomScreen::onFreemodCheckboxChanged));
     m_mods = new UIModList(&bancho.room.mods);
     m_mods = new UIModList(&bancho.room.mods);
     INIT_LABEL(m_no_mods_selected, "No mods selected.", false);
     INIT_LABEL(m_no_mods_selected, "No mods selected.", false);
 
 
-    m_ready_btn = new UIButton(osu, 0, 0, 300, 50, "start_game_btn", "Start game");
+    m_ready_btn = new UIButton(0, 0, 300, 50, "start_game_btn", "Start game");
     m_ready_btn->setColor(0xff00ff00);
     m_ready_btn->setColor(0xff00ff00);
     m_ready_btn->setUseDefaultSkin();
     m_ready_btn->setUseDefaultSkin();
     m_ready_btn->setClickCallback(fastdelegate::MakeDelegate(this, &RoomScreen::onReadyButtonClick));
     m_ready_btn->setClickCallback(fastdelegate::MakeDelegate(this, &RoomScreen::onReadyButtonClick));
@@ -186,10 +186,10 @@ RoomScreen::RoomScreen(Osu *osu) : OsuScreen(osu) {
     m_slotlist->setHorizontalScrolling(false);
     m_slotlist->setHorizontalScrolling(false);
     addBaseUIElement(m_slotlist);
     addBaseUIElement(m_slotlist);
 
 
-    m_contextMenu = new UIContextMenu(m_osu, 50, 50, 150, 0, "", m_settings);
+    m_contextMenu = new UIContextMenu(50, 50, 150, 0, "", m_settings);
     addBaseUIElement(m_contextMenu);
     addBaseUIElement(m_contextMenu);
 
 
-    updateLayout(m_osu->getScreenSize());
+    updateLayout(osu->getScreenSize());
 }
 }
 
 
 RoomScreen::~RoomScreen() {
 RoomScreen::~RoomScreen() {
@@ -219,7 +219,7 @@ void RoomScreen::draw(Graphics *g) {
     if(!m_bVisible) return;
     if(!m_bVisible) return;
 
 
     // XXX: Add convar for toggling room backgrounds
     // XXX: Add convar for toggling room backgrounds
-    SongBrowser::drawSelectedBeatmapBackgroundImage(g, m_osu, 1.0);
+    SongBrowser::drawSelectedBeatmapBackgroundImage(g, 1.0);
     OsuScreen::draw(g);
     OsuScreen::draw(g);
 
 
     // Update avatar visibility status
     // Update avatar visibility status
@@ -272,15 +272,15 @@ void RoomScreen::draw(Graphics *g) {
         ss << MCENGINE_DATA_DIR "maps/" << std::to_string(set_id) << "/";
         ss << MCENGINE_DATA_DIR "maps/" << std::to_string(set_id) << "/";
         auto mapset_path = ss.str();
         auto mapset_path = ss.str();
         // XXX: Make a permanent database for auto-downloaded songs, so we can load them like osu!.db's
         // XXX: Make a permanent database for auto-downloaded songs, so we can load them like osu!.db's
-        m_osu->m_songBrowser2->getDatabase()->addBeatmap(mapset_path);
-        m_osu->m_songBrowser2->updateSongButtonSorting();
+        osu->m_songBrowser2->getDatabase()->addBeatmap(mapset_path);
+        osu->m_songBrowser2->updateSongButtonSorting();
         debugLog("Finished loading beatmapset %d.\n", set_id);
         debugLog("Finished loading beatmapset %d.\n", set_id);
         on_map_change(false);
         on_map_change(false);
     }
     }
 }
 }
 
 
 void RoomScreen::mouse_update(bool *propagate_clicks) {
 void RoomScreen::mouse_update(bool *propagate_clicks) {
-    if(!m_bVisible || m_osu->m_songBrowser2->isVisible()) return;
+    if(!m_bVisible || osu->m_songBrowser2->isVisible()) return;
 
 
     const bool room_name_changed = m_room_name_ipt->getText() != bancho.room.name;
     const bool room_name_changed = m_room_name_ipt->getText() != bancho.room.name;
     if(bancho.room.is_host() && room_name_changed) {
     if(bancho.room.is_host() && room_name_changed) {
@@ -293,7 +293,7 @@ void RoomScreen::mouse_update(bool *propagate_clicks) {
         send_packet(packet);
         send_packet(packet);
     }
     }
 
 
-    m_pauseButton->setPaused(!m_osu->getSelectedBeatmap()->isPreviewMusicPlaying());
+    m_pauseButton->setPaused(!osu->getSelectedBeatmap()->isPreviewMusicPlaying());
 
 
     m_contextMenu->mouse_update(propagate_clicks);
     m_contextMenu->mouse_update(propagate_clicks);
     if(!*propagate_clicks) return;
     if(!*propagate_clicks) return;
@@ -302,7 +302,7 @@ void RoomScreen::mouse_update(bool *propagate_clicks) {
 }
 }
 
 
 void RoomScreen::onKeyDown(KeyboardEvent &key) {
 void RoomScreen::onKeyDown(KeyboardEvent &key) {
-    if(!m_bVisible || m_osu->m_songBrowser2->isVisible()) return;
+    if(!m_bVisible || osu->m_songBrowser2->isVisible()) return;
 
 
     if(key.getKeyCode() == KEY_ESCAPE) {
     if(key.getKeyCode() == KEY_ESCAPE) {
         key.consume();
         key.consume();
@@ -313,8 +313,8 @@ void RoomScreen::onKeyDown(KeyboardEvent &key) {
     if(key.getKeyCode() == KEY_F1) {
     if(key.getKeyCode() == KEY_F1) {
         key.consume();
         key.consume();
         if(bancho.room.freemods || bancho.room.is_host()) {
         if(bancho.room.freemods || bancho.room.is_host()) {
-            m_osu->m_modSelector->setVisible(!m_osu->m_modSelector->isVisible());
-            m_bVisible = !m_osu->m_modSelector->isVisible();
+            osu->m_modSelector->setVisible(!osu->m_modSelector->isVisible());
+            m_bVisible = !osu->m_modSelector->isVisible();
         }
         }
         return;
         return;
     }
     }
@@ -323,12 +323,12 @@ void RoomScreen::onKeyDown(KeyboardEvent &key) {
 }
 }
 
 
 void RoomScreen::onKeyUp(KeyboardEvent &key) {
 void RoomScreen::onKeyUp(KeyboardEvent &key) {
-    if(!m_bVisible || m_osu->m_songBrowser2->isVisible()) return;
+    if(!m_bVisible || osu->m_songBrowser2->isVisible()) return;
     OsuScreen::onKeyUp(key);
     OsuScreen::onKeyUp(key);
 }
 }
 
 
 void RoomScreen::onChar(KeyboardEvent &key) {
 void RoomScreen::onChar(KeyboardEvent &key) {
-    if(!m_bVisible || m_osu->m_songBrowser2->isVisible()) return;
+    if(!m_bVisible || osu->m_songBrowser2->isVisible()) return;
     OsuScreen::onChar(key);
     OsuScreen::onChar(key);
 }
 }
 
 
@@ -453,7 +453,7 @@ void RoomScreen::updateLayout(Vector2 newResolution) {
     setSize(newResolution);
     setSize(newResolution);
     updateSettingsLayout(newResolution);
     updateSettingsLayout(newResolution);
 
 
-    const float dpiScale = Osu::getUIScale(m_osu);
+    const float dpiScale = Osu::getUIScale();
     m_pauseButton->setSize(30 * dpiScale, 30 * dpiScale);
     m_pauseButton->setSize(30 * dpiScale, 30 * dpiScale);
     m_pauseButton->setPos(round(newResolution.x * 0.6) - m_pauseButton->getSize().x * 2 - 10 * dpiScale,
     m_pauseButton->setPos(round(newResolution.x * 0.6) - m_pauseButton->getSize().x * 2 - 10 * dpiScale,
                           m_pauseButton->getSize().y + 10 * dpiScale);
                           m_pauseButton->getSize().y + 10 * dpiScale);
@@ -474,7 +474,7 @@ void RoomScreen::updateLayout(Vector2 newResolution) {
             auto avatar = new UIAvatar(bancho.room.slots[i].player_id, 10, y_total, SLOT_HEIGHT, SLOT_HEIGHT);
             auto avatar = new UIAvatar(bancho.room.slots[i].player_id, 10, y_total, SLOT_HEIGHT, SLOT_HEIGHT);
             m_slotlist->getContainer()->addBaseUIElement(avatar);
             m_slotlist->getContainer()->addBaseUIElement(avatar);
 
 
-            auto user_box = new UIUserLabel(m_osu, bancho.room.slots[i].player_id, username);
+            auto user_box = new UIUserLabel(bancho.room.slots[i].player_id, username);
             user_box->setFont(lfont);
             user_box->setFont(lfont);
             user_box->setPos(avatar->getRelPos().x + avatar->getSize().x + 10, y_total);
             user_box->setPos(avatar->getRelPos().x + avatar->getSize().x + 10, y_total);
 
 
@@ -509,19 +509,19 @@ void RoomScreen::ragequit() {
     packet.id = EXIT_ROOM;
     packet.id = EXIT_ROOM;
     send_packet(packet);
     send_packet(packet);
 
 
-    m_osu->m_modSelector->resetMods();
-    m_osu->m_modSelector->updateButtons();
+    osu->m_modSelector->resetMods();
+    osu->m_modSelector->updateButtons();
 
 
     bancho.room = Room();
     bancho.room = Room();
-    m_osu->m_mainMenu->setVisible(true);
-    m_osu->m_chat->removeChannel("#multiplayer");
-    m_osu->m_chat->updateVisibility();
+    osu->m_mainMenu->setVisible(true);
+    osu->m_chat->removeChannel("#multiplayer");
+    osu->m_chat->updateVisibility();
 }
 }
 
 
 void RoomScreen::process_beatmapset_info_response(Packet packet) {
 void RoomScreen::process_beatmapset_info_response(Packet packet) {
     u32 map_id = packet.extra_int;
     u32 map_id = packet.extra_int;
     if(packet.size == 0) {
     if(packet.size == 0) {
-        bancho.osu->m_room->mapset_by_mapid[map_id] = 0;
+        osu->m_room->mapset_by_mapid[map_id] = 0;
         return;
         return;
     }
     }
 
 
@@ -557,14 +557,14 @@ void RoomScreen::process_beatmapset_info_response(Packet packet) {
 
 
     str = strtok_r(NULL, "|", &saveptr);
     str = strtok_r(NULL, "|", &saveptr);
     if(!str) return;
     if(!str) return;
-    bancho.osu->m_room->mapset_by_mapid[map_id] = strtoul(str, NULL, 10);
+    osu->m_room->mapset_by_mapid[map_id] = strtoul(str, NULL, 10);
 
 
     // Do nothing with the rest
     // Do nothing with the rest
 }
 }
 
 
 void RoomScreen::on_map_change(bool download) {
 void RoomScreen::on_map_change(bool download) {
     // Results screen has map background and such showing, so prevent map from changing while we're on it.
     // Results screen has map background and such showing, so prevent map from changing while we're on it.
-    if(m_osu->m_rankingScreen->isVisible()) return;
+    if(osu->m_rankingScreen->isVisible()) return;
 
 
     debugLog("Map changed to ID %d, MD5 %s: %s\n", bancho.room.map_id, bancho.room.map_md5.hash,
     debugLog("Map changed to ID %d, MD5 %s: %s\n", bancho.room.map_id, bancho.room.map_md5.hash,
              bancho.room.map_name.toUtf8());
              bancho.room.map_name.toUtf8());
@@ -572,16 +572,16 @@ void RoomScreen::on_map_change(bool download) {
 
 
     // Deselect current map
     // Deselect current map
     m_pauseButton->setPaused(true);
     m_pauseButton->setPaused(true);
-    m_osu->m_songBrowser2->m_selectedBeatmap->deselect();
+    osu->m_songBrowser2->m_selectedBeatmap->deselect();
 
 
     if(bancho.room.map_id == 0) {
     if(bancho.room.map_id == 0) {
         m_map_title->setText("(no map selected)");
         m_map_title->setText("(no map selected)");
         m_map_title->setSizeToContent(0, 0);
         m_map_title->setSizeToContent(0, 0);
         m_ready_btn->is_loading = true;
         m_ready_btn->is_loading = true;
     } else {
     } else {
-        auto beatmap = m_osu->getSongBrowser()->getDatabase()->getBeatmapDifficulty(bancho.room.map_md5);
+        auto beatmap = osu->getSongBrowser()->getDatabase()->getBeatmapDifficulty(bancho.room.map_md5);
         if(beatmap != nullptr) {
         if(beatmap != nullptr) {
-            m_osu->m_songBrowser2->onDifficultySelected(beatmap, false);
+            osu->m_songBrowser2->onDifficultySelected(beatmap, false);
             m_map_title->setText(bancho.room.map_name);
             m_map_title->setText(bancho.room.map_name);
             m_map_title->setSizeToContent(0, 0);
             m_map_title->setSizeToContent(0, 0);
             auto attributes = UString::format("AR: %.1f, CS: %.1f, HP: %.1f, OD: %.1f", beatmap->getAR(),
             auto attributes = UString::format("AR: %.1f, CS: %.1f, HP: %.1f, OD: %.1f", beatmap->getAR(),
@@ -632,7 +632,7 @@ void RoomScreen::on_map_change(bool download) {
         }
         }
     }
     }
 
 
-    updateLayout(m_osu->getScreenSize());
+    updateLayout(osu->getScreenSize());
 }
 }
 
 
 void RoomScreen::on_room_joined(Room room) {
 void RoomScreen::on_room_joined(Room room) {
@@ -650,16 +650,16 @@ void RoomScreen::on_room_joined(Room room) {
     // Currently we can only join rooms from the lobby.
     // Currently we can only join rooms from the lobby.
     // If we add ability to join from links, you would need to hide all other
     // If we add ability to join from links, you would need to hide all other
     // screens, kick the player out of the song they're currently playing, etc.
     // screens, kick the player out of the song they're currently playing, etc.
-    m_osu->m_lobby->setVisible(false);
-    updateLayout(m_osu->getScreenSize());
+    osu->m_lobby->setVisible(false);
+    updateLayout(osu->getScreenSize());
     m_bVisible = true;
     m_bVisible = true;
 
 
-    RichPresence::setBanchoStatus(m_osu, room.name.toUtf8(), MULTIPLAYER);
-    m_osu->m_chat->addChannel("#multiplayer");
-    m_osu->m_chat->updateVisibility();
+    RichPresence::setBanchoStatus(room.name.toUtf8(), MULTIPLAYER);
+    osu->m_chat->addChannel("#multiplayer");
+    osu->m_chat->updateVisibility();
 
 
-    m_osu->m_modSelector->resetMods();
-    m_osu->m_modSelector->enableModsFromFlags(bancho.room.mods);
+    osu->m_modSelector->resetMods();
+    osu->m_modSelector->enableModsFromFlags(bancho.room.mods);
 }
 }
 
 
 void RoomScreen::on_room_updated(Room room) {
 void RoomScreen::on_room_updated(Room room) {
@@ -690,52 +690,50 @@ void RoomScreen::on_room_updated(Room room) {
         m_room_name_ipt->setText(bancho.room.name);
         m_room_name_ipt->setText(bancho.room.name);
     }
     }
 
 
-    m_osu->m_modSelector->updateButtons();
-    m_osu->m_modSelector->resetMods();
-    m_osu->m_modSelector->enableModsFromFlags(bancho.room.mods | player_slot->mods);
+    osu->m_modSelector->updateButtons();
+    osu->m_modSelector->resetMods();
+    osu->m_modSelector->enableModsFromFlags(bancho.room.mods | player_slot->mods);
 
 
-    updateLayout(m_osu->getScreenSize());
+    updateLayout(osu->getScreenSize());
 }
 }
 
 
 void RoomScreen::on_match_started(Room room) {
 void RoomScreen::on_match_started(Room room) {
     bancho.room = room;
     bancho.room = room;
-    if(m_osu->getSelectedBeatmap() == nullptr) {
+    if(osu->getSelectedBeatmap() == nullptr) {
         debugLog("We received MATCH_STARTED without being ready, wtf!\n");
         debugLog("We received MATCH_STARTED without being ready, wtf!\n");
         return;
         return;
     }
     }
 
 
     last_packet_tms = time(NULL);
     last_packet_tms = time(NULL);
 
 
-    if(m_osu->getSelectedBeatmap()->play()) {
+    if(osu->getSelectedBeatmap()->play()) {
         m_bVisible = false;
         m_bVisible = false;
         bancho.match_started = true;
         bancho.match_started = true;
-        m_osu->m_songBrowser2->m_bHasSelectedAndIsPlaying = true;
-        m_osu->onPlayStart();
-        m_osu->m_chat->updateVisibility();
+        osu->m_songBrowser2->m_bHasSelectedAndIsPlaying = true;
+        osu->m_chat->updateVisibility();
     } else {
     } else {
         ragequit();  // map failed to load
         ragequit();  // map failed to load
     }
     }
 }
 }
 
 
 void RoomScreen::on_match_score_updated(Packet *packet) {
 void RoomScreen::on_match_score_updated(Packet *packet) {
-    i32 update_tms = read<u32>(packet);
-    u8 slot_id = read<u8>(packet);
-    if(slot_id > 15) return;
-
-    auto slot = &bancho.room.slots[slot_id];
-    slot->last_update_tms = update_tms;
-    slot->num300 = read<u16>(packet);
-    slot->num100 = read<u16>(packet);
-    slot->num50 = read<u16>(packet);
-    slot->num_geki = read<u16>(packet);
-    slot->num_katu = read<u16>(packet);
-    slot->num_miss = read<u16>(packet);
-    slot->total_score = read<u32>(packet);
-    slot->max_combo = read<u16>(packet);
-    slot->current_combo = read<u16>(packet);
-    slot->is_perfect = read<u8>(packet);
-    slot->current_hp = read<u8>(packet);
-    slot->tag = read<u8>(packet);
+    auto frame = read<ScoreFrame>(packet);
+    if(frame.slot_id > 15) return;
+
+    auto slot = &bancho.room.slots[frame.slot_id];
+    slot->last_update_tms = frame.time;
+    slot->num300 = frame.num300;
+    slot->num100 = frame.num100;
+    slot->num50 = frame.num50;
+    slot->num_geki = frame.num_geki;
+    slot->num_katu = frame.num_katu;
+    slot->num_miss = frame.num_miss;
+    slot->total_score = frame.total_score;
+    slot->max_combo = frame.max_combo;
+    slot->current_combo = frame.current_combo;
+    slot->is_perfect = frame.is_perfect;
+    slot->current_hp = frame.current_hp;
+    slot->tag = frame.tag;
 
 
     bool is_scorev2 = read<u8>(packet);
     bool is_scorev2 = read<u8>(packet);
     if(is_scorev2) {
     if(is_scorev2) {
@@ -743,12 +741,12 @@ void RoomScreen::on_match_score_updated(Packet *packet) {
         slot->sv2_bonus = read<f64>(packet);
         slot->sv2_bonus = read<f64>(packet);
     }
     }
 
 
-    bancho.osu->m_hud->updateScoreboard(true);
+    osu->m_hud->updateScoreboard(true);
 }
 }
 
 
 void RoomScreen::on_all_players_loaded() {
 void RoomScreen::on_all_players_loaded() {
     bancho.room.all_players_loaded = true;
     bancho.room.all_players_loaded = true;
-    m_osu->m_chat->updateVisibility();
+    osu->m_chat->updateVisibility();
 }
 }
 
 
 void RoomScreen::on_player_failed(i32 slot_id) {
 void RoomScreen::on_player_failed(i32 slot_id) {
@@ -760,10 +758,10 @@ void RoomScreen::on_player_failed(i32 slot_id) {
 void RoomScreen::on_match_finished() {
 void RoomScreen::on_match_finished() {
     if(!bancho.is_playing_a_multi_map()) return;
     if(!bancho.is_playing_a_multi_map()) return;
     memcpy(bancho.last_scores, bancho.room.slots, sizeof(bancho.room.slots));
     memcpy(bancho.last_scores, bancho.room.slots, sizeof(bancho.room.slots));
-    m_osu->onPlayEnd(false, false);
+    osu->onPlayEnd(false, false);
     bancho.match_started = false;
     bancho.match_started = false;
-    m_osu->m_rankingScreen->setVisible(true);
-    m_osu->m_chat->updateVisibility();
+    osu->m_rankingScreen->setVisible(true);
+    osu->m_chat->updateVisibility();
 }
 }
 
 
 void RoomScreen::on_all_players_skipped() { bancho.room.all_players_skipped = true; }
 void RoomScreen::on_all_players_skipped() { bancho.room.all_players_skipped = true; }
@@ -779,7 +777,7 @@ void RoomScreen::on_player_skip(i32 user_id) {
 
 
 void RoomScreen::on_match_aborted() {
 void RoomScreen::on_match_aborted() {
     if(!bancho.is_playing_a_multi_map()) return;
     if(!bancho.is_playing_a_multi_map()) return;
-    m_osu->onPlayEnd(false, true);
+    osu->onPlayEnd(false, true);
     m_bVisible = true;
     m_bVisible = true;
     bancho.match_started = false;
     bancho.match_started = false;
 }
 }
@@ -794,7 +792,7 @@ void RoomScreen::onClientScoreChange(bool force) {
     Packet packet;
     Packet packet;
     packet.id = UPDATE_MATCH_SCORE;
     packet.id = UPDATE_MATCH_SCORE;
 
 
-    write<u32>(&packet, (i32)m_osu->getSelectedBeatmap()->getTime());
+    write<u32>(&packet, (i32)osu->getSelectedBeatmap()->getTime());
 
 
     u8 slot_id = 0;
     u8 slot_id = 0;
     for(u8 i = 0; i < 16; i++) {
     for(u8 i = 0; i < 16; i++) {
@@ -805,20 +803,20 @@ void RoomScreen::onClientScoreChange(bool force) {
     }
     }
     write<u8>(&packet, slot_id);
     write<u8>(&packet, slot_id);
 
 
-    write<u16>(&packet, (u16)m_osu->getScore()->getNum300s());
-    write<u16>(&packet, (u16)m_osu->getScore()->getNum100s());
-    write<u16>(&packet, (u16)m_osu->getScore()->getNum50s());
-    write<u16>(&packet, (u16)m_osu->getScore()->getNum300gs());
-    write<u16>(&packet, (u16)m_osu->getScore()->getNum100ks());
-    write<u16>(&packet, (u16)m_osu->getScore()->getNumMisses());
-    write<u32>(&packet, (i32)m_osu->getScore()->getScore());
-    write<u16>(&packet, (u16)m_osu->getScore()->getCombo());
-    write<u16>(&packet, (u16)m_osu->getScore()->getComboMax());
-    write<u8>(&packet, m_osu->getScore()->getNumSliderBreaks() == 0 && m_osu->getScore()->getNumMisses() == 0 &&
-                           m_osu->getScore()->getNum50s() == 0 && m_osu->getScore()->getNum100s() == 0);
-    write<u8>(&packet, m_osu->getSelectedBeatmap()->getHealth() * 200);
+    write<u16>(&packet, (u16)osu->getScore()->getNum300s());
+    write<u16>(&packet, (u16)osu->getScore()->getNum100s());
+    write<u16>(&packet, (u16)osu->getScore()->getNum50s());
+    write<u16>(&packet, (u16)osu->getScore()->getNum300gs());
+    write<u16>(&packet, (u16)osu->getScore()->getNum100ks());
+    write<u16>(&packet, (u16)osu->getScore()->getNumMisses());
+    write<u32>(&packet, (i32)osu->getScore()->getScore());
+    write<u16>(&packet, (u16)osu->getScore()->getCombo());
+    write<u16>(&packet, (u16)osu->getScore()->getComboMax());
+    write<u8>(&packet, osu->getScore()->getNumSliderBreaks() == 0 && osu->getScore()->getNumMisses() == 0 &&
+                           osu->getScore()->getNum50s() == 0 && osu->getScore()->getNum100s() == 0);
+    write<u8>(&packet, osu->getSelectedBeatmap()->getHealth() * 200);
     write<u8>(&packet, 0);  // 4P, not supported
     write<u8>(&packet, 0);  // 4P, not supported
-    write<u8>(&packet, m_osu->getModScorev2());
+    write<u8>(&packet, osu->getModScorev2());
     send_packet(packet);
     send_packet(packet);
 
 
     last_packet_tms = time(NULL);
     last_packet_tms = time(NULL);
@@ -826,7 +824,7 @@ void RoomScreen::onClientScoreChange(bool force) {
 
 
 void RoomScreen::onReadyButtonClick() {
 void RoomScreen::onReadyButtonClick() {
     if(m_ready_btn->is_loading) return;
     if(m_ready_btn->is_loading) return;
-    engine->getSound()->play(m_osu->getSkin()->getMenuHit());
+    engine->getSound()->play(osu->getSkin()->getMenuHit());
 
 
     int nb_ready = 0;
     int nb_ready = 0;
     bool is_ready = false;
     bool is_ready = false;
@@ -850,15 +848,15 @@ void RoomScreen::onReadyButtonClick() {
 }
 }
 
 
 void RoomScreen::onSelectModsClicked() {
 void RoomScreen::onSelectModsClicked() {
-    engine->getSound()->play(m_osu->getSkin()->getMenuHit());
-    m_osu->m_modSelector->setVisible(true);
+    engine->getSound()->play(osu->getSkin()->getMenuHit());
+    osu->m_modSelector->setVisible(true);
     m_bVisible = false;
     m_bVisible = false;
 }
 }
 
 
 void RoomScreen::onSelectMapClicked() {
 void RoomScreen::onSelectMapClicked() {
     if(!bancho.room.is_host()) return;
     if(!bancho.room.is_host()) return;
 
 
-    engine->getSound()->play(m_osu->getSkin()->getMenuHit());
+    engine->getSound()->play(osu->getSkin()->getMenuHit());
 
 
     Packet packet;
     Packet packet;
     packet.id = MATCH_CHANGE_SETTINGS;
     packet.id = MATCH_CHANGE_SETTINGS;
@@ -868,11 +866,11 @@ void RoomScreen::onSelectMapClicked() {
     bancho.room.pack(&packet);
     bancho.room.pack(&packet);
     send_packet(packet);
     send_packet(packet);
 
 
-    m_osu->m_songBrowser2->setVisible(true);
+    osu->m_songBrowser2->setVisible(true);
 }
 }
 
 
 void RoomScreen::onChangePasswordClicked() {
 void RoomScreen::onChangePasswordClicked() {
-    m_osu->m_prompt->prompt("New password:", fastdelegate::MakeDelegate(this, &RoomScreen::set_new_password));
+    osu->m_prompt->prompt("New password:", fastdelegate::MakeDelegate(this, &RoomScreen::set_new_password));
 }
 }
 
 
 void RoomScreen::onChangeWinConditionClicked() {
 void RoomScreen::onChangeWinConditionClicked() {
@@ -896,7 +894,7 @@ void RoomScreen::onWinConditionSelected(UString win_condition_str, int win_condi
     bancho.room.pack(&packet);
     bancho.room.pack(&packet);
     send_packet(packet);
     send_packet(packet);
 
 
-    updateLayout(m_osu->getScreenSize());
+    updateLayout(osu->getScreenSize());
 }
 }
 
 
 void RoomScreen::set_new_password(UString new_password) {
 void RoomScreen::set_new_password(UString new_password) {

+ 1 - 1
src/App/Osu/RoomScreen.h

@@ -26,7 +26,7 @@ class UIModList : public CBaseUIContainer {
 
 
 class RoomScreen : public OsuScreen {
 class RoomScreen : public OsuScreen {
    public:
    public:
-    RoomScreen(Osu *osu);
+    RoomScreen();
     ~RoomScreen();
     ~RoomScreen();
 
 
     virtual void draw(Graphics *g) override;
     virtual void draw(Graphics *g) override;

+ 8 - 8
src/App/Osu/ScoreboardSlot.cpp

@@ -35,13 +35,13 @@ void ScoreboardSlot::draw(Graphics *g) {
 
 
     g->setBlendMode(Graphics::BLEND_MODE::BLEND_MODE_PREMUL_ALPHA);
     g->setBlendMode(Graphics::BLEND_MODE::BLEND_MODE_PREMUL_ALPHA);
 
 
-    const float height = roundf(bancho.osu->getScreenHeight() * 0.07f);
+    const float height = roundf(osu->getScreenHeight() * 0.07f);
     const float width = roundf(height * 2.6f);  // does not include avatar_width
     const float width = roundf(height * 2.6f);  // does not include avatar_width
     const float avatar_height = height;
     const float avatar_height = height;
     const float avatar_width = avatar_height;
     const float avatar_width = avatar_height;
     const float padding = roundf(height * 0.05f);
     const float padding = roundf(height * 0.05f);
 
 
-    float start_y = bancho.osu->getScreenHeight() / 2.0f - (height * 2.5f);
+    float start_y = osu->getScreenHeight() / 2.0f - (height * 2.5f);
     start_y += m_y * height;
     start_y += m_y * height;
     start_y = roundf(start_y);
     start_y = roundf(start_y);
 
 
@@ -65,7 +65,7 @@ void ScoreboardSlot::draw(Graphics *g) {
 
 
     if(convar->getConVarByName("osu_hud_scoreboard_use_menubuttonbackground")->getBool()) {
     if(convar->getConVarByName("osu_hud_scoreboard_use_menubuttonbackground")->getBool()) {
         float bg_scale = 0.625f;
         float bg_scale = 0.625f;
-        auto bg_img = bancho.osu->getSkin()->getMenuButtonBackground2();
+        auto bg_img = osu->getSkin()->getMenuButtonBackground2();
         float oScale = bg_img->getResolutionScale() * 0.99f;
         float oScale = bg_img->getResolutionScale() * 0.99f;
         g->fillRect(0, start_y, avatar_width, height);
         g->fillRect(0, start_y, avatar_width, height);
         bg_img->draw(g,
         bg_img->draw(g,
@@ -86,7 +86,7 @@ void ScoreboardSlot::draw(Graphics *g) {
     // Draw index
     // Draw index
     g->pushTransform();
     g->pushTransform();
     {
     {
-        McFont *indexFont = bancho.osu->getSongBrowserFontBold();
+        McFont *indexFont = osu->getSongBrowserFontBold();
         UString indexString = UString::format("%i", m_index + 1);
         UString indexString = UString::format("%i", m_index + 1);
         const float scale = (avatar_height / indexFont->getHeight()) * 0.5f;
         const float scale = (avatar_height / indexFont->getHeight()) * 0.5f;
 
 
@@ -114,7 +114,7 @@ void ScoreboardSlot::draw(Graphics *g) {
     const float nameScale = 0.315f;
     const float nameScale = 0.315f;
     g->pushTransform();
     g->pushTransform();
     {
     {
-        McFont *nameFont = bancho.osu->getSongBrowserFont();
+        McFont *nameFont = osu->getSongBrowserFont();
         g->pushClipRect(McRect(avatar_width, start_y, width, height));
         g->pushClipRect(McRect(avatar_width, start_y, width, height));
 
 
         const float scale = (height / nameFont->getHeight()) * nameScale;
         const float scale = (height / nameFont->getHeight()) * nameScale;
@@ -149,7 +149,7 @@ void ScoreboardSlot::draw(Graphics *g) {
     const Color comboAccuracyColorHighlight = 0xff99fafe;
     const Color comboAccuracyColorHighlight = 0xff99fafe;
     const Color comboAccuracyColorTop = 0xff84dbe0;
     const Color comboAccuracyColorTop = 0xff84dbe0;
     const float comboScale = 0.26f;
     const float comboScale = 0.26f;
-    McFont *scoreFont = bancho.osu->getSongBrowserFont();
+    McFont *scoreFont = osu->getSongBrowserFont();
     McFont *comboFont = scoreFont;
     McFont *comboFont = scoreFont;
     McFont *accFont = comboFont;
     McFont *accFont = comboFont;
     g->pushTransform();
     g->pushTransform();
@@ -253,8 +253,8 @@ void ScoreboardSlot::draw(Graphics *g) {
 }
 }
 
 
 void ScoreboardSlot::updateIndex(int new_index, bool animate) {
 void ScoreboardSlot::updateIndex(int new_index, bool animate) {
-    bool is_player = bancho.osu->m_hud->player_slot == this;
-    int player_idx = bancho.osu->m_hud->player_slot->m_index;
+    bool is_player = osu->m_hud->player_slot == this;
+    int player_idx = osu->m_hud->player_slot->m_index;
     if(is_player) {
     if(is_player) {
         if(animate && new_index < m_index) {
         if(animate && new_index < m_index) {
             m_fFlash = 1.f;
             m_fFlash = 1.f;

+ 3 - 3
src/App/Osu/ScreenBackable.cpp

@@ -14,8 +14,8 @@
 #include "Skin.h"
 #include "Skin.h"
 #include "UIBackButton.h"
 #include "UIBackButton.h"
 
 
-ScreenBackable::ScreenBackable(Osu *osu) : OsuScreen(osu) {
-    m_backButton = new UIBackButton(m_osu, -1, 0, 0, 0, "");
+ScreenBackable::ScreenBackable() : OsuScreen() {
+    m_backButton = new UIBackButton(-1, 0, 0, 0, "");
     m_backButton->setClickCallback(fastdelegate::MakeDelegate(this, &ScreenBackable::onBack));
     m_backButton->setClickCallback(fastdelegate::MakeDelegate(this, &ScreenBackable::onBack));
 
 
     updateLayout();
     updateLayout();
@@ -49,7 +49,7 @@ void ScreenBackable::onKeyDown(KeyboardEvent &e) {
 
 
 void ScreenBackable::updateLayout() {
 void ScreenBackable::updateLayout() {
     m_backButton->updateLayout();
     m_backButton->updateLayout();
-    m_backButton->setPosY(m_osu->getScreenHeight() - m_backButton->getSize().y);
+    m_backButton->setPosY(osu->getScreenHeight() - m_backButton->getSize().y);
 }
 }
 
 
 void ScreenBackable::onResolutionChange(Vector2 newResolution) { updateLayout(); }
 void ScreenBackable::onResolutionChange(Vector2 newResolution) { updateLayout(); }

+ 2 - 15
src/App/Osu/ScreenBackable.h

@@ -1,21 +1,10 @@
-//================ Copyright (c) 2016, PG, All rights reserved. =================//
-//
-// Purpose:		screen + back button
-//
-// $NoKeywords: $
-//===============================================================================//
-
-#ifndef OSUSCREENBACKABLE_H
-#define OSUSCREENBACKABLE_H
-
+#pragma once
 #include "OsuScreen.h"
 #include "OsuScreen.h"
 #include "UIBackButton.h"
 #include "UIBackButton.h"
 
 
-class Osu;
-
 class ScreenBackable : public OsuScreen {
 class ScreenBackable : public OsuScreen {
    public:
    public:
-    ScreenBackable(Osu *osu);
+    ScreenBackable();
     virtual ~ScreenBackable();
     virtual ~ScreenBackable();
 
 
     virtual void draw(Graphics *g);
     virtual void draw(Graphics *g);
@@ -30,5 +19,3 @@ class ScreenBackable : public OsuScreen {
 
 
     UIBackButton *m_backButton;
     UIBackButton *m_backButton;
 };
 };
-
-#endif

+ 26 - 35
src/App/Osu/Skin.cpp

@@ -1,10 +1,3 @@
-//================ Copyright (c) 2015, PG, All rights reserved. =================//
-//
-// Purpose:		skin loader and container
-//
-// $NoKeywords: $osusk
-//===============================================================================//
-
 #include "Skin.h"
 #include "Skin.h"
 
 
 #include <string.h>
 #include <string.h>
@@ -66,8 +59,7 @@ ConVar *Skin::m_osu_skin_hd = &osu_skin_hd;
 ConVar *Skin::m_osu_skin_ref = NULL;
 ConVar *Skin::m_osu_skin_ref = NULL;
 ConVar *Skin::m_osu_mod_fposu_ref = NULL;
 ConVar *Skin::m_osu_mod_fposu_ref = NULL;
 
 
-Skin::Skin(Osu *osu, UString name, std::string filepath, bool isDefaultSkin) {
-    m_osu = osu;
+Skin::Skin(UString name, std::string filepath, bool isDefaultSkin) {
     m_sName = name;
     m_sName = name;
     m_sFilePath = filepath;
     m_sFilePath = filepath;
     m_bIsDefaultSkin = isDefaultSkin;
     m_bIsDefaultSkin = isDefaultSkin;
@@ -341,15 +333,14 @@ void Skin::update() {
         m_bReady = true;
         m_bReady = true;
 
 
         // force effect volume update
         // force effect volume update
-        m_osu->m_volumeOverlay->onEffectVolumeChange();
+        osu->m_volumeOverlay->onEffectVolumeChange();
     }
     }
 
 
     // shitty check to not animate while paused with hitobjects in background
     // shitty check to not animate while paused with hitobjects in background
-    if(m_osu->isInPlayMode() && !m_osu->getSelectedBeatmap()->isPlaying() && !osu_skin_animation_force.getBool())
-        return;
+    if(osu->isInPlayMode() && !osu->getSelectedBeatmap()->isPlaying() && !osu_skin_animation_force.getBool()) return;
 
 
-    const bool useEngineTimeForAnimations = !m_osu->isInPlayMode();
-    const long curMusicPos = m_osu->getSelectedBeatmap()->getCurMusicPosWithOffsets();
+    const bool useEngineTimeForAnimations = !osu->isInPlayMode();
+    const long curMusicPos = osu->getSelectedBeatmap()->getCurMusicPosWithOffsets();
     for(int i = 0; i < m_images.size(); i++) {
     for(int i = 0; i < m_images.size(); i++) {
         m_images[i]->update(m_animationSpeedMultiplier, useEngineTimeForAnimations, curMusicPos);
         m_images[i]->update(m_animationSpeedMultiplier, useEngineTimeForAnimations, curMusicPos);
     }
     }
@@ -958,13 +949,13 @@ void Skin::load() {
 
 
     // delayed error notifications due to resource loading potentially blocking engine time
     // delayed error notifications due to resource loading potentially blocking engine time
     if(!parseSkinIni1Status && parseSkinIni2Status && m_osu_skin_ref->getString() != UString("default"))
     if(!parseSkinIni1Status && parseSkinIni2Status && m_osu_skin_ref->getString() != UString("default"))
-        m_osu->getNotificationOverlay()->addNotification("Error: Couldn't load skin.ini!", 0xffff0000);
+        osu->getNotificationOverlay()->addNotification("Error: Couldn't load skin.ini!", 0xffff0000);
     else if(!parseSkinIni2Status)
     else if(!parseSkinIni2Status)
-        m_osu->getNotificationOverlay()->addNotification("Error: Couldn't load DEFAULT skin.ini!!!", 0xffff0000);
+        osu->getNotificationOverlay()->addNotification("Error: Couldn't load DEFAULT skin.ini!!!", 0xffff0000);
 
 
     // TODO: is this crashing some users?
     // TODO: is this crashing some users?
     // HACKHACK: speed up initial game startup time by async loading the skin (if osu_skin_async 1 in underride)
     // HACKHACK: speed up initial game startup time by async loading the skin (if osu_skin_async 1 in underride)
-    if(m_osu->getSkin() == NULL && osu_skin_async.getBool()) {
+    if(osu->getSkin() == NULL && osu_skin_async.getBool()) {
         while(engine->getResourceManager()->isLoading()) {
         while(engine->getResourceManager()->isLoading()) {
             engine->getResourceManager()->update();
             engine->getResourceManager()->update();
             env->sleep(0);
             env->sleep(0);
@@ -1153,14 +1144,16 @@ Color Skin::getComboColorForCounter(int i, int offset) {
 void Skin::setBeatmapComboColors(std::vector<Color> colors) { m_beatmapComboColors = colors; }
 void Skin::setBeatmapComboColors(std::vector<Color> colors) { m_beatmapComboColors = colors; }
 
 
 void Skin::playHitCircleSound(int sampleType, float pan) {
 void Skin::playHitCircleSound(int sampleType, float pan) {
-    if(m_iSampleVolume <= 0 || (m_osu->getInstanceID() > 0 && m_osu->getInstanceID() != osu2_sound_source_id.getInt()))
+    if(m_iSampleVolume <= 0) {
         return;
         return;
+    }
 
 
     if(!osu_sound_panning.getBool() || (m_osu_mod_fposu_ref->getBool() && !osu_mod_fposu_sound_panning.getBool()) ||
     if(!osu_sound_panning.getBool() || (m_osu_mod_fposu_ref->getBool() && !osu_mod_fposu_sound_panning.getBool()) ||
-       (GameRules::osu_mod_fps.getBool() && !osu_mod_fps_sound_panning.getBool()))
+       (GameRules::osu_mod_fps.getBool() && !osu_mod_fps_sound_panning.getBool())) {
         pan = 0.0f;
         pan = 0.0f;
-    else
+    } else {
         pan *= osu_sound_panning_multiplier.getFloat();
         pan *= osu_sound_panning_multiplier.getFloat();
+    }
 
 
     int actualSampleSet = m_iSampleSet;
     int actualSampleSet = m_iSampleSet;
     if(osu_skin_force_hitsound_sample_set.getInt() > 0) actualSampleSet = osu_skin_force_hitsound_sample_set.getInt();
     if(osu_skin_force_hitsound_sample_set.getInt() > 0) actualSampleSet = osu_skin_force_hitsound_sample_set.getInt();
@@ -1191,14 +1184,14 @@ void Skin::playHitCircleSound(int sampleType, float pan) {
 }
 }
 
 
 void Skin::playSliderTickSound(float pan) {
 void Skin::playSliderTickSound(float pan) {
-    if(m_iSampleVolume <= 0 || (m_osu->getInstanceID() > 0 && m_osu->getInstanceID() != osu2_sound_source_id.getInt()))
-        return;
+    if(m_iSampleVolume <= 0) return;
 
 
     if(!osu_sound_panning.getBool() || (m_osu_mod_fposu_ref->getBool() && !osu_mod_fposu_sound_panning.getBool()) ||
     if(!osu_sound_panning.getBool() || (m_osu_mod_fposu_ref->getBool() && !osu_mod_fposu_sound_panning.getBool()) ||
-       (GameRules::osu_mod_fps.getBool() && !osu_mod_fps_sound_panning.getBool()))
+       (GameRules::osu_mod_fps.getBool() && !osu_mod_fps_sound_panning.getBool())) {
         pan = 0.0f;
         pan = 0.0f;
-    else
+    } else {
         pan *= osu_sound_panning_multiplier.getFloat();
         pan *= osu_sound_panning_multiplier.getFloat();
+    }
 
 
     switch(m_iSampleSet) {
     switch(m_iSampleSet) {
         case 3:
         case 3:
@@ -1214,13 +1207,12 @@ void Skin::playSliderTickSound(float pan) {
 }
 }
 
 
 void Skin::playSliderSlideSound(float pan) {
 void Skin::playSliderSlideSound(float pan) {
-    if((m_osu->getInstanceID() > 0 && m_osu->getInstanceID() != osu2_sound_source_id.getInt())) return;
-
     if(!osu_sound_panning.getBool() || (m_osu_mod_fposu_ref->getBool() && !osu_mod_fposu_sound_panning.getBool()) ||
     if(!osu_sound_panning.getBool() || (m_osu_mod_fposu_ref->getBool() && !osu_mod_fposu_sound_panning.getBool()) ||
-       (GameRules::osu_mod_fps.getBool() && !osu_mod_fps_sound_panning.getBool()))
+       (GameRules::osu_mod_fps.getBool() && !osu_mod_fps_sound_panning.getBool())) {
         pan = 0.0f;
         pan = 0.0f;
-    else
+    } else {
         pan *= osu_sound_panning_multiplier.getFloat();
         pan *= osu_sound_panning_multiplier.getFloat();
+    }
 
 
     switch(m_iSampleSet) {
     switch(m_iSampleSet) {
         case 3:
         case 3:
@@ -1254,16 +1246,15 @@ void Skin::playSliderSlideSound(float pan) {
 }
 }
 
 
 void Skin::playSpinnerSpinSound() {
 void Skin::playSpinnerSpinSound() {
-    if((m_osu->getInstanceID() > 0 && m_osu->getInstanceID() != osu2_sound_source_id.getInt())) return;
-
-    if(!m_spinnerSpinSound->isPlaying()) engine->getSound()->play(m_spinnerSpinSound);
+    if(!m_spinnerSpinSound->isPlaying()) {
+        engine->getSound()->play(m_spinnerSpinSound);
+    }
 }
 }
 
 
 void Skin::playSpinnerBonusSound() {
 void Skin::playSpinnerBonusSound() {
-    if(m_iSampleVolume <= 0 || (m_osu->getInstanceID() > 0 && m_osu->getInstanceID() != osu2_sound_source_id.getInt()))
-        return;
-
-    engine->getSound()->play(m_spinnerBonus);
+    if(m_iSampleVolume > 0) {
+        engine->getSound()->play(m_spinnerBonus);
+    }
 }
 }
 
 
 void Skin::stopSliderSlideSound(int sampleSet) {
 void Skin::stopSliderSlideSound(int sampleSet) {

+ 2 - 16
src/App/Osu/Skin.h

@@ -1,13 +1,4 @@
-//================ Copyright (c) 2015, PG, All rights reserved. =================//
-//
-// Purpose:		skin loader and container
-//
-// $NoKeywords: $osusk
-//===============================================================================//
-
-#ifndef OSUSKIN_H
-#define OSUSKIN_H
-
+#pragma once
 #include "cbase.h"
 #include "cbase.h"
 
 
 class Image;
 class Image;
@@ -15,7 +6,6 @@ class Sound;
 class Resource;
 class Resource;
 class ConVar;
 class ConVar;
 
 
-class Osu;
 class SkinImage;
 class SkinImage;
 
 
 class Skin {
 class Skin {
@@ -25,7 +15,7 @@ class Skin {
     static ConVar *m_osu_skin_async;
     static ConVar *m_osu_skin_async;
     static ConVar *m_osu_skin_hd;
     static ConVar *m_osu_skin_hd;
 
 
-    Skin(Osu *osu, UString name, std::string filepath, bool isDefaultSkin = false);
+    Skin(UString name, std::string filepath, bool isDefaultSkin = false);
     virtual ~Skin();
     virtual ~Skin();
 
 
     void update();
     void update();
@@ -59,7 +49,6 @@ class Skin {
     // drawable helpers
     // drawable helpers
     inline std::string getName() { return m_sName; }
     inline std::string getName() { return m_sName; }
     inline std::string getFilePath() { return m_sFilePath; }
     inline std::string getFilePath() { return m_sFilePath; }
-    inline Osu *getOsu() { return m_osu; }
 
 
     // raw
     // raw
     inline Image *getMissingTexture() { return m_missingTexture; }
     inline Image *getMissingTexture() { return m_missingTexture; }
@@ -366,7 +355,6 @@ class Skin {
     void onEffectVolumeChange(UString oldValue, UString newValue);
     void onEffectVolumeChange(UString oldValue, UString newValue);
     void onIgnoreBeatmapSampleVolumeChange(UString oldValue, UString newValue);
     void onIgnoreBeatmapSampleVolumeChange(UString oldValue, UString newValue);
 
 
-    Osu *m_osu;
     bool m_bReady;
     bool m_bReady;
     bool m_bIsDefaultSkin;
     bool m_bIsDefaultSkin;
     float m_animationSpeedMultiplier;
     float m_animationSpeedMultiplier;
@@ -690,5 +678,3 @@ class Skin {
 
 
     std::vector<std::string> m_filepathsForExport;
     std::vector<std::string> m_filepathsForExport;
 };
 };
-
-#endif

+ 1 - 3
src/App/Osu/SkinImage.cpp

@@ -395,9 +395,7 @@ float SkinImage::getImageScale() {
         return 1.0f;
         return 1.0f;
 }
 }
 
 
-float SkinImage::getResolutionScale() {
-    return Osu::getImageScale(m_skin->getOsu(), m_vBaseSizeForScaling2x, m_fOsuSize);
-}
+float SkinImage::getResolutionScale() { return Osu::getImageScale(m_vBaseSizeForScaling2x, m_fOsuSize); }
 
 
 bool SkinImage::isReady() {
 bool SkinImage::isReady() {
     if(m_bReady) return true;
     if(m_bReady) return true;

+ 39 - 59
src/App/Osu/Slider.cpp

@@ -1,10 +1,3 @@
-//================ Copyright (c) 2015, PG, All rights reserved. =================//
-//
-// Purpose:		slider
-//
-// $NoKeywords: $slider
-//===============================================================================//
-
 #include "Slider.h"
 #include "Slider.h"
 
 
 #include "AnimationHandler.h"
 #include "AnimationHandler.h"
@@ -313,7 +306,7 @@ void Slider::draw(Graphics *g) {
                     Vector2 pos = m_beatmap->osuCoords2Pixels(m_curve->pointAt(1.0f));
                     Vector2 pos = m_beatmap->osuCoords2Pixels(m_curve->pointAt(1.0f));
                     float rotation = m_curve->getEndAngle() - m_osu_playfield_rotation_ref->getFloat() -
                     float rotation = m_curve->getEndAngle() - m_osu_playfield_rotation_ref->getFloat() -
                                      m_beatmap->getPlayfieldRotation();
                                      m_beatmap->getPlayfieldRotation();
-                    if(m_beatmap->getOsu()->getModHR()) rotation = 360.0f - rotation;
+                    if(osu->getModHR()) rotation = 360.0f - rotation;
                     if(m_osu_playfield_mirror_horizontal_ref->getBool()) rotation = 360.0f - rotation;
                     if(m_osu_playfield_mirror_horizontal_ref->getBool()) rotation = 360.0f - rotation;
                     if(m_osu_playfield_mirror_vertical_ref->getBool()) rotation = 180.0f - rotation;
                     if(m_osu_playfield_mirror_vertical_ref->getBool()) rotation = 180.0f - rotation;
 
 
@@ -342,7 +335,7 @@ void Slider::draw(Graphics *g) {
                     Vector2 pos = m_beatmap->osuCoords2Pixels(m_curve->pointAt(0.0f));
                     Vector2 pos = m_beatmap->osuCoords2Pixels(m_curve->pointAt(0.0f));
                     float rotation = m_curve->getStartAngle() - m_osu_playfield_rotation_ref->getFloat() -
                     float rotation = m_curve->getStartAngle() - m_osu_playfield_rotation_ref->getFloat() -
                                      m_beatmap->getPlayfieldRotation();
                                      m_beatmap->getPlayfieldRotation();
-                    if(m_beatmap->getOsu()->getModHR()) rotation = 360.0f - rotation;
+                    if(osu->getModHR()) rotation = 360.0f - rotation;
                     if(m_osu_playfield_mirror_horizontal_ref->getBool()) rotation = 360.0f - rotation;
                     if(m_osu_playfield_mirror_horizontal_ref->getBool()) rotation = 360.0f - rotation;
                     if(m_osu_playfield_mirror_vertical_ref->getBool()) rotation = 180.0f - rotation;
                     if(m_osu_playfield_mirror_vertical_ref->getBool()) rotation = 180.0f - rotation;
 
 
@@ -371,21 +364,19 @@ void Slider::draw(Graphics *g) {
 
 
     // slider body fade animation, draw start/end circle hit animation
     // slider body fade animation, draw start/end circle hit animation
 
 
-    if(m_fEndSliderBodyFadeAnimation > 0.0f && m_fEndSliderBodyFadeAnimation != 1.0f &&
-       !m_beatmap->getOsu()->getModHD()) {
+    if(m_fEndSliderBodyFadeAnimation > 0.0f && m_fEndSliderBodyFadeAnimation != 1.0f && !osu->getModHD()) {
         std::vector<Vector2> emptyVector;
         std::vector<Vector2> emptyVector;
         std::vector<Vector2> alwaysPoints;
         std::vector<Vector2> alwaysPoints;
         alwaysPoints.push_back(m_beatmap->osuCoords2Pixels(m_curve->pointAt(m_fSlidePercent)));
         alwaysPoints.push_back(m_beatmap->osuCoords2Pixels(m_curve->pointAt(m_fSlidePercent)));
         if(!osu_slider_shrink.getBool())
         if(!osu_slider_shrink.getBool())
             drawBody(g, 1.0f - m_fEndSliderBodyFadeAnimation, 0, 1);
             drawBody(g, 1.0f - m_fEndSliderBodyFadeAnimation, 0, 1);
         else if(osu_slider_body_lazer_fadeout_style.getBool())
         else if(osu_slider_body_lazer_fadeout_style.getBool())
-            SliderRenderer::draw(g, m_beatmap->getOsu(), emptyVector, alwaysPoints, m_beatmap->getHitcircleDiameter(),
-                                 0.0f, 0.0f,
+            SliderRenderer::draw(g, emptyVector, alwaysPoints, m_beatmap->getHitcircleDiameter(), 0.0f, 0.0f,
                                  m_beatmap->getSkin()->getComboColorForCounter(m_iColorCounter, m_iColorOffset), 1.0f,
                                  m_beatmap->getSkin()->getComboColorForCounter(m_iColorCounter, m_iColorOffset), 1.0f,
                                  1.0f - m_fEndSliderBodyFadeAnimation, getTime());
                                  1.0f - m_fEndSliderBodyFadeAnimation, getTime());
     }
     }
 
 
-    if(m_fStartHitAnimation > 0.0f && m_fStartHitAnimation != 1.0f && !m_beatmap->getOsu()->getModHD()) {
+    if(m_fStartHitAnimation > 0.0f && m_fStartHitAnimation != 1.0f && !osu->getModHD()) {
         float alpha = 1.0f - m_fStartHitAnimation;
         float alpha = 1.0f - m_fStartHitAnimation;
 
 
         float scale = m_fStartHitAnimation;
         float scale = m_fStartHitAnimation;
@@ -423,7 +414,7 @@ void Slider::draw(Graphics *g) {
         g->popTransform();
         g->popTransform();
     }
     }
 
 
-    if(m_fEndHitAnimation > 0.0f && m_fEndHitAnimation != 1.0f && !m_beatmap->getOsu()->getModHD()) {
+    if(m_fEndHitAnimation > 0.0f && m_fEndHitAnimation != 1.0f && !osu->getModHD()) {
         float alpha = 1.0f - m_fEndHitAnimation;
         float alpha = 1.0f - m_fEndHitAnimation;
 
 
         float scale = m_fEndHitAnimation;
         float scale = m_fEndHitAnimation;
@@ -487,8 +478,7 @@ void Slider::draw2(Graphics *g, bool drawApproachCircle, bool drawOnlyApproachCi
     // draw followcircle
     // draw followcircle
     // HACKHACK: this is not entirely correct (due to m_bHeldTillEnd, if held within 300 range but then released, will
     // HACKHACK: this is not entirely correct (due to m_bHeldTillEnd, if held within 300 range but then released, will
     // flash followcircle at the end)
     // flash followcircle at the end)
-    if((m_bVisible && m_bCursorInside &&
-        (isClickHeldSlider() || m_beatmap->getOsu()->getModAuto() || m_beatmap->getOsu()->getModRelax())) ||
+    if((m_bVisible && m_bCursorInside && (isClickHeldSlider() || osu->getModAuto() || osu->getModRelax())) ||
        (m_bFinished && m_fFollowCircleAnimationAlpha > 0.0f && m_bHeldTillEnd)) {
        (m_bFinished && m_fFollowCircleAnimationAlpha > 0.0f && m_bHeldTillEnd)) {
         Vector2 point = m_beatmap->osuCoords2Pixels(m_vCurPointRaw);
         Vector2 point = m_beatmap->osuCoords2Pixels(m_vCurPointRaw);
 
 
@@ -608,26 +598,21 @@ void Slider::drawBody(Graphics *g, float alpha, float from, float to) {
 
 
     const Color undimmedComboColor = m_beatmap->getSkin()->getComboColorForCounter(m_iColorCounter, m_iColorOffset);
     const Color undimmedComboColor = m_beatmap->getSkin()->getComboColorForCounter(m_iColorCounter, m_iColorOffset);
 
 
-    if(m_beatmap->getOsu()->shouldFallBackToLegacySliderRenderer()) {
+    if(osu->shouldFallBackToLegacySliderRenderer()) {
         std::vector<Vector2> screenPoints = m_curve->getPoints();
         std::vector<Vector2> screenPoints = m_curve->getPoints();
         for(int p = 0; p < screenPoints.size(); p++) {
         for(int p = 0; p < screenPoints.size(); p++) {
             screenPoints[p] = m_beatmap->osuCoords2Pixels(screenPoints[p]);
             screenPoints[p] = m_beatmap->osuCoords2Pixels(screenPoints[p]);
         }
         }
 
 
         // peppy sliders
         // peppy sliders
-        SliderRenderer::draw(g, m_beatmap->getOsu(), screenPoints, alwaysPoints, m_beatmap->getHitcircleDiameter(),
-                             from, to, undimmedComboColor, m_fHittableDimRGBColorMultiplierPercent, alpha, getTime());
-
-        // mm sliders
-        /// SliderRenderer::drawMM(g, m_beatmap->getOsu(), screenPoints, m_beatmap->getHitcircleDiameter(), from, to,
-        /// m_beatmap->getSkin()->getComboColorForCounter(m_iColorCounter, m_iColorOffset),
-        /// m_fHittableDimRGBColorMultiplierPercent, alpha, getTime());
+        SliderRenderer::draw(g, screenPoints, alwaysPoints, m_beatmap->getHitcircleDiameter(), from, to,
+                             undimmedComboColor, m_fHittableDimRGBColorMultiplierPercent, alpha, getTime());
     } else {
     } else {
         // vertex buffered sliders
         // vertex buffered sliders
         // as the base mesh is centered at (0, 0, 0) and in raw osu coordinates, we have to scale and translate it to
         // as the base mesh is centered at (0, 0, 0) and in raw osu coordinates, we have to scale and translate it to
         // make it fit the actual desktop playfield
         // make it fit the actual desktop playfield
-        const float scale = GameRules::getPlayfieldScaleFactor(m_beatmap->getOsu());
-        Vector2 translation = GameRules::getPlayfieldCenter(m_beatmap->getOsu());
+        const float scale = GameRules::getPlayfieldScaleFactor();
+        Vector2 translation = GameRules::getPlayfieldCenter();
 
 
         if(m_beatmap->hasFailed())
         if(m_beatmap->hasFailed())
             translation =
             translation =
@@ -635,9 +620,8 @@ void Slider::drawBody(Graphics *g, float alpha, float from, float to) {
 
 
         if(m_osu_mod_fps_ref->getBool()) translation += m_beatmap->getFirstPersonCursorDelta();
         if(m_osu_mod_fps_ref->getBool()) translation += m_beatmap->getFirstPersonCursorDelta();
 
 
-        SliderRenderer::draw(g, m_beatmap->getOsu(), m_vao, alwaysPoints, translation, scale,
-                             m_beatmap->getHitcircleDiameter(), from, to, undimmedComboColor,
-                             m_fHittableDimRGBColorMultiplierPercent, alpha, getTime());
+        SliderRenderer::draw(g, m_vao, alwaysPoints, translation, scale, m_beatmap->getHitcircleDiameter(), from, to,
+                             undimmedComboColor, m_fHittableDimRGBColorMultiplierPercent, alpha, getTime());
     }
     }
 }
 }
 
 
@@ -679,7 +663,7 @@ void Slider::update(long curPos) {
     m_fReverseArrowAlpha *= osu_slider_reverse_arrow_alpha_multiplier.getFloat();
     m_fReverseArrowAlpha *= osu_slider_reverse_arrow_alpha_multiplier.getFloat();
 
 
     m_fBodyAlpha = m_fAlpha;
     m_fBodyAlpha = m_fAlpha;
-    if(m_beatmap->getOsu()->getModHD())  // hidden modifies the body alpha
+    if(osu->getModHD())  // hidden modifies the body alpha
     {
     {
         m_fBodyAlpha = m_fAlphaWithoutHidden;  // fade in as usual
         m_fBodyAlpha = m_fAlphaWithoutHidden;  // fade in as usual
 
 
@@ -742,27 +726,27 @@ void Slider::update(long curPos) {
         m_bCursorLeft ? m_beatmap->getHitcircleDiameter() / 2.0f : m_beatmap->getSliderFollowCircleDiameter() / 2.0f;
         m_bCursorLeft ? m_beatmap->getHitcircleDiameter() / 2.0f : m_beatmap->getSliderFollowCircleDiameter() / 2.0f;
     const bool isBeatmapCursorInside = ((m_beatmap->getCursorPos() - m_vCurPoint).length() < followRadius);
     const bool isBeatmapCursorInside = ((m_beatmap->getCursorPos() - m_vCurPoint).length() < followRadius);
     const bool isAutoCursorInside =
     const bool isAutoCursorInside =
-        (m_beatmap->getOsu()->getModAuto() && (!m_osu_auto_cursordance_ref->getBool() ||
-                                               ((m_beatmap->getCursorPos() - m_vCurPoint).length() < followRadius)));
+        (osu->getModAuto() && (!m_osu_auto_cursordance_ref->getBool() ||
+                               ((m_beatmap->getCursorPos() - m_vCurPoint).length() < followRadius)));
     m_bCursorInside = (isAutoCursorInside || isBeatmapCursorInside);
     m_bCursorInside = (isAutoCursorInside || isBeatmapCursorInside);
     m_bCursorLeft = !m_bCursorInside;
     m_bCursorLeft = !m_bCursorInside;
 
 
     // handle slider start
     // handle slider start
     if(!m_bStartFinished) {
     if(!m_bStartFinished) {
-        if(m_beatmap->getOsu()->getModAuto()) {
+        if(osu->getModAuto()) {
             if(curPos >= m_iTime) {
             if(curPos >= m_iTime) {
                 onHit(LiveScore::HIT::HIT_300, 0, false);
                 onHit(LiveScore::HIT::HIT_300, 0, false);
-                bancho.osu->holding_slider = true;
+                osu->holding_slider = true;
             }
             }
         } else {
         } else {
             long delta = curPos - m_iTime;
             long delta = curPos - m_iTime;
 
 
-            if(m_beatmap->getOsu()->getModRelax()) {
+            if(osu->getModRelax()) {
                 if(curPos >= m_iTime + (long)m_osu_relax_offset_ref->getInt() && !m_beatmap->isPaused() &&
                 if(curPos >= m_iTime + (long)m_osu_relax_offset_ref->getInt() && !m_beatmap->isPaused() &&
                    !m_beatmap->isContinueScheduled()) {
                    !m_beatmap->isContinueScheduled()) {
                     const Vector2 pos = m_beatmap->osuCoords2Pixels(m_curve->pointAt(0.0f));
                     const Vector2 pos = m_beatmap->osuCoords2Pixels(m_curve->pointAt(0.0f));
                     const float cursorDelta = (m_beatmap->getCursorPos() - pos).length();
                     const float cursorDelta = (m_beatmap->getCursorPos() - pos).length();
-                    if((cursorDelta < m_beatmap->getHitcircleDiameter() / 2.0f && m_beatmap->getOsu()->getModRelax())) {
+                    if((cursorDelta < m_beatmap->getHitcircleDiameter() / 2.0f && osu->getModRelax())) {
                         LiveScore::HIT result = GameRules::getHitResult(delta, m_beatmap);
                         LiveScore::HIT result = GameRules::getHitResult(delta, m_beatmap);
 
 
                         if(result != LiveScore::HIT::HIT_NULL) {
                         if(result != LiveScore::HIT::HIT_NULL) {
@@ -772,7 +756,7 @@ void Slider::update(long curPos) {
 
 
                             m_startResult = result;
                             m_startResult = result;
                             onHit(m_startResult, delta, false, targetDelta, targetAngle);
                             onHit(m_startResult, delta, false, targetDelta, targetAngle);
-                            bancho.osu->holding_slider = true;
+                            osu->holding_slider = true;
                         }
                         }
                     }
                     }
                 }
                 }
@@ -784,7 +768,7 @@ void Slider::update(long curPos) {
                 if(delta > (long)GameRules::getHitWindow50(m_beatmap)) {
                 if(delta > (long)GameRules::getHitWindow50(m_beatmap)) {
                     m_startResult = LiveScore::HIT::HIT_MISS;
                     m_startResult = LiveScore::HIT::HIT_MISS;
                     onHit(m_startResult, delta, false);
                     onHit(m_startResult, delta, false);
-                    bancho.osu->holding_slider = false;
+                    osu->holding_slider = false;
                 }
                 }
             }
             }
         }
         }
@@ -807,7 +791,7 @@ void Slider::update(long curPos) {
         const long offset = (long)osu_slider_end_inside_check_offset.getInt();
         const long offset = (long)osu_slider_end_inside_check_offset.getInt();
         const long lenienceHackEndTime =
         const long lenienceHackEndTime =
             std::max(m_iTime + m_iObjectDuration / 2, (m_iTime + m_iObjectDuration) - offset);
             std::max(m_iTime + m_iObjectDuration / 2, (m_iTime + m_iObjectDuration) - offset);
-        const bool isTrackingCorrectly = (isClickHeldSlider() || m_beatmap->getOsu()->getModRelax()) && m_bCursorInside;
+        const bool isTrackingCorrectly = (isClickHeldSlider() || osu->getModRelax()) && m_bCursorInside;
         if(isTrackingCorrectly) {
         if(isTrackingCorrectly) {
             if(isTrackingStrictTrackingMod) {
             if(isTrackingStrictTrackingMod) {
                 m_iStrictTrackingModLastClickHeldTime = curPos;
                 m_iStrictTrackingModLastClickHeldTime = curPos;
@@ -867,9 +851,8 @@ void Slider::update(long curPos) {
         for(int i = 0; i < m_clicks.size(); i++) {
         for(int i = 0; i < m_clicks.size(); i++) {
             if(!m_clicks[i].finished && curPos >= m_clicks[i].time) {
             if(!m_clicks[i].finished && curPos >= m_clicks[i].time) {
                 m_clicks[i].finished = true;
                 m_clicks[i].finished = true;
-                m_clicks[i].successful = (isClickHeldSlider() && m_bCursorInside) ||
-                                         m_beatmap->getOsu()->getModAuto() ||
-                                         (m_beatmap->getOsu()->getModRelax() && m_bCursorInside);
+                m_clicks[i].successful = (isClickHeldSlider() && m_bCursorInside) || osu->getModAuto() ||
+                                         (osu->getModRelax() && m_bCursorInside);
 
 
                 if(m_clicks[i].type == 0)
                 if(m_clicks[i].type == 0)
                     onRepeatHit(m_clicks[i].successful, m_clicks[i].sliderend);
                     onRepeatHit(m_clicks[i].successful, m_clicks[i].sliderend);
@@ -879,11 +862,11 @@ void Slider::update(long curPos) {
         }
         }
 
 
         // handle auto, and the last circle
         // handle auto, and the last circle
-        if(m_beatmap->getOsu()->getModAuto()) {
+        if(osu->getModAuto()) {
             if(curPos >= m_iTime + m_iObjectDuration) {
             if(curPos >= m_iTime + m_iObjectDuration) {
                 m_bHeldTillEnd = true;
                 m_bHeldTillEnd = true;
                 onHit(LiveScore::HIT::HIT_300, 0, true);
                 onHit(LiveScore::HIT::HIT_300, 0, true);
-                bancho.osu->holding_slider = false;
+                osu->holding_slider = false;
             }
             }
         } else {
         } else {
             if(curPos >= m_iTime + m_iObjectDuration) {
             if(curPos >= m_iTime + m_iObjectDuration) {
@@ -923,11 +906,11 @@ void Slider::update(long curPos) {
 
 
                     const float percent = numActualHits / numMaxPossibleHits;
                     const float percent = numActualHits / numMaxPossibleHits;
 
 
-                    const bool allow300 = (osu_slider_scorev2.getBool() || m_beatmap->getOsu()->getModScorev2())
+                    const bool allow300 = (osu_slider_scorev2.getBool() || osu->getModScorev2())
                                               ? (m_startResult == LiveScore::HIT::HIT_300)
                                               ? (m_startResult == LiveScore::HIT::HIT_300)
                                               : true;
                                               : true;
                     const bool allow100 =
                     const bool allow100 =
-                        (osu_slider_scorev2.getBool() || m_beatmap->getOsu()->getModScorev2())
+                        (osu_slider_scorev2.getBool() || osu->getModScorev2())
                             ? (m_startResult == LiveScore::HIT::HIT_300 || m_startResult == LiveScore::HIT::HIT_100)
                             ? (m_startResult == LiveScore::HIT::HIT_300 || m_startResult == LiveScore::HIT::HIT_100)
                             : true;
                             : true;
 
 
@@ -950,14 +933,14 @@ void Slider::update(long curPos) {
                     isEndResultComingFromStrictTrackingMod = true;
                     isEndResultComingFromStrictTrackingMod = true;
 
 
                 onHit(m_endResult, 0, true, 0.0f, 0.0f, isEndResultComingFromStrictTrackingMod);
                 onHit(m_endResult, 0, true, 0.0f, 0.0f, isEndResultComingFromStrictTrackingMod);
-                bancho.osu->holding_slider = false;
+                osu->holding_slider = false;
             }
             }
         }
         }
 
 
         // handle sliderslide sound
         // handle sliderslide sound
         if(m_bStartFinished && !m_bEndFinished && m_bCursorInside && m_iDelta <= 0 &&
         if(m_bStartFinished && !m_bEndFinished && m_bCursorInside && m_iDelta <= 0 &&
-           (isClickHeldSlider() || m_beatmap->getOsu()->getModAuto() || m_beatmap->getOsu()->getModRelax()) &&
-           !m_beatmap->isPaused() && !m_beatmap->isWaiting() && m_beatmap->isPlaying()) {
+           (isClickHeldSlider() || osu->getModAuto() || osu->getModRelax()) && !m_beatmap->isPaused() &&
+           !m_beatmap->isWaiting() && m_beatmap->isPlaying()) {
             const Vector2 osuCoords = m_beatmap->pixels2OsuCoords(m_beatmap->osuCoords2Pixels(m_vCurPointRaw));
             const Vector2 osuCoords = m_beatmap->pixels2OsuCoords(m_beatmap->osuCoords2Pixels(m_vCurPointRaw));
 
 
             m_beatmap->getSkin()->playSliderSlideSound(GameRules::osuCoords2Pan(osuCoords.x));
             m_beatmap->getSkin()->playSliderSlideSound(GameRules::osuCoords2Pan(osuCoords.x));
@@ -970,7 +953,6 @@ void Slider::update(long curPos) {
 }
 }
 
 
 void Slider::updateAnimations(long curPos) {
 void Slider::updateAnimations(long curPos) {
-    Osu *osu = m_beatmap->getOsu();
     float animation_multiplier = osu->getSpeedMultiplier() / osu->getAnimationSpeedMultiplier();
     float animation_multiplier = osu->getSpeedMultiplier() / osu->getAnimationSpeedMultiplier();
 
 
     float fadein_fade_time = GameRules::osu_slider_followcircle_fadein_fade_time.getFloat() * animation_multiplier;
     float fadein_fade_time = GameRules::osu_slider_followcircle_fadein_fade_time.getFloat() * animation_multiplier;
@@ -1009,7 +991,7 @@ void Slider::updateAnimations(long curPos) {
 }
 }
 
 
 void Slider::updateStackPosition(float stackOffset) {
 void Slider::updateStackPosition(float stackOffset) {
-    if(m_curve != NULL) m_curve->updateStackPosition(m_iStack * stackOffset, m_beatmap->getOsu()->getModHR());
+    if(m_curve != NULL) m_curve->updateStackPosition(m_iStack * stackOffset, osu->getModHR());
 }
 }
 
 
 void Slider::miss(long curPos) {
 void Slider::miss(long curPos) {
@@ -1021,7 +1003,7 @@ void Slider::miss(long curPos) {
     if(!m_bStartFinished) {
     if(!m_bStartFinished) {
         m_startResult = LiveScore::HIT::HIT_MISS;
         m_startResult = LiveScore::HIT::HIT_MISS;
         onHit(m_startResult, delta, false);
         onHit(m_startResult, delta, false);
-        bancho.osu->holding_slider = false;
+        osu->holding_slider = false;
     }
     }
 
 
     // endcircle, repeats, ticks
     // endcircle, repeats, ticks
@@ -1049,7 +1031,7 @@ void Slider::miss(long curPos) {
 
 
             m_endResult = LiveScore::HIT::HIT_MISS;
             m_endResult = LiveScore::HIT::HIT_MISS;
             onHit(m_endResult, 0, true);
             onHit(m_endResult, 0, true);
-            bancho.osu->holding_slider = false;
+            osu->holding_slider = false;
         }
         }
     }
     }
 }
 }
@@ -1113,7 +1095,7 @@ void Slider::onClickEvent(std::vector<Click> &clicks) {
                 clicks.erase(clicks.begin());
                 clicks.erase(clicks.begin());
                 m_startResult = result;
                 m_startResult = result;
                 onHit(m_startResult, delta, false, targetDelta, targetAngle);
                 onHit(m_startResult, delta, false, targetDelta, targetAngle);
-                bancho.osu->holding_slider = true;
+                osu->holding_slider = true;
             }
             }
         }
         }
     }
     }
@@ -1184,7 +1166,7 @@ void Slider::onHit(LiveScore::HIT result, long delta, bool startOrEnd, float tar
             }
             }
         }
         }
 
 
-        if(!m_beatmap->getOsu()->getModTarget())
+        if(!osu->getModTarget())
             m_beatmap->addHitResult(
             m_beatmap->addHitResult(
                 this, result, delta, false, false, true, false, true,
                 this, result, delta, false, false, true, false, true,
                 true);  // not end of combo, show in hiterrorbar, ignore for accuracy, increase combo, don't count
                 true);  // not end of combo, show in hiterrorbar, ignore for accuracy, increase combo, don't count
@@ -1261,7 +1243,6 @@ void Slider::onRepeatHit(bool successful, bool sliderend) {
                                                      : m_iSampleType,
                                                      : m_iSampleType,
                                                  GameRules::osuCoords2Pan(osuCoords.x));
                                                  GameRules::osuCoords2Pan(osuCoords.x));
 
 
-        Osu *osu = m_beatmap->getOsu();
         float animation_multiplier = osu->getSpeedMultiplier() / osu->getAnimationSpeedMultiplier();
         float animation_multiplier = osu->getSpeedMultiplier() / osu->getAnimationSpeedMultiplier();
         float tick_pulse_time = GameRules::osu_slider_followcircle_tick_pulse_time.getFloat() * animation_multiplier;
         float tick_pulse_time = GameRules::osu_slider_followcircle_tick_pulse_time.getFloat() * animation_multiplier;
 
 
@@ -1318,7 +1299,6 @@ void Slider::onTickHit(bool successful, int tickIndex) {
 
 
         m_beatmap->getSkin()->playSliderTickSound(GameRules::osuCoords2Pan(osuCoords.x));
         m_beatmap->getSkin()->playSliderTickSound(GameRules::osuCoords2Pan(osuCoords.x));
 
 
-        Osu *osu = m_beatmap->getOsu();
         float animation_multiplier = osu->getSpeedMultiplier() / osu->getAnimationSpeedMultiplier();
         float animation_multiplier = osu->getSpeedMultiplier() / osu->getAnimationSpeedMultiplier();
         float tick_pulse_time = GameRules::osu_slider_followcircle_tick_pulse_time.getFloat() * animation_multiplier;
         float tick_pulse_time = GameRules::osu_slider_followcircle_tick_pulse_time.getFloat() * animation_multiplier;
 
 
@@ -1429,7 +1409,7 @@ void Slider::rebuildVertexBuffer(bool useRawCoords) {
         }
         }
     }
     }
     SAFE_DELETE(m_vao);
     SAFE_DELETE(m_vao);
-    m_vao = SliderRenderer::generateVAO(m_beatmap->getOsu(), osuCoordPoints, m_beatmap->getRawHitcircleDiameter());
+    m_vao = SliderRenderer::generateVAO(osuCoordPoints, m_beatmap->getRawHitcircleDiameter());
 }
 }
 
 
 bool Slider::isClickHeldSlider() {
 bool Slider::isClickHeldSlider() {

+ 18 - 18
src/App/Osu/SliderRenderer.cpp

@@ -62,12 +62,12 @@ ConVar osu_slider_legacy_use_baked_vao(
     "use baked cone mesh instead of raw mesh for legacy slider renderer (disabled by default because usually slower on "
     "use baked cone mesh instead of raw mesh for legacy slider renderer (disabled by default because usually slower on "
     "very old gpus even though it should not be)");
     "very old gpus even though it should not be)");
 
 
-VertexArrayObject *SliderRenderer::generateVAO(Osu *osu, const std::vector<Vector2> &points, float hitcircleDiameter,
+VertexArrayObject *SliderRenderer::generateVAO(const std::vector<Vector2> &points, float hitcircleDiameter,
                                                Vector3 translation, bool skipOOBPoints) {
                                                Vector3 translation, bool skipOOBPoints) {
     engine->getResourceManager()->requestNextLoadUnmanaged();
     engine->getResourceManager()->requestNextLoadUnmanaged();
     VertexArrayObject *vao = engine->getResourceManager()->createVertexArrayObject();
     VertexArrayObject *vao = engine->getResourceManager()->createVertexArrayObject();
 
 
-    checkUpdateVars(osu, hitcircleDiameter);
+    checkUpdateVars(hitcircleDiameter);
 
 
     const Vector3 xOffset = Vector3(hitcircleDiameter, 0, 0);
     const Vector3 xOffset = Vector3(hitcircleDiameter, 0, 0);
     const Vector3 yOffset = Vector3(0, hitcircleDiameter, 0);
     const Vector3 yOffset = Vector3(0, hitcircleDiameter, 0);
@@ -126,12 +126,12 @@ VertexArrayObject *SliderRenderer::generateVAO(Osu *osu, const std::vector<Vecto
     return vao;
     return vao;
 }
 }
 
 
-void SliderRenderer::draw(Graphics *g, Osu *osu, const std::vector<Vector2> &points,
-                          const std::vector<Vector2> &alwaysPoints, float hitcircleDiameter, float from, float to,
-                          Color undimmedColor, float colorRGBMultiplier, float alpha, long sliderTimeForRainbow) {
+void SliderRenderer::draw(Graphics *g, const std::vector<Vector2> &points, const std::vector<Vector2> &alwaysPoints,
+                          float hitcircleDiameter, float from, float to, Color undimmedColor, float colorRGBMultiplier,
+                          float alpha, long sliderTimeForRainbow) {
     if(osu_slider_alpha_multiplier.getFloat() <= 0.0f || alpha <= 0.0f) return;
     if(osu_slider_alpha_multiplier.getFloat() <= 0.0f || alpha <= 0.0f) return;
 
 
-    checkUpdateVars(osu, hitcircleDiameter);
+    checkUpdateVars(hitcircleDiameter);
 
 
     const int drawFromIndex = clamp<int>((int)std::round(points.size() * from), 0, points.size());
     const int drawFromIndex = clamp<int>((int)std::round(points.size() * from), 0, points.size());
     const int drawUpToIndex = clamp<int>((int)std::round(points.size() * to), 0, points.size());
     const int drawUpToIndex = clamp<int>((int)std::round(points.size() * to), 0, points.size());
@@ -246,13 +246,13 @@ void SliderRenderer::draw(Graphics *g, Osu *osu, const std::vector<Vector2> &poi
                 // draw curve mesh
                 // draw curve mesh
                 {
                 {
                     drawFillSliderBodyPeppy(
                     drawFillSliderBodyPeppy(
-                        g, osu, points,
+                        g, points,
                         (osu_slider_legacy_use_baked_vao.getBool() ? UNIT_CIRCLE_VAO_BAKED : UNIT_CIRCLE_VAO),
                         (osu_slider_legacy_use_baked_vao.getBool() ? UNIT_CIRCLE_VAO_BAKED : UNIT_CIRCLE_VAO),
                         hitcircleDiameter / 2.0f, drawFromIndex, drawUpToIndex, BLEND_SHADER);
                         hitcircleDiameter / 2.0f, drawFromIndex, drawUpToIndex, BLEND_SHADER);
 
 
                     if(alwaysPoints.size() > 0)
                     if(alwaysPoints.size() > 0)
-                        drawFillSliderBodyPeppy(g, osu, alwaysPoints, UNIT_CIRCLE_VAO_BAKED, hitcircleDiameter / 2.0f,
-                                                0, alwaysPoints.size(), BLEND_SHADER);
+                        drawFillSliderBodyPeppy(g, alwaysPoints, UNIT_CIRCLE_VAO_BAKED, hitcircleDiameter / 2.0f, 0,
+                                                alwaysPoints.size(), BLEND_SHADER);
                 }
                 }
             }
             }
 
 
@@ -276,7 +276,7 @@ void SliderRenderer::draw(Graphics *g, Osu *osu, const std::vector<Vector2> &poi
                                           m_fBoundingBoxMaxY - m_fBoundingBoxMinY);
                                           m_fBoundingBoxMaxY - m_fBoundingBoxMinY);
 }
 }
 
 
-void SliderRenderer::draw(Graphics *g, Osu *osu, VertexArrayObject *vao, const std::vector<Vector2> &alwaysPoints,
+void SliderRenderer::draw(Graphics *g, VertexArrayObject *vao, const std::vector<Vector2> &alwaysPoints,
                           Vector2 translation, float scale, float hitcircleDiameter, float from, float to,
                           Vector2 translation, float scale, float hitcircleDiameter, float from, float to,
                           Color undimmedColor, float colorRGBMultiplier, float alpha, long sliderTimeForRainbow,
                           Color undimmedColor, float colorRGBMultiplier, float alpha, long sliderTimeForRainbow,
                           bool doEnableRenderTarget, bool doDisableRenderTarget, bool doDrawSliderFrameBufferToScreen) {
                           bool doEnableRenderTarget, bool doDisableRenderTarget, bool doDrawSliderFrameBufferToScreen) {
@@ -284,7 +284,7 @@ void SliderRenderer::draw(Graphics *g, Osu *osu, VertexArrayObject *vao, const s
        (alpha <= 0.0f && doDrawSliderFrameBufferToScreen) || vao == NULL)
        (alpha <= 0.0f && doDrawSliderFrameBufferToScreen) || vao == NULL)
         return;
         return;
 
 
-    checkUpdateVars(osu, hitcircleDiameter);
+    checkUpdateVars(hitcircleDiameter);
 
 
     if(osu_slider_debug_draw_square_vao.getBool()) {
     if(osu_slider_debug_draw_square_vao.getBool()) {
         const Color dimmedColor = COLOR(255, (int)(COLOR_GET_Ri(undimmedColor) * colorRGBMultiplier),
         const Color dimmedColor = COLOR(255, (int)(COLOR_GET_Ri(undimmedColor) * colorRGBMultiplier),
@@ -435,8 +435,8 @@ void SliderRenderer::draw(Graphics *g, Osu *osu, VertexArrayObject *vao, const s
                     g->popTransform();
                     g->popTransform();
 
 
                     if(alwaysPoints.size() > 0)
                     if(alwaysPoints.size() > 0)
-                        drawFillSliderBodyPeppy(g, osu, alwaysPoints, UNIT_CIRCLE_VAO_BAKED, hitcircleDiameter / 2.0f,
-                                                0, alwaysPoints.size(), BLEND_SHADER);
+                        drawFillSliderBodyPeppy(g, alwaysPoints, UNIT_CIRCLE_VAO_BAKED, hitcircleDiameter / 2.0f, 0,
+                                                alwaysPoints.size(), BLEND_SHADER);
                 }
                 }
             }
             }
 
 
@@ -454,12 +454,12 @@ void SliderRenderer::draw(Graphics *g, Osu *osu, VertexArrayObject *vao, const s
     }
     }
 }
 }
 
 
-void SliderRenderer::drawMM(Graphics *g, Osu *osu, const std::vector<Vector2> &points, float hitcircleDiameter,
-                            float from, float to, Color undimmedColor, float colorRGBMultiplier, float alpha,
+void SliderRenderer::drawMM(Graphics *g, const std::vector<Vector2> &points, float hitcircleDiameter, float from,
+                            float to, Color undimmedColor, float colorRGBMultiplier, float alpha,
                             long sliderTimeForRainbow) {
                             long sliderTimeForRainbow) {
     if(osu_slider_alpha_multiplier.getFloat() <= 0.0f || alpha <= 0.0f) return;
     if(osu_slider_alpha_multiplier.getFloat() <= 0.0f || alpha <= 0.0f) return;
 
 
-    checkUpdateVars(osu, hitcircleDiameter);
+    checkUpdateVars(hitcircleDiameter);
 
 
     // TODO: shit
     // TODO: shit
     int numPointsTotal = points.size();
     int numPointsTotal = points.size();
@@ -549,7 +549,7 @@ void SliderRenderer::drawMM(Graphics *g, Osu *osu, const std::vector<Vector2> &p
     osu->getSliderFrameBuffer()->draw(g, 0, 0);
     osu->getSliderFrameBuffer()->draw(g, 0, 0);
 }
 }
 
 
-void SliderRenderer::drawFillSliderBodyPeppy(Graphics *g, Osu *osu, const std::vector<Vector2> &points,
+void SliderRenderer::drawFillSliderBodyPeppy(Graphics *g, const std::vector<Vector2> &points,
                                              VertexArrayObject *circleMesh, float radius, int drawFromIndex,
                                              VertexArrayObject *circleMesh, float radius, int drawFromIndex,
                                              int drawUpToIndex, Shader *shader) {
                                              int drawUpToIndex, Shader *shader) {
     if(drawFromIndex < 0) drawFromIndex = 0;
     if(drawFromIndex < 0) drawFromIndex = 0;
@@ -744,7 +744,7 @@ void SliderRenderer::drawFillSliderBodyMM(Graphics *g, const std::vector<Vector2
     }
     }
 }
 }
 
 
-void SliderRenderer::checkUpdateVars(Osu *osu, float hitcircleDiameter) {
+void SliderRenderer::checkUpdateVars(float hitcircleDiameter) {
     // static globals
     // static globals
 
 
     // build shaders and circle mesh
     // build shaders and circle mesh

+ 13 - 28
src/App/Osu/SliderRenderer.h

@@ -1,20 +1,9 @@
-//================ Copyright (c) 2016, PG, All rights reserved. =================//
-//
-// Purpose:		static renderer class, so it can be used outside of Slider
-//
-// $NoKeywords: $sliderrender
-//===============================================================================//
-
-#ifndef OSUSLIDERRENDERER_H
-#define OSUSLIDERRENDERER_H
-
+#pragma once
 #include "cbase.h"
 #include "cbase.h"
 
 
 class Shader;
 class Shader;
 class VertexArrayObject;
 class VertexArrayObject;
 
 
-class Osu;
-
 class SliderRenderer {
 class SliderRenderer {
    public:
    public:
     static Shader *BLEND_SHADER;
     static Shader *BLEND_SHADER;
@@ -22,30 +11,28 @@ class SliderRenderer {
     static float UNIT_CIRCLE_VAO_DIAMETER;
     static float UNIT_CIRCLE_VAO_DIAMETER;
 
 
    public:
    public:
-    static VertexArrayObject *generateVAO(Osu *osu, const std::vector<Vector2> &points, float hitcircleDiameter,
+    static VertexArrayObject *generateVAO(const std::vector<Vector2> &points, float hitcircleDiameter,
                                           Vector3 translation = Vector3(0, 0, 0), bool skipOOBPoints = true);
                                           Vector3 translation = Vector3(0, 0, 0), bool skipOOBPoints = true);
 
 
-    static void draw(Graphics *g, Osu *osu, const std::vector<Vector2> &points,
-                     const std::vector<Vector2> &alwaysPoints, float hitcircleDiameter, float from = 0.0f,
-                     float to = 1.0f, Color undimmedColor = 0xffffffff, float colorRGBMultiplier = 1.0f,
-                     float alpha = 1.0f, long sliderTimeForRainbow = 0);
-    static void draw(Graphics *g, Osu *osu, VertexArrayObject *vao, const std::vector<Vector2> &alwaysPoints,
-                     Vector2 translation, float scale, float hitcircleDiameter, float from = 0.0f, float to = 1.0f,
+    static void draw(Graphics *g, const std::vector<Vector2> &points, const std::vector<Vector2> &alwaysPoints,
+                     float hitcircleDiameter, float from = 0.0f, float to = 1.0f, Color undimmedColor = 0xffffffff,
+                     float colorRGBMultiplier = 1.0f, float alpha = 1.0f, long sliderTimeForRainbow = 0);
+    static void draw(Graphics *g, VertexArrayObject *vao, const std::vector<Vector2> &alwaysPoints, Vector2 translation,
+                     float scale, float hitcircleDiameter, float from = 0.0f, float to = 1.0f,
                      Color undimmedColor = 0xffffffff, float colorRGBMultiplier = 1.0f, float alpha = 1.0f,
                      Color undimmedColor = 0xffffffff, float colorRGBMultiplier = 1.0f, float alpha = 1.0f,
                      long sliderTimeForRainbow = 0, bool doEnableRenderTarget = true, bool doDisableRenderTarget = true,
                      long sliderTimeForRainbow = 0, bool doEnableRenderTarget = true, bool doDisableRenderTarget = true,
                      bool doDrawSliderFrameBufferToScreen = true);
                      bool doDrawSliderFrameBufferToScreen = true);
-    static void drawMM(Graphics *g, Osu *osu, const std::vector<Vector2> &points, float hitcircleDiameter,
-                       float from = 0.0f, float to = 1.0f, Color undimmedColor = 0xffffffff,
-                       float colorRGBMultiplier = 1.0f, float alpha = 1.0f, long sliderTimeForRainbow = 0);
+    static void drawMM(Graphics *g, const std::vector<Vector2> &points, float hitcircleDiameter, float from = 0.0f,
+                       float to = 1.0f, Color undimmedColor = 0xffffffff, float colorRGBMultiplier = 1.0f,
+                       float alpha = 1.0f, long sliderTimeForRainbow = 0);
 
 
    private:
    private:
-    static void drawFillSliderBodyPeppy(Graphics *g, Osu *osu, const std::vector<Vector2> &points,
-                                        VertexArrayObject *circleMesh, float radius, int drawFromIndex,
-                                        int drawUpToIndex, Shader *shader = NULL);
+    static void drawFillSliderBodyPeppy(Graphics *g, const std::vector<Vector2> &points, VertexArrayObject *circleMesh,
+                                        float radius, int drawFromIndex, int drawUpToIndex, Shader *shader = NULL);
     static void drawFillSliderBodyMM(Graphics *g, const std::vector<Vector2> &points, float radius, int drawFromIndex,
     static void drawFillSliderBodyMM(Graphics *g, const std::vector<Vector2> &points, float radius, int drawFromIndex,
                                      int drawUpToIndex);
                                      int drawUpToIndex);
 
 
-    static void checkUpdateVars(Osu *osu, float hitcircleDiameter);
+    static void checkUpdateVars(float hitcircleDiameter);
 
 
     static void resetRenderTargetBoundingBox();
     static void resetRenderTargetBoundingBox();
 
 
@@ -63,5 +50,3 @@ class SliderRenderer {
     static float m_fBoundingBoxMinY;
     static float m_fBoundingBoxMinY;
     static float m_fBoundingBoxMaxY;
     static float m_fBoundingBoxMaxY;
 };
 };
-
-#endif

+ 12 - 13
src/App/Osu/SongBrowser/Button.cpp

@@ -31,16 +31,15 @@ int Button::sortHackCounter = 0;
 
 
 // Color Button::inactiveDifficultyBackgroundColor = COLOR(255, 0, 150, 236); // blue
 // Color Button::inactiveDifficultyBackgroundColor = COLOR(255, 0, 150, 236); // blue
 
 
-Button::Button(Osu *osu, SongBrowser *songBrowser, CBaseUIScrollView *view, UIContextMenu *contextMenu, float xPos,
-               float yPos, float xSize, float ySize, UString name)
+Button::Button(SongBrowser *songBrowser, CBaseUIScrollView *view, UIContextMenu *contextMenu, float xPos, float yPos,
+               float xSize, float ySize, UString name)
     : CBaseUIButton(xPos, yPos, xSize, ySize, name, "") {
     : CBaseUIButton(xPos, yPos, xSize, ySize, name, "") {
-    m_osu = osu;
     m_view = view;
     m_view = view;
     m_songBrowser = songBrowser;
     m_songBrowser = songBrowser;
     m_contextMenu = contextMenu;
     m_contextMenu = contextMenu;
 
 
-    m_font = m_osu->getSongBrowserFont();
-    m_fontBold = m_osu->getSongBrowserFontBold();
+    m_font = osu->getSongBrowserFont();
+    m_fontBold = osu->getSongBrowserFontBold();
 
 
     m_bVisible = false;
     m_bVisible = false;
     m_bSelected = false;
     m_bSelected = false;
@@ -106,7 +105,7 @@ void Button::drawMenuButtonBackground(Graphics *g) {
     {
     {
         g->scale(m_fScale, m_fScale);
         g->scale(m_fScale, m_fScale);
         g->translate(m_vPos.x + m_vSize.x / 2, m_vPos.y + m_vSize.y / 2);
         g->translate(m_vPos.x + m_vSize.x / 2, m_vPos.y + m_vSize.y / 2);
-        g->drawImage(m_osu->getSkin()->getMenuButtonBackground());
+        g->drawImage(osu->getSkin()->getMenuButtonBackground());
     }
     }
     g->popTransform();
     g->popTransform();
 }
 }
@@ -150,12 +149,12 @@ void Button::mouse_update(bool *propagate_clicks) {
 void Button::updateLayoutEx() {
 void Button::updateLayoutEx() {
     const float uiScale = Osu::ui_scale->getFloat();
     const float uiScale = Osu::ui_scale->getFloat();
 
 
-    Image *menuButtonBackground = m_osu->getSkin()->getMenuButtonBackground();
+    Image *menuButtonBackground = osu->getSkin()->getMenuButtonBackground();
     {
     {
         const Vector2 minimumSize =
         const Vector2 minimumSize =
-            Vector2(699.0f, 103.0f) * (m_osu->getSkin()->isMenuButtonBackground2x() ? 2.0f : 1.0f);
+            Vector2(699.0f, 103.0f) * (osu->getSkin()->isMenuButtonBackground2x() ? 2.0f : 1.0f);
         const float minimumScale = Osu::getImageScaleToFitResolution(menuButtonBackground, minimumSize);
         const float minimumScale = Osu::getImageScaleToFitResolution(menuButtonBackground, minimumSize);
-        m_fScale = Osu::getImageScale(m_osu, menuButtonBackground->getSize() * minimumScale, 64.0f) * uiScale;
+        m_fScale = Osu::getImageScale(menuButtonBackground->getSize() * minimumScale, 64.0f) * uiScale;
     }
     }
 
 
     if(m_bVisible)  // lag prevention (animationHandler overflow)
     if(m_bVisible)  // lag prevention (animationHandler overflow)
@@ -248,7 +247,7 @@ void Button::deselect() { m_bSelected = false; }
 void Button::resetAnimations() { setMoveAwayState(MOVE_AWAY_STATE::MOVE_CENTER, false); }
 void Button::resetAnimations() { setMoveAwayState(MOVE_AWAY_STATE::MOVE_CENTER, false); }
 
 
 void Button::onClicked() {
 void Button::onClicked() {
-    engine->getSound()->play(m_osu->getSkin()->getMenuClick());
+    engine->getSound()->play(osu->getSkin()->getMenuClick());
 
 
     CBaseUIButton::onClicked();
     CBaseUIButton::onClicked();
 
 
@@ -261,7 +260,7 @@ void Button::onMouseInside() {
     // hover sound
     // hover sound
     if(engine->getTime() > lastHoverSoundTime + 0.05f)  // to avoid earraep
     if(engine->getTime() > lastHoverSoundTime + 0.05f)  // to avoid earraep
     {
     {
-        if(engine->hasFocus()) engine->getSound()->play(m_osu->getSkin()->getMenuClick());
+        if(engine->hasFocus()) engine->getSound()->play(osu->getSkin()->getMenuClick());
 
 
         lastHoverSoundTime = engine->getTime();
         lastHoverSoundTime = engine->getTime();
     }
     }
@@ -309,9 +308,9 @@ void Button::setTargetRelPosY(float targetRelPosY) {
 }
 }
 
 
 Vector2 Button::getActualOffset() const {
 Vector2 Button::getActualOffset() const {
-    const float hd2xMultiplier = m_osu->getSkin()->isMenuButtonBackground2x() ? 2.0f : 1.0f;
+    const float hd2xMultiplier = osu->getSkin()->isMenuButtonBackground2x() ? 2.0f : 1.0f;
     const float correctedMarginPixelsY =
     const float correctedMarginPixelsY =
-        (2 * marginPixelsY + m_osu->getSkin()->getMenuButtonBackground()->getHeight() / hd2xMultiplier - 103.0f) / 2.0f;
+        (2 * marginPixelsY + osu->getSkin()->getMenuButtonBackground()->getHeight() / hd2xMultiplier - 103.0f) / 2.0f;
     return Vector2((int)(marginPixelsX * m_fScale * hd2xMultiplier),
     return Vector2((int)(marginPixelsX * m_fScale * hd2xMultiplier),
                    (int)(correctedMarginPixelsY * m_fScale * hd2xMultiplier));
                    (int)(correctedMarginPixelsY * m_fScale * hd2xMultiplier));
 }
 }

+ 2 - 4
src/App/Osu/SongBrowser/Button.h

@@ -1,7 +1,6 @@
 #pragma once
 #pragma once
 #include "CBaseUIButton.h"
 #include "CBaseUIButton.h"
 
 
-class Osu;
 class DatabaseBeatmap;
 class DatabaseBeatmap;
 class SongBrowser;
 class SongBrowser;
 class UIContextMenu;
 class UIContextMenu;
@@ -10,8 +9,8 @@ class CBaseUIScrollView;
 
 
 class Button : public CBaseUIButton {
 class Button : public CBaseUIButton {
    public:
    public:
-    Button(Osu *osu, SongBrowser *songBrowser, CBaseUIScrollView *view, UIContextMenu *contextMenu, float xPos,
-           float yPos, float xSize, float ySize, UString name);
+    Button(SongBrowser *songBrowser, CBaseUIScrollView *view, UIContextMenu *contextMenu, float xPos, float yPos,
+           float xSize, float ySize, UString name);
     virtual ~Button();
     virtual ~Button();
     void deleteAnimations();
     void deleteAnimations();
 
 
@@ -53,7 +52,6 @@ class Button : public CBaseUIButton {
     virtual void onSelected(bool wasSelected, bool autoSelectBottomMostChild, bool wasParentSelected) { ; }
     virtual void onSelected(bool wasSelected, bool autoSelectBottomMostChild, bool wasParentSelected) { ; }
     virtual void onRightMouseUpInside() { ; }
     virtual void onRightMouseUpInside() { ; }
 
 
-    Osu *m_osu;
     CBaseUIScrollView *m_view;
     CBaseUIScrollView *m_view;
     SongBrowser *m_songBrowser;
     SongBrowser *m_songBrowser;
     UIContextMenu *m_contextMenu;
     UIContextMenu *m_contextMenu;

+ 8 - 8
src/App/Osu/SongBrowser/CollectionButton.cpp

@@ -33,10 +33,10 @@ ConVar osu_songbrowser_button_collection_inactive_color_g("osu_songbrowser_butto
 ConVar osu_songbrowser_button_collection_inactive_color_b("osu_songbrowser_button_collection_inactive_color_b", 143,
 ConVar osu_songbrowser_button_collection_inactive_color_b("osu_songbrowser_button_collection_inactive_color_b", 143,
                                                           FCVAR_DEFAULT);
                                                           FCVAR_DEFAULT);
 
 
-CollectionButton::CollectionButton(Osu *osu, SongBrowser *songBrowser, CBaseUIScrollView *view,
-                                   UIContextMenu *contextMenu, float xPos, float yPos, float xSize, float ySize,
-                                   UString name, UString collectionName, std::vector<Button *> children)
-    : Button(osu, songBrowser, view, contextMenu, xPos, yPos, xSize, ySize, name) {
+CollectionButton::CollectionButton(SongBrowser *songBrowser, CBaseUIScrollView *view, UIContextMenu *contextMenu,
+                                   float xPos, float yPos, float xSize, float ySize, UString name,
+                                   UString collectionName, std::vector<Button *> children)
+    : Button(songBrowser, view, contextMenu, xPos, yPos, xSize, ySize, name) {
     m_sCollectionName = collectionName;
     m_sCollectionName = collectionName;
     m_children = children;
     m_children = children;
 
 
@@ -50,7 +50,7 @@ void CollectionButton::draw(Graphics *g) {
     Button::draw(g);
     Button::draw(g);
     if(!m_bVisible) return;
     if(!m_bVisible) return;
 
 
-    Skin *skin = m_osu->getSkin();
+    Skin *skin = osu->getSkin();
 
 
     // scaling
     // scaling
     const Vector2 pos = getActualPos();
     const Vector2 pos = getActualPos();
@@ -94,7 +94,7 @@ void CollectionButton::onSelected(bool wasSelected, bool autoSelectBottomMostChi
 void CollectionButton::onRightMouseUpInside() { triggerContextMenu(engine->getMouse()->getPos()); }
 void CollectionButton::onRightMouseUpInside() { triggerContextMenu(engine->getMouse()->getPos()); }
 
 
 void CollectionButton::triggerContextMenu(Vector2 pos) {
 void CollectionButton::triggerContextMenu(Vector2 pos) {
-    if(m_osu->getSongBrowser()->getGroupingMode() != SongBrowser::GROUP::GROUP_COLLECTIONS) return;
+    if(osu->getSongBrowser()->getGroupingMode() != SongBrowser::GROUP::GROUP_COLLECTIONS) return;
 
 
     if(m_contextMenu != NULL) {
     if(m_contextMenu != NULL) {
         m_contextMenu->setPos(pos);
         m_contextMenu->setPos(pos);
@@ -182,7 +182,7 @@ void CollectionButton::onRenameCollectionConfirmed(UString text, int id) {
         save_collections();
         save_collections();
 
 
         // (trigger re-sorting of collection buttons)
         // (trigger re-sorting of collection buttons)
-        m_osu->getSongBrowser()->onCollectionButtonContextMenu(this, m_sCollectionName.c_str(), 3);
+        osu->getSongBrowser()->onCollectionButtonContextMenu(this, m_sCollectionName.c_str(), 3);
     }
     }
 }
 }
 
 
@@ -190,7 +190,7 @@ void CollectionButton::onDeleteCollectionConfirmed(UString text, int id) {
     if(id != 2) return;
     if(id != 2) return;
 
 
     // just forward it
     // just forward it
-    m_osu->getSongBrowser()->onCollectionButtonContextMenu(this, m_sCollectionName.c_str(), id);
+    osu->getSongBrowser()->onCollectionButtonContextMenu(this, m_sCollectionName.c_str(), id);
 }
 }
 
 
 Color CollectionButton::getActiveBackgroundColor() const {
 Color CollectionButton::getActiveBackgroundColor() const {

+ 2 - 2
src/App/Osu/SongBrowser/CollectionButton.h

@@ -3,8 +3,8 @@
 
 
 class CollectionButton : public Button {
 class CollectionButton : public Button {
    public:
    public:
-    CollectionButton(Osu *osu, SongBrowser *songBrowser, CBaseUIScrollView *view, UIContextMenu *contextMenu,
-                     float xPos, float yPos, float xSize, float ySize, UString name, UString collectionName,
+    CollectionButton(SongBrowser *songBrowser, CBaseUIScrollView *view, UIContextMenu *contextMenu, float xPos,
+                     float yPos, float xSize, float ySize, UString name, UString collectionName,
                      std::vector<Button *> children);
                      std::vector<Button *> children);
 
 
     virtual void draw(Graphics *g);
     virtual void draw(Graphics *g);

+ 45 - 48
src/App/Osu/SongBrowser/InfoLabel.cpp

@@ -16,10 +16,9 @@
 #include "ResourceManager.h"
 #include "ResourceManager.h"
 #include "TooltipOverlay.h"
 #include "TooltipOverlay.h"
 
 
-InfoLabel::InfoLabel(Osu *osu, float xPos, float yPos, float xSize, float ySize, UString name)
+InfoLabel::InfoLabel(float xPos, float yPos, float xSize, float ySize, UString name)
     : CBaseUIButton(xPos, yPos, xSize, ySize, name, "") {
     : CBaseUIButton(xPos, yPos, xSize, ySize, name, "") {
-    m_osu = osu;
-    m_font = m_osu->getSubTitleFont();
+    m_font = osu->getSubTitleFont();
 
 
     m_osu_debug_ref = convar->getConVarByName("osu_debug");
     m_osu_debug_ref = convar->getConVarByName("osu_debug");
     m_osu_songbrowser_dynamic_star_recalc_ref = convar->getConVarByName("osu_songbrowser_dynamic_star_recalc");
     m_osu_songbrowser_dynamic_star_recalc_ref = convar->getConVarByName("osu_songbrowser_dynamic_star_recalc");
@@ -126,8 +125,7 @@ void InfoLabel::draw(Graphics *g) {
 
 
     // draw song info (length, bpm, objects)
     // draw song info (length, bpm, objects)
     const Color songInfoColor =
     const Color songInfoColor =
-        (m_osu->getSpeedMultiplier() != 1.0f ? (m_osu->getSpeedMultiplier() > 1.0f ? 0xffff7f7f : 0xffadd8e6)
-                                             : 0xffffffff);
+        (osu->getSpeedMultiplier() != 1.0f ? (osu->getSpeedMultiplier() > 1.0f ? 0xffff7f7f : 0xffadd8e6) : 0xffffffff);
     g->pushTransform();
     g->pushTransform();
     {
     {
         const float scale = m_fSongInfoScale * globalScale * 0.9f;
         const float scale = m_fSongInfoScale * globalScale * 0.9f;
@@ -147,7 +145,7 @@ void InfoLabel::draw(Graphics *g) {
     g->popTransform();
     g->popTransform();
 
 
     // draw diff info (CS, AR, OD, HP, Stars)
     // draw diff info (CS, AR, OD, HP, Stars)
-    const Color diffInfoColor = m_osu->getModEZ() ? 0xffadd8e6 : (m_osu->getModHR() ? 0xffff7f7f : 0xffffffff);
+    const Color diffInfoColor = osu->getModEZ() ? 0xffadd8e6 : (osu->getModHR() ? 0xffff7f7f : 0xffffffff);
     g->pushTransform();
     g->pushTransform();
     {
     {
         const float scale = m_fDiffInfoScale * globalScale * 0.9f;
         const float scale = m_fDiffInfoScale * globalScale * 0.9f;
@@ -193,10 +191,10 @@ void InfoLabel::mouse_update(bool *propagate_clicks) {
     CBaseUIButton::mouse_update(propagate_clicks);
     CBaseUIButton::mouse_update(propagate_clicks);
 
 
     // detail info tooltip when hovering over diff info
     // detail info tooltip when hovering over diff info
-    if(isMouseInside() && !m_osu->getOptionsMenu()->isMouseInside()) {
-        Beatmap *beatmap = m_osu->getSelectedBeatmap();
+    if(isMouseInside() && !osu->getOptionsMenu()->isMouseInside()) {
+        Beatmap *beatmap = osu->getSelectedBeatmap();
         if(beatmap != NULL) {
         if(beatmap != NULL) {
-            const float speedMultiplierInv = (1.0f / m_osu->getSpeedMultiplier());
+            const float speedMultiplierInv = (1.0f / osu->getSpeedMultiplier());
 
 
             const float approachTimeRoundedCompensated =
             const float approachTimeRoundedCompensated =
                 ((int)GameRules::getApproachTime(beatmap)) * speedMultiplierInv;
                 ((int)GameRules::getApproachTime(beatmap)) * speedMultiplierInv;
@@ -209,16 +207,16 @@ void InfoLabel::mouse_update(bool *propagate_clicks) {
             const float hitobjectRadiusRoundedCompensated =
             const float hitobjectRadiusRoundedCompensated =
                 (GameRules::getRawHitCircleDiameter(beatmap->getCS()) / 2.0f);
                 (GameRules::getRawHitCircleDiameter(beatmap->getCS()) / 2.0f);
 
 
-            m_osu->getTooltipOverlay()->begin();
+            osu->getTooltipOverlay()->begin();
             {
             {
-                m_osu->getTooltipOverlay()->addLine(
+                osu->getTooltipOverlay()->addLine(
                     UString::format("Approach time: %.2fms", approachTimeRoundedCompensated));
                     UString::format("Approach time: %.2fms", approachTimeRoundedCompensated));
-                m_osu->getTooltipOverlay()->addLine(UString::format("300: +-%.2fms", hitWindow300RoundedCompensated));
-                m_osu->getTooltipOverlay()->addLine(UString::format("100: +-%.2fms", hitWindow100RoundedCompensated));
-                m_osu->getTooltipOverlay()->addLine(UString::format(" 50: +-%.2fms", hitWindow50RoundedCompensated));
-                m_osu->getTooltipOverlay()->addLine(
+                osu->getTooltipOverlay()->addLine(UString::format("300: +-%.2fms", hitWindow300RoundedCompensated));
+                osu->getTooltipOverlay()->addLine(UString::format("100: +-%.2fms", hitWindow100RoundedCompensated));
+                osu->getTooltipOverlay()->addLine(UString::format(" 50: +-%.2fms", hitWindow50RoundedCompensated));
+                osu->getTooltipOverlay()->addLine(
                     UString::format("Spinner difficulty: %.2f", GameRules::getSpinnerSpinsPerSecond(beatmap)));
                     UString::format("Spinner difficulty: %.2f", GameRules::getSpinnerSpinsPerSecond(beatmap)));
-                m_osu->getTooltipOverlay()->addLine(
+                osu->getTooltipOverlay()->addLine(
                     UString::format("Hit object radius: %.2f", hitobjectRadiusRoundedCompensated));
                     UString::format("Hit object radius: %.2f", hitobjectRadiusRoundedCompensated));
 
 
                 if(beatmap->getSelectedDifficulty2() != NULL) {
                 if(beatmap->getSelectedDifficulty2() != NULL) {
@@ -228,41 +226,41 @@ void InfoLabel::mouse_update(bool *propagate_clicks) {
                     unsigned long lengthMS = beatmap->getSelectedDifficulty2()->getLengthMS();
                     unsigned long lengthMS = beatmap->getSelectedDifficulty2()->getLengthMS();
 
 
                     const bool areStarsInaccurate =
                     const bool areStarsInaccurate =
-                        (m_osu->getSongBrowser()->getDynamicStarCalculator()->isDead() ||
-                         !m_osu->getSongBrowser()->getDynamicStarCalculator()->isAsyncReady());
+                        (osu->getSongBrowser()->getDynamicStarCalculator()->isDead() ||
+                         !osu->getSongBrowser()->getDynamicStarCalculator()->isAsyncReady());
                     if(!areStarsInaccurate) {
                     if(!areStarsInaccurate) {
-                        numObjects = m_osu->getSongBrowser()->getDynamicStarCalculator()->getNumObjects();
-                        numCircles = m_osu->getSongBrowser()->getDynamicStarCalculator()->getNumCircles();
+                        numObjects = osu->getSongBrowser()->getDynamicStarCalculator()->getNumObjects();
+                        numCircles = osu->getSongBrowser()->getDynamicStarCalculator()->getNumCircles();
                         numSliders =
                         numSliders =
-                            std::max(0, m_osu->getSongBrowser()->getDynamicStarCalculator()->getNumObjects() -
-                                            m_osu->getSongBrowser()->getDynamicStarCalculator()->getNumCircles() -
-                                            m_osu->getSongBrowser()->getDynamicStarCalculator()->getNumSpinners());
-                        lengthMS = m_osu->getSongBrowser()->getDynamicStarCalculator()->getLengthMS();
+                            std::max(0, osu->getSongBrowser()->getDynamicStarCalculator()->getNumObjects() -
+                                            osu->getSongBrowser()->getDynamicStarCalculator()->getNumCircles() -
+                                            osu->getSongBrowser()->getDynamicStarCalculator()->getNumSpinners());
+                        lengthMS = osu->getSongBrowser()->getDynamicStarCalculator()->getLengthMS();
                     }
                     }
 
 
                     const float opm =
                     const float opm =
                         (lengthMS > 0 ? ((float)numObjects / (float)(lengthMS / 1000.0f / 60.0f)) : 0.0f) *
                         (lengthMS > 0 ? ((float)numObjects / (float)(lengthMS / 1000.0f / 60.0f)) : 0.0f) *
-                        m_osu->getSpeedMultiplier();
+                        osu->getSpeedMultiplier();
                     const float cpm =
                     const float cpm =
                         (lengthMS > 0 ? ((float)numCircles / (float)(lengthMS / 1000.0f / 60.0f)) : 0.0f) *
                         (lengthMS > 0 ? ((float)numCircles / (float)(lengthMS / 1000.0f / 60.0f)) : 0.0f) *
-                        m_osu->getSpeedMultiplier();
+                        osu->getSpeedMultiplier();
                     const float spm =
                     const float spm =
                         (lengthMS > 0 ? ((float)numSliders / (float)(lengthMS / 1000.0f / 60.0f)) : 0.0f) *
                         (lengthMS > 0 ? ((float)numSliders / (float)(lengthMS / 1000.0f / 60.0f)) : 0.0f) *
-                        m_osu->getSpeedMultiplier();
+                        osu->getSpeedMultiplier();
 
 
-                    m_osu->getTooltipOverlay()->addLine(
+                    osu->getTooltipOverlay()->addLine(
                         UString::format("Circles: %i, Sliders: %i, Spinners: %i", numCircles, numSliders,
                         UString::format("Circles: %i, Sliders: %i, Spinners: %i", numCircles, numSliders,
                                         std::max(0, numObjects - numCircles - numSliders)));
                                         std::max(0, numObjects - numCircles - numSliders)));
-                    m_osu->getTooltipOverlay()->addLine(
+                    osu->getTooltipOverlay()->addLine(
                         UString::format("OPM: %i, CPM: %i, SPM: %i", (int)opm, (int)cpm, (int)spm));
                         UString::format("OPM: %i, CPM: %i, SPM: %i", (int)opm, (int)cpm, (int)spm));
-                    m_osu->getTooltipOverlay()->addLine(UString::format("ID: %i, SetID: %i",
-                                                                        beatmap->getSelectedDifficulty2()->getID(),
-                                                                        beatmap->getSelectedDifficulty2()->getSetID()));
-                    m_osu->getTooltipOverlay()->addLine(
+                    osu->getTooltipOverlay()->addLine(UString::format("ID: %i, SetID: %i",
+                                                                      beatmap->getSelectedDifficulty2()->getID(),
+                                                                      beatmap->getSelectedDifficulty2()->getSetID()));
+                    osu->getTooltipOverlay()->addLine(
                         UString::format("MD5: %s", beatmap->getSelectedDifficulty2()->getMD5Hash().toUtf8()));
                         UString::format("MD5: %s", beatmap->getSelectedDifficulty2()->getMD5Hash().toUtf8()));
                 }
                 }
             }
             }
-            m_osu->getTooltipOverlay()->end();
+            osu->getTooltipOverlay()->end();
         }
         }
     }
     }
 }
 }
@@ -314,24 +312,23 @@ void InfoLabel::setFromMissingBeatmap(long beatmapId) {
 UString InfoLabel::buildSongInfoString() {
 UString InfoLabel::buildSongInfoString() {
     unsigned long lengthMS = m_iLengthMS;
     unsigned long lengthMS = m_iLengthMS;
 
 
-    const bool areStarsInaccurate = (m_osu->getSongBrowser()->getDynamicStarCalculator()->isDead() ||
-                                     !m_osu->getSongBrowser()->getDynamicStarCalculator()->isAsyncReady());
+    const bool areStarsInaccurate = (osu->getSongBrowser()->getDynamicStarCalculator()->isDead() ||
+                                     !osu->getSongBrowser()->getDynamicStarCalculator()->isAsyncReady());
 
 
     if(!areStarsInaccurate)
     if(!areStarsInaccurate)
-        lengthMS =
-            std::max(lengthMS, (unsigned long)m_osu->getSongBrowser()->getDynamicStarCalculator()->getLengthMS());
+        lengthMS = std::max(lengthMS, (unsigned long)osu->getSongBrowser()->getDynamicStarCalculator()->getLengthMS());
 
 
-    const unsigned long fullSeconds = (lengthMS * (1.0 / m_osu->getSpeedMultiplier())) / 1000.0;
+    const unsigned long fullSeconds = (lengthMS * (1.0 / osu->getSpeedMultiplier())) / 1000.0;
     const int minutes = fullSeconds / 60;
     const int minutes = fullSeconds / 60;
     const int seconds = fullSeconds % 60;
     const int seconds = fullSeconds % 60;
 
 
-    const int minBPM = m_iMinBPM * m_osu->getSpeedMultiplier();
-    const int maxBPM = m_iMaxBPM * m_osu->getSpeedMultiplier();
-    const int mostCommonBPM = m_iMostCommonBPM * m_osu->getSpeedMultiplier();
+    const int minBPM = m_iMinBPM * osu->getSpeedMultiplier();
+    const int maxBPM = m_iMaxBPM * osu->getSpeedMultiplier();
+    const int mostCommonBPM = m_iMostCommonBPM * osu->getSpeedMultiplier();
 
 
     int numObjects = m_iNumObjects;
     int numObjects = m_iNumObjects;
 
 
-    if(!areStarsInaccurate) numObjects = m_osu->getSongBrowser()->getDynamicStarCalculator()->getNumObjects();
+    if(!areStarsInaccurate) numObjects = osu->getSongBrowser()->getDynamicStarCalculator()->getNumObjects();
 
 
     if(m_iMinBPM == m_iMaxBPM)
     if(m_iMinBPM == m_iMaxBPM)
         return UString::format("Length: %02i:%02i BPM: %i Objects: %i", minutes, seconds, maxBPM, numObjects);
         return UString::format("Length: %02i:%02i BPM: %i Objects: %i", minutes, seconds, maxBPM, numObjects);
@@ -347,12 +344,12 @@ UString InfoLabel::buildDiffInfoString() {
     float HP = m_fHP;
     float HP = m_fHP;
     float stars = m_fStars;
     float stars = m_fStars;
 
 
-    const float modStars = (float)m_osu->getSongBrowser()->getDynamicStarCalculator()->getTotalStars();
-    const float modPp = (float)m_osu->getSongBrowser()->getDynamicStarCalculator()->getPPv2();
-    const bool areStarsInaccurate = (m_osu->getSongBrowser()->getDynamicStarCalculator()->isDead() ||
-                                     !m_osu->getSongBrowser()->getDynamicStarCalculator()->isAsyncReady());
+    const float modStars = (float)osu->getSongBrowser()->getDynamicStarCalculator()->getTotalStars();
+    const float modPp = (float)osu->getSongBrowser()->getDynamicStarCalculator()->getPPv2();
+    const bool areStarsInaccurate = (osu->getSongBrowser()->getDynamicStarCalculator()->isDead() ||
+                                     !osu->getSongBrowser()->getDynamicStarCalculator()->isAsyncReady());
 
 
-    Beatmap *beatmap = m_osu->getSelectedBeatmap();
+    Beatmap *beatmap = osu->getSelectedBeatmap();
     if(beatmap != NULL) {
     if(beatmap != NULL) {
         CS = beatmap->getCS();
         CS = beatmap->getCS();
         AR = GameRules::getApproachRateForSpeedMultiplier(beatmap);
         AR = GameRules::getApproachRateForSpeedMultiplier(beatmap);

+ 1 - 3
src/App/Osu/SongBrowser/InfoLabel.h

@@ -3,13 +3,12 @@
 
 
 class McFont;
 class McFont;
 
 
-class Osu;
 class Beatmap;
 class Beatmap;
 class DatabaseBeatmap;
 class DatabaseBeatmap;
 
 
 class InfoLabel : public CBaseUIButton {
 class InfoLabel : public CBaseUIButton {
    public:
    public:
-    InfoLabel(Osu *osu, float xPos, float yPos, float xSize, float ySize, UString name);
+    InfoLabel(float xPos, float yPos, float xSize, float ySize, UString name);
 
 
     void draw(Graphics *g);
     void draw(Graphics *g);
     virtual void mouse_update(bool *propagate_clicks);
     virtual void mouse_update(bool *propagate_clicks);
@@ -52,7 +51,6 @@ class InfoLabel : public CBaseUIButton {
     ConVar *m_osu_debug_ref;
     ConVar *m_osu_debug_ref;
     ConVar *m_osu_songbrowser_dynamic_star_recalc_ref;
     ConVar *m_osu_songbrowser_dynamic_star_recalc_ref;
 
 
-    Osu *m_osu;
     McFont *m_font;
     McFont *m_font;
 
 
     int m_iMargin;
     int m_iMargin;

+ 22 - 24
src/App/Osu/SongBrowser/ScoreButton.cpp

@@ -34,10 +34,8 @@
 ConVar *ScoreButton::m_osu_scores_sort_by_pp_ref = NULL;
 ConVar *ScoreButton::m_osu_scores_sort_by_pp_ref = NULL;
 UString ScoreButton::recentScoreIconString;
 UString ScoreButton::recentScoreIconString;
 
 
-ScoreButton::ScoreButton(Osu *osu, UIContextMenu *contextMenu, float xPos, float yPos, float xSize, float ySize,
-                         STYLE style)
+ScoreButton::ScoreButton(UIContextMenu *contextMenu, float xPos, float yPos, float xSize, float ySize, STYLE style)
     : CBaseUIButton(xPos, yPos, xSize, ySize, "", "") {
     : CBaseUIButton(xPos, yPos, xSize, ySize, "", "") {
-    m_osu = osu;
     m_contextMenu = contextMenu;
     m_contextMenu = contextMenu;
     m_style = style;
     m_style = style;
 
 
@@ -67,12 +65,12 @@ void ScoreButton::draw(Graphics *g) {
     if(m_style == STYLE::SCORE_BROWSER) {
     if(m_style == STYLE::SCORE_BROWSER) {
         g->setColor(0xff000000);
         g->setColor(0xff000000);
         g->setAlpha(0.59f * (0.5f + 0.5f * m_fIndexNumberAnim));
         g->setAlpha(0.59f * (0.5f + 0.5f * m_fIndexNumberAnim));
-        Image *backgroundImage = m_osu->getSkin()->getMenuButtonBackground();
+        Image *backgroundImage = osu->getSkin()->getMenuButtonBackground();
         g->pushTransform();
         g->pushTransform();
         {
         {
             // allow overscale
             // allow overscale
             Vector2 hardcodedImageSize =
             Vector2 hardcodedImageSize =
-                Vector2(699.0f, 103.0f) * (m_osu->getSkin()->isMenuButtonBackground2x() ? 2.0f : 1.0f);
+                Vector2(699.0f, 103.0f) * (osu->getSkin()->isMenuButtonBackground2x() ? 2.0f : 1.0f);
             const float scale = Osu::getImageScaleToFillResolution(hardcodedImageSize, m_vSize);
             const float scale = Osu::getImageScaleToFillResolution(hardcodedImageSize, m_vSize);
 
 
             g->scale(scale, scale);
             g->scale(scale, scale);
@@ -97,7 +95,7 @@ void ScoreButton::draw(Graphics *g) {
 
 
         // Update avatar visibility status
         // Update avatar visibility status
         // NOTE: Not checking horizontal visibility
         // NOTE: Not checking horizontal visibility
-        auto m_scoreBrowser = m_osu->m_songBrowser2->m_scoreBrowser;
+        auto m_scoreBrowser = osu->m_songBrowser2->m_scoreBrowser;
         bool is_below_top = m_avatar->getPos().y + m_avatar->getSize().y >= m_scoreBrowser->getPos().y;
         bool is_below_top = m_avatar->getPos().y + m_avatar->getSize().y >= m_scoreBrowser->getPos().y;
         bool is_above_bottom = m_avatar->getPos().y <= m_scoreBrowser->getPos().y + m_scoreBrowser->getSize().y;
         bool is_above_bottom = m_avatar->getPos().y <= m_scoreBrowser->getPos().y + m_scoreBrowser->getSize().y;
         m_avatar->on_screen = is_below_top && is_above_bottom;
         m_avatar->on_screen = is_below_top && is_above_bottom;
@@ -105,7 +103,7 @@ void ScoreButton::draw(Graphics *g) {
     }
     }
     const float indexNumberScale = 0.35f;
     const float indexNumberScale = 0.35f;
     const float indexNumberWidthPercent = (m_style == STYLE::TOP_RANKS ? 0.075f : 0.15f);
     const float indexNumberWidthPercent = (m_style == STYLE::TOP_RANKS ? 0.075f : 0.15f);
-    McFont *indexNumberFont = m_osu->getSongBrowserFontBold();
+    McFont *indexNumberFont = osu->getSongBrowserFontBold();
     g->pushTransform();
     g->pushTransform();
     {
     {
         UString indexNumberString = UString::format("%i", m_iScoreIndexNumber);
         UString indexNumberString = UString::format("%i", m_iScoreIndexNumber);
@@ -128,7 +126,7 @@ void ScoreButton::draw(Graphics *g) {
 
 
     // grade
     // grade
     const float gradeHeightPercent = 0.7f;
     const float gradeHeightPercent = 0.7f;
-    SkinImage *grade = getGradeImage(m_osu, m_scoreGrade);
+    SkinImage *grade = getGradeImage(m_scoreGrade);
     int gradeWidth = 0;
     int gradeWidth = 0;
     g->pushTransform();
     g->pushTransform();
     {
     {
@@ -149,7 +147,7 @@ void ScoreButton::draw(Graphics *g) {
 
 
     // username | (artist + songName + diffName)
     // username | (artist + songName + diffName)
     const float usernameScale = (m_style == STYLE::TOP_RANKS ? 0.6f : 0.7f);
     const float usernameScale = (m_style == STYLE::TOP_RANKS ? 0.6f : 0.7f);
-    McFont *usernameFont = m_osu->getSongBrowserFont();
+    McFont *usernameFont = osu->getSongBrowserFont();
     g->pushClipRect(McRect(m_vPos.x, m_vPos.y, m_vSize.x, m_vSize.y));
     g->pushClipRect(McRect(m_vPos.x, m_vPos.y, m_vSize.x, m_vSize.y));
     g->pushTransform();
     g->pushTransform();
     {
     {
@@ -220,7 +218,7 @@ void ScoreButton::draw(Graphics *g) {
 
 
     // mods
     // mods
     const float modScale = 0.7f;
     const float modScale = 0.7f;
-    McFont *modFont = m_osu->getSubTitleFont();
+    McFont *modFont = osu->getSubTitleFont();
     g->pushTransform();
     g->pushTransform();
     {
     {
         const float height = rightSideThirdHeight;
         const float height = rightSideThirdHeight;
@@ -244,7 +242,7 @@ void ScoreButton::draw(Graphics *g) {
 
 
     // accuracy
     // accuracy
     const float accScale = 0.65f;
     const float accScale = 0.65f;
-    McFont *accFont = m_osu->getSubTitleFont();
+    McFont *accFont = osu->getSubTitleFont();
     g->pushTransform();
     g->pushTransform();
     {
     {
         const UString &scoreAccuracy = (m_style == STYLE::TOP_RANKS ? m_sScoreAccuracyFC : m_sScoreAccuracy);
         const UString &scoreAccuracy = (m_style == STYLE::TOP_RANKS ? m_sScoreAccuracyFC : m_sScoreAccuracy);
@@ -271,7 +269,7 @@ void ScoreButton::draw(Graphics *g) {
     // custom info (Spd.)
     // custom info (Spd.)
     if(m_style == STYLE::SCORE_BROWSER && m_sCustom.length() > 0) {
     if(m_style == STYLE::SCORE_BROWSER && m_sCustom.length() > 0) {
         const float customScale = 0.50f;
         const float customScale = 0.50f;
-        McFont *customFont = m_osu->getSubTitleFont();
+        McFont *customFont = osu->getSubTitleFont();
         g->pushTransform();
         g->pushTransform();
         {
         {
             const float height = rightSideThirdHeight;
             const float height = rightSideThirdHeight;
@@ -297,7 +295,7 @@ void ScoreButton::draw(Graphics *g) {
     if(m_style == STYLE::TOP_RANKS) {
     if(m_style == STYLE::TOP_RANKS) {
         // weighted percent
         // weighted percent
         const float weightScale = 0.65f;
         const float weightScale = 0.65f;
-        McFont *weightFont = m_osu->getSubTitleFont();
+        McFont *weightFont = osu->getSubTitleFont();
         g->pushTransform();
         g->pushTransform();
         {
         {
             const float height = rightSideThirdHeight;
             const float height = rightSideThirdHeight;
@@ -323,7 +321,7 @@ void ScoreButton::draw(Graphics *g) {
     // recent icon + elapsed time since score
     // recent icon + elapsed time since score
     const float upIconScale = 0.35f;
     const float upIconScale = 0.35f;
     const float timeElapsedScale = accScale;
     const float timeElapsedScale = accScale;
-    McFont *iconFont = m_osu->getFontIcons();
+    McFont *iconFont = osu->getFontIcons();
     McFont *timeFont = accFont;
     McFont *timeFont = accFont;
     if(m_iScoreUnixTimestamp > 0) {
     if(m_iScoreUnixTimestamp > 0) {
         const float iconScale = (m_vSize.y / iconFont->getHeight()) * upIconScale;
         const float iconScale = (m_vSize.y / iconFont->getHeight()) * upIconScale;
@@ -406,13 +404,13 @@ void ScoreButton::mouse_update(bool *propagate_clicks) {
     if(isMouseInside()) {
     if(isMouseInside()) {
         if(!isContextMenuVisible()) {
         if(!isContextMenuVisible()) {
             if(m_fIndexNumberAnim > 0.0f) {
             if(m_fIndexNumberAnim > 0.0f) {
-                m_osu->getTooltipOverlay()->begin();
+                osu->getTooltipOverlay()->begin();
                 {
                 {
                     for(int i = 0; i < m_tooltipLines.size(); i++) {
                     for(int i = 0; i < m_tooltipLines.size(); i++) {
-                        if(m_tooltipLines[i].length() > 0) m_osu->getTooltipOverlay()->addLine(m_tooltipLines[i]);
+                        if(m_tooltipLines[i].length() > 0) osu->getTooltipOverlay()->addLine(m_tooltipLines[i]);
                     }
                     }
                 }
                 }
-                m_osu->getTooltipOverlay()->end();
+                osu->getTooltipOverlay()->end();
             }
             }
         } else {
         } else {
             anim->deleteExistingAnimation(&m_fIndexNumberAnim);
             anim->deleteExistingAnimation(&m_fIndexNumberAnim);
@@ -481,7 +479,7 @@ void ScoreButton::updateElapsedTimeString() {
 }
 }
 
 
 void ScoreButton::onClicked() {
 void ScoreButton::onClicked() {
-    engine->getSound()->play(m_osu->getSkin()->getMenuHit());
+    engine->getSound()->play(osu->getSkin()->getMenuHit());
     CBaseUIButton::onClicked();
     CBaseUIButton::onClicked();
 }
 }
 
 
@@ -563,8 +561,8 @@ void ScoreButton::onContextMenu(UString text, int id) {
 }
 }
 
 
 void ScoreButton::onUseModsClicked() {
 void ScoreButton::onUseModsClicked() {
-    bool nomod = m_osu->useMods(&m_score);
-    engine->getSound()->play(nomod ? m_osu->getSkin()->getCheckOff() : m_osu->getSkin()->getCheckOn());
+    bool nomod = osu->useMods(&m_score);
+    engine->getSound()->play(nomod ? osu->getSkin()->getCheckOff() : osu->getSkin()->getCheckOn());
 }
 }
 
 
 void ScoreButton::onDeleteScoreClicked() {
 void ScoreButton::onDeleteScoreClicked() {
@@ -594,13 +592,13 @@ void ScoreButton::onDeleteScoreConfirmed(UString text, int id) {
 
 
     // absolutely disgusting
     // absolutely disgusting
     if(m_style == STYLE::SCORE_BROWSER)
     if(m_style == STYLE::SCORE_BROWSER)
-        m_osu->getSongBrowser()->onScoreContextMenu(this, 2);
+        osu->getSongBrowser()->onScoreContextMenu(this, 2);
     else if(m_style == STYLE::TOP_RANKS) {
     else if(m_style == STYLE::TOP_RANKS) {
         // in this case, deletion of the actual scores is handled in SongBrowser::onScoreContextMenu()
         // in this case, deletion of the actual scores is handled in SongBrowser::onScoreContextMenu()
         // this is nice because it updates the songbrowser scorebrowser too (so if the user closes the top ranks screen
         // this is nice because it updates the songbrowser scorebrowser too (so if the user closes the top ranks screen
         // everything is in sync, even for the currently selected beatmap)
         // everything is in sync, even for the currently selected beatmap)
-        m_osu->getSongBrowser()->onScoreContextMenu(this, 2);
-        m_osu->getUserStatsScreen()->onScoreContextMenu(this, 2);
+        osu->getSongBrowser()->onScoreContextMenu(this, 2);
+        osu->getUserStatsScreen()->onScoreContextMenu(this, 2);
     }
     }
 }
 }
 
 
@@ -769,7 +767,7 @@ void ScoreButton::setScore(const FinishedScore &score, const DatabaseBeatmap *di
 
 
 bool ScoreButton::isContextMenuVisible() { return (m_contextMenu != NULL && m_contextMenu->isVisible()); }
 bool ScoreButton::isContextMenuVisible() { return (m_contextMenu != NULL && m_contextMenu->isVisible()); }
 
 
-SkinImage *ScoreButton::getGradeImage(Osu *osu, FinishedScore::Grade grade) {
+SkinImage *ScoreButton::getGradeImage(FinishedScore::Grade grade) {
     switch(grade) {
     switch(grade) {
         case FinishedScore::Grade::XH:
         case FinishedScore::Grade::XH:
             return osu->getSkin()->getRankingXHsmall();
             return osu->getSkin()->getRankingXHsmall();

+ 2 - 4
src/App/Osu/SongBrowser/ScoreButton.h

@@ -3,7 +3,6 @@
 #include "Database.h"
 #include "Database.h"
 #include "score.h"
 #include "score.h"
 
 
-class Osu;
 class SkinImage;
 class SkinImage;
 
 
 class UIAvatar;
 class UIAvatar;
@@ -11,12 +10,12 @@ class UIContextMenu;
 
 
 class ScoreButton : public CBaseUIButton {
 class ScoreButton : public CBaseUIButton {
    public:
    public:
-    static SkinImage *getGradeImage(Osu *osu, FinishedScore::Grade grade);
+    static SkinImage *getGradeImage(FinishedScore::Grade grade);
     static UString getModsStringForDisplay(int mods);
     static UString getModsStringForDisplay(int mods);
 
 
     enum class STYLE { SCORE_BROWSER, TOP_RANKS };
     enum class STYLE { SCORE_BROWSER, TOP_RANKS };
 
 
-    ScoreButton(Osu *osu, UIContextMenu *contextMenu, float xPos, float yPos, float xSize, float ySize,
+    ScoreButton(UIContextMenu *contextMenu, float xPos, float yPos, float xSize, float ySize,
                 STYLE style = STYLE::SCORE_BROWSER);
                 STYLE style = STYLE::SCORE_BROWSER);
     virtual ~ScoreButton();
     virtual ~ScoreButton();
 
 
@@ -69,7 +68,6 @@ class ScoreButton : public CBaseUIButton {
 
 
     bool isContextMenuVisible();
     bool isContextMenuVisible();
 
 
-    Osu *m_osu;
     UIContextMenu *m_contextMenu;
     UIContextMenu *m_contextMenu;
     STYLE m_style;
     STYLE m_style;
     float m_fIndexNumberAnim;
     float m_fIndexNumberAnim;

+ 165 - 181
src/App/Osu/SongBrowser/SongBrowser.cpp

@@ -158,15 +158,14 @@ class SongBrowserBackgroundSearchMatcher : public Resource {
 
 
 class ScoresStillLoadingElement : public CBaseUILabel {
 class ScoresStillLoadingElement : public CBaseUILabel {
    public:
    public:
-    ScoresStillLoadingElement(Osu *osu, UString text) : CBaseUILabel(0, 0, 0, 0, "", text) {
-        m_osu = osu;
+    ScoresStillLoadingElement(UString text) : CBaseUILabel(0, 0, 0, 0, "", text) {
         m_sIconString.insert(0, Icons::GLOBE);
         m_sIconString.insert(0, Icons::GLOBE);
     }
     }
 
 
     virtual void drawText(Graphics *g) {
     virtual void drawText(Graphics *g) {
         // draw icon
         // draw icon
         const float iconScale = 0.6f;
         const float iconScale = 0.6f;
-        McFont *iconFont = m_osu->getFontIcons();
+        McFont *iconFont = osu->getFontIcons();
         int iconWidth = 0;
         int iconWidth = 0;
         g->pushTransform();
         g->pushTransform();
         {
         {
@@ -185,7 +184,7 @@ class ScoresStillLoadingElement : public CBaseUILabel {
 
 
         // draw text
         // draw text
         const float textScale = 0.4f;
         const float textScale = 0.4f;
-        McFont *textFont = m_osu->getSongBrowserFont();
+        McFont *textFont = osu->getSongBrowserFont();
         g->pushTransform();
         g->pushTransform();
         {
         {
             const float stringWidth = textFont->getStringWidth(m_sText);
             const float stringWidth = textFont->getStringWidth(m_sText);
@@ -202,21 +201,17 @@ class ScoresStillLoadingElement : public CBaseUILabel {
     }
     }
 
 
    private:
    private:
-    Osu *m_osu;
     UString m_sIconString;
     UString m_sIconString;
 };
 };
 
 
 class NoRecordsSetElement : public CBaseUILabel {
 class NoRecordsSetElement : public CBaseUILabel {
    public:
    public:
-    NoRecordsSetElement(Osu *osu, UString text) : CBaseUILabel(0, 0, 0, 0, "", text) {
-        m_osu = osu;
-        m_sIconString.insert(0, Icons::TROPHY);
-    }
+    NoRecordsSetElement(UString text) : CBaseUILabel(0, 0, 0, 0, "", text) { m_sIconString.insert(0, Icons::TROPHY); }
 
 
     virtual void drawText(Graphics *g) {
     virtual void drawText(Graphics *g) {
         // draw icon
         // draw icon
         const float iconScale = 0.6f;
         const float iconScale = 0.6f;
-        McFont *iconFont = m_osu->getFontIcons();
+        McFont *iconFont = osu->getFontIcons();
         int iconWidth = 0;
         int iconWidth = 0;
         g->pushTransform();
         g->pushTransform();
         {
         {
@@ -235,7 +230,7 @@ class NoRecordsSetElement : public CBaseUILabel {
 
 
         // draw text
         // draw text
         const float textScale = 0.6f;
         const float textScale = 0.6f;
-        McFont *textFont = m_osu->getSongBrowserFont();
+        McFont *textFont = osu->getSongBrowserFont();
         g->pushTransform();
         g->pushTransform();
         {
         {
             const float stringWidth = textFont->getStringWidth(m_sText);
             const float stringWidth = textFont->getStringWidth(m_sText);
@@ -252,7 +247,6 @@ class NoRecordsSetElement : public CBaseUILabel {
     }
     }
 
 
    private:
    private:
-    Osu *m_osu;
     UString m_sIconString;
     UString m_sIconString;
 };
 };
 
 
@@ -325,9 +319,7 @@ bool SongBrowser::SortByTitle::operator()(Button const *a, Button const *b) cons
     return res > 0;
     return res > 0;
 }
 }
 
 
-SongBrowser::SongBrowser(Osu *osu) : ScreenBackable(osu) {
-    m_osu = osu;
-
+SongBrowser::SongBrowser() : ScreenBackable() {
     // sorting/grouping + methods
     // sorting/grouping + methods
     m_group = GROUP::GROUP_NO_GROUPING;
     m_group = GROUP::GROUP_NO_GROUPING;
     {
     {
@@ -413,7 +405,7 @@ SongBrowser::SongBrowser(Osu *osu) : ScreenBackable(osu) {
     // build topbar left
     // build topbar left
     m_topbarLeft = new CBaseUIContainer(0, 0, 0, 0, "");
     m_topbarLeft = new CBaseUIContainer(0, 0, 0, 0, "");
     {
     {
-        m_songInfo = new InfoLabel(m_osu, 0, 0, 0, 0, "");
+        m_songInfo = new InfoLabel(0, 0, 0, 0, "");
 
 
         m_topbarLeft->addBaseUIElement(m_songInfo);
         m_topbarLeft->addBaseUIElement(m_songInfo);
     }
     }
@@ -466,26 +458,26 @@ SongBrowser::SongBrowser(Osu *osu) : ScreenBackable(osu) {
     m_sortButton->setClickCallback(fastdelegate::MakeDelegate(this, &SongBrowser::onSortClicked));
     m_sortButton->setClickCallback(fastdelegate::MakeDelegate(this, &SongBrowser::onSortClicked));
 
 
     // context menu
     // context menu
-    m_contextMenu = new UIContextMenu(m_osu, 50, 50, 150, 0, "");
+    m_contextMenu = new UIContextMenu(50, 50, 150, 0, "");
     m_contextMenu->setVisible(true);
     m_contextMenu->setVisible(true);
 
 
     // build bottombar
     // build bottombar
     m_bottombar = new CBaseUIContainer(0, 0, 0, 0, "");
     m_bottombar = new CBaseUIContainer(0, 0, 0, 0, "");
 
 
-    addBottombarNavButton([this]() -> SkinImage * { return m_osu->getSkin()->getSelectionMode(); },
-                          [this]() -> SkinImage * { return m_osu->getSkin()->getSelectionModeOver(); })
+    addBottombarNavButton([]() -> SkinImage * { return osu->getSkin()->getSelectionMode(); },
+                          []() -> SkinImage * { return osu->getSkin()->getSelectionModeOver(); })
         ->setClickCallback(fastdelegate::MakeDelegate(this, &SongBrowser::onSelectionMode));
         ->setClickCallback(fastdelegate::MakeDelegate(this, &SongBrowser::onSelectionMode));
-    addBottombarNavButton([this]() -> SkinImage * { return m_osu->getSkin()->getSelectionMods(); },
-                          [this]() -> SkinImage * { return m_osu->getSkin()->getSelectionModsOver(); })
+    addBottombarNavButton([]() -> SkinImage * { return osu->getSkin()->getSelectionMods(); },
+                          []() -> SkinImage * { return osu->getSkin()->getSelectionModsOver(); })
         ->setClickCallback(fastdelegate::MakeDelegate(this, &SongBrowser::onSelectionMods));
         ->setClickCallback(fastdelegate::MakeDelegate(this, &SongBrowser::onSelectionMods));
-    addBottombarNavButton([this]() -> SkinImage * { return m_osu->getSkin()->getSelectionRandom(); },
-                          [this]() -> SkinImage * { return m_osu->getSkin()->getSelectionRandomOver(); })
+    addBottombarNavButton([]() -> SkinImage * { return osu->getSkin()->getSelectionRandom(); },
+                          []() -> SkinImage * { return osu->getSkin()->getSelectionRandomOver(); })
         ->setClickCallback(fastdelegate::MakeDelegate(this, &SongBrowser::onSelectionRandom));
         ->setClickCallback(fastdelegate::MakeDelegate(this, &SongBrowser::onSelectionRandom));
-    addBottombarNavButton([this]() -> SkinImage * { return m_osu->getSkin()->getSelectionOptions(); },
-                          [this]() -> SkinImage * { return m_osu->getSkin()->getSelectionOptionsOver(); })
+    addBottombarNavButton([]() -> SkinImage * { return osu->getSkin()->getSelectionOptions(); },
+                          []() -> SkinImage * { return osu->getSkin()->getSelectionOptionsOver(); })
         ->setClickCallback(fastdelegate::MakeDelegate(this, &SongBrowser::onSelectionOptions));
         ->setClickCallback(fastdelegate::MakeDelegate(this, &SongBrowser::onSelectionOptions));
 
 
-    m_userButton = new UserButton(m_osu);
+    m_userButton = new UserButton();
     m_userButton->addTooltipLine("Click to change [User] or view/edit [Top Ranks]");
     m_userButton->addTooltipLine("Click to change [User] or view/edit [Top Ranks]");
     m_userButton->setClickCallback(fastdelegate::MakeDelegate(this, &SongBrowser::onUserButtonClicked));
     m_userButton->setClickCallback(fastdelegate::MakeDelegate(this, &SongBrowser::onUserButtonClicked));
     m_userButton->setText(m_name_ref->getString());
     m_userButton->setText(m_name_ref->getString());
@@ -501,8 +493,8 @@ SongBrowser::SongBrowser(Osu *osu) : ScreenBackable(osu) {
     m_scoreBrowser->setHorizontalScrolling(false);
     m_scoreBrowser->setHorizontalScrolling(false);
     m_scoreBrowser->setScrollbarSizeMultiplier(0.25f);
     m_scoreBrowser->setScrollbarSizeMultiplier(0.25f);
     m_scoreBrowser->setScrollResistance(15);
     m_scoreBrowser->setScrollResistance(15);
-    m_scoreBrowserScoresStillLoadingElement = new ScoresStillLoadingElement(m_osu, "Loading...");
-    m_scoreBrowserNoRecordsYetElement = new NoRecordsSetElement(m_osu, "No records set!");
+    m_scoreBrowserScoresStillLoadingElement = new ScoresStillLoadingElement("Loading...");
+    m_scoreBrowserNoRecordsYetElement = new NoRecordsSetElement("No records set!");
     m_scoreBrowser->getContainer()->addBaseUIElement(m_scoreBrowserNoRecordsYetElement);
     m_scoreBrowser->getContainer()->addBaseUIElement(m_scoreBrowserNoRecordsYetElement);
 
 
     m_localBestContainer = new CBaseUIContainer(0, 0, 0, 0, "");
     m_localBestContainer = new CBaseUIContainer(0, 0, 0, 0, "");
@@ -522,17 +514,17 @@ SongBrowser::SongBrowser(Osu *osu) : ScreenBackable(osu) {
     m_songBrowser->setScrollResistance(15);
     m_songBrowser->setScrollResistance(15);
 
 
     // beatmap database
     // beatmap database
-    m_db = new Database(m_osu);
+    m_db = new Database();
     m_bBeatmapRefreshScheduled = true;
     m_bBeatmapRefreshScheduled = true;
 
 
     // behaviour
     // behaviour
     m_bHasSelectedAndIsPlaying = false;
     m_bHasSelectedAndIsPlaying = false;
-    m_selectedBeatmap = new Beatmap(m_osu);
+    m_selectedBeatmap = new Beatmap();
     m_fPulseAnimation = 0.0f;
     m_fPulseAnimation = 0.0f;
     m_fBackgroundFadeInTime = 0.0f;
     m_fBackgroundFadeInTime = 0.0f;
 
 
     // search
     // search
-    m_search = new UISearchOverlay(m_osu, 0, 0, 0, 0, "");
+    m_search = new UISearchOverlay(0, 0, 0, 0, "");
     m_search->setOffsetRight(10);
     m_search->setOffsetRight(10);
     m_fSearchWaitTime = 0.0f;
     m_fSearchWaitTime = 0.0f;
     m_bInSearch = (osu_songbrowser_search_hardcoded_filter.getString().length() > 0);
     m_bInSearch = (osu_songbrowser_search_hardcoded_filter.getString().length() > 0);
@@ -605,6 +597,7 @@ SongBrowser::~SongBrowser() {
         delete m_sortingMethods[i].comparator;
         delete m_sortingMethods[i].comparator;
     }
     }
 
 
+    SAFE_DELETE(m_selectedBeatmap);
     SAFE_DELETE(m_search);
     SAFE_DELETE(m_search);
     SAFE_DELETE(m_topbarLeft);
     SAFE_DELETE(m_topbarLeft);
     SAFE_DELETE(m_topbarRight);
     SAFE_DELETE(m_topbarRight);
@@ -619,7 +612,7 @@ void SongBrowser::draw(Graphics *g) {
 
 
     // draw background
     // draw background
     g->setColor(0xff000000);
     g->setColor(0xff000000);
-    g->fillRect(0, 0, m_osu->getScreenWidth(), m_osu->getScreenHeight());
+    g->fillRect(0, 0, osu->getScreenWidth(), osu->getScreenHeight());
 
 
     // refreshing (blocks every other call in draw() below it!)
     // refreshing (blocks every other call in draw() below it!)
     if(m_bBeatmapRefreshScheduled) {
     if(m_bBeatmapRefreshScheduled) {
@@ -628,14 +621,13 @@ void SongBrowser::draw(Graphics *g) {
         g->setColor(0xffffffff);
         g->setColor(0xffffffff);
         g->pushTransform();
         g->pushTransform();
         {
         {
-            g->translate(
-                (int)(m_osu->getScreenWidth() / 2 - m_osu->getSubTitleFont()->getStringWidth(loadingMessage) / 2),
-                m_osu->getScreenHeight() - 15);
-            g->drawString(m_osu->getSubTitleFont(), loadingMessage);
+            g->translate((int)(osu->getScreenWidth() / 2 - osu->getSubTitleFont()->getStringWidth(loadingMessage) / 2),
+                         osu->getScreenHeight() - 15);
+            g->drawString(osu->getSubTitleFont(), loadingMessage);
         }
         }
         g->popTransform();
         g->popTransform();
 
 
-        m_osu->getHUD()->drawBeatmapImportSpinner(g);
+        osu->getHUD()->drawBeatmapImportSpinner(g);
         return;
         return;
     }
     }
 
 
@@ -644,11 +636,11 @@ void SongBrowser::draw(Graphics *g) {
         float alpha = 1.0f;
         float alpha = 1.0f;
         if(osu_songbrowser_background_fade_in_duration.getFloat() > 0.0f) {
         if(osu_songbrowser_background_fade_in_duration.getFloat() > 0.0f) {
             // handle fadein trigger after handler is finished loading
             // handle fadein trigger after handler is finished loading
-            const bool ready = m_osu->getSelectedBeatmap()->getSelectedDifficulty2() != NULL &&
-                               m_osu->getBackgroundImageHandler()->getLoadBackgroundImage(
-                                   m_osu->getSelectedBeatmap()->getSelectedDifficulty2()) != NULL &&
-                               m_osu->getBackgroundImageHandler()
-                                   ->getLoadBackgroundImage(m_osu->getSelectedBeatmap()->getSelectedDifficulty2())
+            const bool ready = osu->getSelectedBeatmap()->getSelectedDifficulty2() != NULL &&
+                               osu->getBackgroundImageHandler()->getLoadBackgroundImage(
+                                   osu->getSelectedBeatmap()->getSelectedDifficulty2()) != NULL &&
+                               osu->getBackgroundImageHandler()
+                                   ->getLoadBackgroundImage(osu->getSelectedBeatmap()->getSelectedDifficulty2())
                                    ->isReady();
                                    ->isReady();
 
 
             if(!ready)
             if(!ready)
@@ -661,19 +653,19 @@ void SongBrowser::draw(Graphics *g) {
             }
             }
         }
         }
 
 
-        drawSelectedBeatmapBackgroundImage(g, m_osu, alpha);
+        drawSelectedBeatmapBackgroundImage(g, alpha);
     } else if(osu_draw_songbrowser_menu_background_image.getBool()) {
     } else if(osu_draw_songbrowser_menu_background_image.getBool()) {
         // menu-background
         // menu-background
-        Image *backgroundImage = m_osu->getSkin()->getMenuBackground();
-        if(backgroundImage != NULL && backgroundImage != m_osu->getSkin()->getMissingTexture() &&
+        Image *backgroundImage = osu->getSkin()->getMenuBackground();
+        if(backgroundImage != NULL && backgroundImage != osu->getSkin()->getMissingTexture() &&
            backgroundImage->isReady()) {
            backgroundImage->isReady()) {
-            const float scale = Osu::getImageScaleToFillResolution(backgroundImage, m_osu->getScreenSize());
+            const float scale = Osu::getImageScaleToFillResolution(backgroundImage, osu->getScreenSize());
 
 
             g->setColor(0xffffffff);
             g->setColor(0xffffffff);
             g->pushTransform();
             g->pushTransform();
             {
             {
                 g->scale(scale, scale);
                 g->scale(scale, scale);
-                g->translate(m_osu->getScreenWidth() / 2, m_osu->getScreenHeight() / 2);
+                g->translate(osu->getScreenWidth() / 2, osu->getScreenHeight() / 2);
                 g->drawImage(backgroundImage);
                 g->drawImage(backgroundImage);
             }
             }
             g->popTransform();
             g->popTransform();
@@ -692,7 +684,7 @@ void SongBrowser::draw(Graphics *g) {
         /// const std::vector<double> &speedStrains = getSelectedBeatmap()->getSpeedStrains();
         /// const std::vector<double> &speedStrains = getSelectedBeatmap()->getSpeedStrains();
         const std::vector<double> &aimStrains = m_dynamicStarCalculator->getAimStrains();
         const std::vector<double> &aimStrains = m_dynamicStarCalculator->getAimStrains();
         const std::vector<double> &speedStrains = m_dynamicStarCalculator->getSpeedStrains();
         const std::vector<double> &speedStrains = m_dynamicStarCalculator->getSpeedStrains();
-        const float speedMultiplier = m_osu->getSpeedMultiplier();
+        const float speedMultiplier = osu->getSpeedMultiplier();
 
 
         // const unsigned long lengthFullMS = beatmapLength;
         // const unsigned long lengthFullMS = beatmapLength;
         // const unsigned long lengthMS = getSelectedBeatmap()->getLengthPlayable();
         // const unsigned long lengthMS = getSelectedBeatmap()->getLengthPlayable();
@@ -725,7 +717,7 @@ void SongBrowser::draw(Graphics *g) {
 
 
             // draw strain bar graph
             // draw strain bar graph
             if(highestAimStrain > 0.0 && highestSpeedStrain > 0.0 && highestStrain > 0.0) {
             if(highestAimStrain > 0.0 && highestSpeedStrain > 0.0 && highestStrain > 0.0) {
-                const float dpiScale = Osu::getUIScale(m_osu);
+                const float dpiScale = Osu::getUIScale();
 
 
                 const float graphWidth = m_scoreBrowser->getSize().x;
                 const float graphWidth = m_scoreBrowser->getSize().x;
 
 
@@ -825,9 +817,9 @@ void SongBrowser::draw(Graphics *g) {
     g->pushTransform();
     g->pushTransform();
     {
     {
         g->scale(m_fSongSelectTopScale, m_fSongSelectTopScale);
         g->scale(m_fSongSelectTopScale, m_fSongSelectTopScale);
-        g->translate((m_osu->getSkin()->getSongSelectTop()->getWidth() * m_fSongSelectTopScale) / 2,
-                     (m_osu->getSkin()->getSongSelectTop()->getHeight() * m_fSongSelectTopScale) / 2);
-        g->drawImage(m_osu->getSkin()->getSongSelectTop());
+        g->translate((osu->getSkin()->getSongSelectTop()->getWidth() * m_fSongSelectTopScale) / 2,
+                     (osu->getSkin()->getSongSelectTop()->getHeight() * m_fSongSelectTopScale) / 2);
+        g->drawImage(osu->getSkin()->getSongSelectTop());
     }
     }
     g->popTransform();
     g->popTransform();
 
 
@@ -837,26 +829,26 @@ void SongBrowser::draw(Graphics *g) {
     if(Osu::debug->getBool()) m_topbarRight->draw_debug(g);
     if(Osu::debug->getBool()) m_topbarRight->draw_debug(g);
 
 
     // draw bottom bar
     // draw bottom bar
-    float songSelectBottomScale = m_bottombar->getSize().y / m_osu->getSkin()->getSongSelectBottom()->getHeight();
+    float songSelectBottomScale = m_bottombar->getSize().y / osu->getSkin()->getSongSelectBottom()->getHeight();
     songSelectBottomScale *= 0.8f;
     songSelectBottomScale *= 0.8f;
 
 
     g->setColor(0xff000000);
     g->setColor(0xff000000);
-    g->fillRect(0, m_bottombar->getPos().y + 10, m_osu->getScreenWidth(), m_bottombar->getSize().y);
+    g->fillRect(0, m_bottombar->getPos().y + 10, osu->getScreenWidth(), m_bottombar->getSize().y);
 
 
     g->setColor(0xffffffff);
     g->setColor(0xffffffff);
     g->pushTransform();
     g->pushTransform();
     {
     {
         g->scale(songSelectBottomScale, songSelectBottomScale);
         g->scale(songSelectBottomScale, songSelectBottomScale);
         g->translate(0, (int)(m_bottombar->getPos().y) +
         g->translate(0, (int)(m_bottombar->getPos().y) +
-                            (int)((m_osu->getSkin()->getSongSelectBottom()->getHeight() * songSelectBottomScale) / 2) -
+                            (int)((osu->getSkin()->getSongSelectBottom()->getHeight() * songSelectBottomScale) / 2) -
                             1);
                             1);
-        m_osu->getSkin()->getSongSelectBottom()->bind();
+        osu->getSkin()->getSongSelectBottom()->bind();
         {
         {
             g->drawQuad(0, -(int)(m_bottombar->getSize().y * (1.0f / songSelectBottomScale) / 2),
             g->drawQuad(0, -(int)(m_bottombar->getSize().y * (1.0f / songSelectBottomScale) / 2),
-                        (int)(m_osu->getScreenWidth() * (1.0f / songSelectBottomScale)),
+                        (int)(osu->getScreenWidth() * (1.0f / songSelectBottomScale)),
                         (int)(m_bottombar->getSize().y * (1.0f / songSelectBottomScale)));
                         (int)(m_bottombar->getSize().y * (1.0f / songSelectBottomScale)));
         }
         }
-        m_osu->getSkin()->getSongSelectBottom()->unbind();
+        osu->getSkin()->getSongSelectBottom()->unbind();
     }
     }
     g->popTransform();
     g->popTransform();
 
 
@@ -890,20 +882,18 @@ void SongBrowser::draw(Graphics *g) {
         g->setColor(0xffff0000);
         g->setColor(0xffff0000);
         g->pushTransform();
         g->pushTransform();
         {
         {
-            g->translate(
-                (int)(m_osu->getScreenWidth() / 2 - m_osu->getSubTitleFont()->getStringWidth(errorMessage1) / 2),
-                (int)(m_osu->getScreenHeight() / 2 + m_osu->getSubTitleFont()->getHeight()));
-            g->drawString(m_osu->getSubTitleFont(), errorMessage1);
+            g->translate((int)(osu->getScreenWidth() / 2 - osu->getSubTitleFont()->getStringWidth(errorMessage1) / 2),
+                         (int)(osu->getScreenHeight() / 2 + osu->getSubTitleFont()->getHeight()));
+            g->drawString(osu->getSubTitleFont(), errorMessage1);
         }
         }
         g->popTransform();
         g->popTransform();
 
 
         g->setColor(0xff00ff00);
         g->setColor(0xff00ff00);
         g->pushTransform();
         g->pushTransform();
         {
         {
-            g->translate(
-                (int)(m_osu->getScreenWidth() / 2 - m_osu->getSubTitleFont()->getStringWidth(errorMessage2) / 2),
-                (int)(m_osu->getScreenHeight() / 2 + m_osu->getSubTitleFont()->getHeight() * 2 + 15));
-            g->drawString(m_osu->getSubTitleFont(), errorMessage2);
+            g->translate((int)(osu->getScreenWidth() / 2 - osu->getSubTitleFont()->getStringWidth(errorMessage2) / 2),
+                         (int)(osu->getScreenHeight() / 2 + osu->getSubTitleFont()->getHeight() * 2 + 15));
+            g->drawString(osu->getSubTitleFont(), errorMessage2);
         }
         }
         g->popTransform();
         g->popTransform();
     }
     }
@@ -916,12 +906,12 @@ void SongBrowser::draw(Graphics *g) {
         Color topColor = 0x00ffffff;
         Color topColor = 0x00ffffff;
         Color bottomColor = COLOR((int)(25 * m_fPulseAnimation), 255, 255, 255);
         Color bottomColor = COLOR((int)(25 * m_fPulseAnimation), 255, 255, 255);
 
 
-        g->fillGradient(0, 0, m_osu->getScreenWidth(), m_osu->getScreenHeight(), topColor, topColor, bottomColor,
+        g->fillGradient(0, 0, osu->getScreenWidth(), osu->getScreenHeight(), topColor, topColor, bottomColor,
                         bottomColor);
                         bottomColor);
     }
     }
 }
 }
 
 
-void SongBrowser::drawSelectedBeatmapBackgroundImage(Graphics *g, Osu *osu, float alpha) {
+void SongBrowser::drawSelectedBeatmapBackgroundImage(Graphics *g, float alpha) {
     if(osu->getSelectedBeatmap()->getSelectedDifficulty2() != NULL) {
     if(osu->getSelectedBeatmap()->getSelectedDifficulty2() != NULL) {
         Image *backgroundImage = osu->getBackgroundImageHandler()->getLoadBackgroundImage(
         Image *backgroundImage = osu->getBackgroundImageHandler()->getLoadBackgroundImage(
             osu->getSelectedBeatmap()->getSelectedDifficulty2());
             osu->getSelectedBeatmap()->getSelectedDifficulty2());
@@ -994,7 +984,7 @@ void SongBrowser::mouse_update(bool *propagate_clicks) {
                     }
                     }
                 }
                 }
 
 
-                if(m_songBrowser->isMouseInside() && !m_osu->getOptionsMenu()->isMouseInside() &&
+                if(m_songBrowser->isMouseInside() && !osu->getOptionsMenu()->isMouseInside() &&
                    !isMouseInsideAnySongButton)
                    !isMouseInsideAnySongButton)
                     m_bSongBrowserRightClickScrolling = true;
                     m_bSongBrowserRightClickScrolling = true;
                 else
                 else
@@ -1024,7 +1014,7 @@ void SongBrowser::mouse_update(bool *propagate_clicks) {
     // if cursor is to the left edge of the screen, force center currently selected beatmap/diff
     // if cursor is to the left edge of the screen, force center currently selected beatmap/diff
     // but only if the context menu is currently not visible (since we don't want move things while e.g. managing
     // but only if the context menu is currently not visible (since we don't want move things while e.g. managing
     // collections etc.)
     // collections etc.)
-    if(engine->getMouse()->getPos().x < m_osu->getScreenWidth() * 0.1f && !m_contextMenu->isVisible())
+    if(engine->getMouse()->getPos().x < osu->getScreenWidth() * 0.1f && !m_contextMenu->isVisible())
         scrollToSelectedSongButton();
         scrollToSelectedSongButton();
 
 
     // handle searching
     // handle searching
@@ -1204,7 +1194,7 @@ void SongBrowser::onKeyDown(KeyboardEvent &key) {
         }
         }
     } else if(!m_contextMenu->isVisible()) {
     } else if(!m_contextMenu->isVisible()) {
         if(key == KEY_ESCAPE)  // can't support GAME_PAUSE hotkey here because of text searching
         if(key == KEY_ESCAPE)  // can't support GAME_PAUSE hotkey here because of text searching
-            m_osu->toggleSongBrowser();
+            osu->toggleSongBrowser();
     }
     }
 
 
     // paste clipboard support
     // paste clipboard support
@@ -1403,7 +1393,7 @@ void SongBrowser::onKeyDown(KeyboardEvent &key) {
     if(key == KEY_ENTER && !engine->getKeyboard()->isShiftDown()) playSelectedDifficulty();
     if(key == KEY_ENTER && !engine->getKeyboard()->isShiftDown()) playSelectedDifficulty();
 
 
     // toggle auto
     // toggle auto
-    if(key == KEY_A && engine->getKeyboard()->isControlDown()) m_osu->getModSelector()->toggleAuto();
+    if(key == KEY_A && engine->getKeyboard()->isControlDown()) osu->getModSelector()->toggleAuto();
 
 
     key.consume();
     key.consume();
 }
 }
@@ -1448,7 +1438,7 @@ CBaseUIContainer *SongBrowser::setVisible(bool visible) {
     m_bShiftPressed = false;  // seems to get stuck sometimes otherwise
     m_bShiftPressed = false;  // seems to get stuck sometimes otherwise
 
 
     if(m_bVisible) {
     if(m_bVisible) {
-        RichPresence::onSongBrowser(m_osu);
+        RichPresence::onSongBrowser();
 
 
         updateLayout();
         updateLayout();
 
 
@@ -1483,7 +1473,7 @@ CBaseUIContainer *SongBrowser::setVisible(bool visible) {
         m_contextMenu->setVisible2(false);
         m_contextMenu->setVisible2(false);
     }
     }
 
 
-    m_osu->m_chat->updateVisibility();
+    osu->m_chat->updateVisibility();
     return this;
     return this;
 }
 }
 
 
@@ -1620,18 +1610,16 @@ void SongBrowser::onDifficultySelected(DatabaseBeatmap *diff2, bool play) {
             bancho.room.pack(&packet);
             bancho.room.pack(&packet);
             send_packet(packet);
             send_packet(packet);
 
 
-            m_osu->m_room->on_map_change(false);
+            osu->m_room->on_map_change(false);
 
 
             setVisible(false);
             setVisible(false);
         } else {
         } else {
             // CTRL + click = auto
             // CTRL + click = auto
-            if(engine->getKeyboard()->isControlDown()) m_osu->getModSelector()->enableAuto();
+            if(engine->getKeyboard()->isControlDown()) osu->getModSelector()->enableAuto();
 
 
             if(m_selectedBeatmap->play()) {
             if(m_selectedBeatmap->play()) {
                 m_bHasSelectedAndIsPlaying = true;
                 m_bHasSelectedAndIsPlaying = true;
                 setVisible(false);
                 setVisible(false);
-
-                m_osu->onPlayStart();
             }
             }
         }
         }
     }
     }
@@ -1668,7 +1656,7 @@ void SongBrowser::refreshBeatmaps() {
     m_selectedBeatmap->pausePreviewMusic();
     m_selectedBeatmap->pausePreviewMusic();
     m_selectedBeatmap->deselect();
     m_selectedBeatmap->deselect();
     SAFE_DELETE(m_selectedBeatmap);
     SAFE_DELETE(m_selectedBeatmap);
-    m_selectedBeatmap = new Beatmap(m_osu);
+    m_selectedBeatmap = new Beatmap();
 
 
     m_selectionPreviousSongButton = NULL;
     m_selectionPreviousSongButton = NULL;
     m_selectionPreviousSongDiffButton = NULL;
     m_selectionPreviousSongDiffButton = NULL;
@@ -1741,12 +1729,11 @@ void SongBrowser::addBeatmap(DatabaseBeatmap *beatmap) {
 
 
     SongButton *songButton;
     SongButton *songButton;
     if(beatmap->getDifficulties().size() > 1) {
     if(beatmap->getDifficulties().size() > 1) {
-        songButton = new SongButton(m_osu, this, m_songBrowser, m_contextMenu, 250, 250 + m_beatmaps.size() * 50, 200,
-                                    50, "", beatmap);
-    } else {
         songButton =
         songButton =
-            new SongDifficultyButton(m_osu, this, m_songBrowser, m_contextMenu, 250, 250 + m_beatmaps.size() * 50, 200,
-                                     50, "", beatmap->getDifficulties()[0], NULL);
+            new SongButton(this, m_songBrowser, m_contextMenu, 250, 250 + m_beatmaps.size() * 50, 200, 50, "", beatmap);
+    } else {
+        songButton = new SongDifficultyButton(this, m_songBrowser, m_contextMenu, 250, 250 + m_beatmaps.size() * 50,
+                                              200, 50, "", beatmap->getDifficulties()[0], NULL);
     }
     }
 
 
     m_songButtons.push_back(songButton);
     m_songButtons.push_back(songButton);
@@ -2238,21 +2225,21 @@ bool SongBrowser::searchMatcher(const DatabaseBeatmap *databaseBeatmap,
                                             (diff->getLengthMS() > 0 ? ((float)diff->getNumObjects() /
                                             (diff->getLengthMS() > 0 ? ((float)diff->getNumObjects() /
                                                                         (float)(diff->getLengthMS() / 1000.0f / 60.0f))
                                                                         (float)(diff->getLengthMS() / 1000.0f / 60.0f))
                                                                      : 0.0f) *
                                                                      : 0.0f) *
-                                            databaseBeatmap->getOsu()->getSpeedMultiplier();
+                                            osu->getSpeedMultiplier();
                                         break;
                                         break;
                                     case CPM:
                                     case CPM:
                                         compareValue =
                                         compareValue =
                                             (diff->getLengthMS() > 0 ? ((float)diff->getNumCircles() /
                                             (diff->getLengthMS() > 0 ? ((float)diff->getNumCircles() /
                                                                         (float)(diff->getLengthMS() / 1000.0f / 60.0f))
                                                                         (float)(diff->getLengthMS() / 1000.0f / 60.0f))
                                                                      : 0.0f) *
                                                                      : 0.0f) *
-                                            databaseBeatmap->getOsu()->getSpeedMultiplier();
+                                            osu->getSpeedMultiplier();
                                         break;
                                         break;
                                     case SPM:
                                     case SPM:
                                         compareValue =
                                         compareValue =
                                             (diff->getLengthMS() > 0 ? ((float)diff->getNumSliders() /
                                             (diff->getLengthMS() > 0 ? ((float)diff->getNumSliders() /
                                                                         (float)(diff->getLengthMS() / 1000.0f / 60.0f))
                                                                         (float)(diff->getLengthMS() / 1000.0f / 60.0f))
                                                                      : 0.0f) *
                                                                      : 0.0f) *
-                                            databaseBeatmap->getOsu()->getSpeedMultiplier();
+                                            osu->getSpeedMultiplier();
                                         break;
                                         break;
                                     case OBJECTS:
                                     case OBJECTS:
                                         compareValue = diff->getNumObjects();
                                         compareValue = diff->getNumObjects();
@@ -2426,28 +2413,27 @@ void SongBrowser::updateLayout() {
     ScreenBackable::updateLayout();
     ScreenBackable::updateLayout();
 
 
     const float uiScale = Osu::ui_scale->getFloat();
     const float uiScale = Osu::ui_scale->getFloat();
-    const float dpiScale = Osu::getUIScale(m_osu);
+    const float dpiScale = Osu::getUIScale();
 
 
     const int margin = 5 * dpiScale;
     const int margin = 5 * dpiScale;
 
 
     // top bar
     // top bar
-    m_fSongSelectTopScale =
-        Osu::getImageScaleToFitResolution(m_osu->getSkin()->getSongSelectTop(), m_osu->getScreenSize());
+    m_fSongSelectTopScale = Osu::getImageScaleToFitResolution(osu->getSkin()->getSongSelectTop(), osu->getScreenSize());
     const float songSelectTopHeightScaled =
     const float songSelectTopHeightScaled =
-        std::max(m_osu->getSkin()->getSongSelectTop()->getHeight() * m_fSongSelectTopScale,
+        std::max(osu->getSkin()->getSongSelectTop()->getHeight() * m_fSongSelectTopScale,
                  m_songInfo->getMinimumHeight() * 1.5f + margin);  // NOTE: the height is a heuristic here more or less
                  m_songInfo->getMinimumHeight() * 1.5f + margin);  // NOTE: the height is a heuristic here more or less
     m_fSongSelectTopScale =
     m_fSongSelectTopScale =
-        std::max(m_fSongSelectTopScale, songSelectTopHeightScaled / m_osu->getSkin()->getSongSelectTop()->getHeight());
+        std::max(m_fSongSelectTopScale, songSelectTopHeightScaled / osu->getSkin()->getSongSelectTop()->getHeight());
     m_fSongSelectTopScale *=
     m_fSongSelectTopScale *=
         uiScale;  // NOTE: any user osu_ui_scale below 1.0 will break things (because songSelectTop image)
         uiScale;  // NOTE: any user osu_ui_scale below 1.0 will break things (because songSelectTop image)
 
 
     // topbar left (NOTE: the right side of the std::max() width is commented to keep the scorebrowser width consistent,
     // topbar left (NOTE: the right side of the std::max() width is commented to keep the scorebrowser width consistent,
     // and because it's not really needed anyway)
     // and because it's not really needed anyway)
-    m_topbarLeft->setSize(std::max(m_osu->getSkin()->getSongSelectTop()->getWidth() * m_fSongSelectTopScale *
+    m_topbarLeft->setSize(std::max(osu->getSkin()->getSongSelectTop()->getWidth() * m_fSongSelectTopScale *
                                            osu_songbrowser_topbar_left_width_percent.getFloat() +
                                            osu_songbrowser_topbar_left_width_percent.getFloat() +
                                        margin,
                                        margin,
                                    /*m_songInfo->getMinimumWidth() + margin*/ 0.0f),
                                    /*m_songInfo->getMinimumWidth() + margin*/ 0.0f),
-                          std::max(m_osu->getSkin()->getSongSelectTop()->getHeight() * m_fSongSelectTopScale *
+                          std::max(osu->getSkin()->getSongSelectTop()->getHeight() * m_fSongSelectTopScale *
                                        osu_songbrowser_topbar_left_percent.getFloat(),
                                        osu_songbrowser_topbar_left_percent.getFloat(),
                                    m_songInfo->getMinimumHeight() + margin));
                                    m_songInfo->getMinimumHeight() + margin));
     m_songInfo->setRelPos(margin, margin);
     m_songInfo->setRelPos(margin, margin);
@@ -2479,10 +2465,10 @@ void SongBrowser::updateLayout() {
     m_topbarLeft->update_pos();
     m_topbarLeft->update_pos();
 
 
     // topbar right
     // topbar right
-    m_topbarRight->setPosX(m_osu->getSkin()->getSongSelectTop()->getWidth() * m_fSongSelectTopScale *
+    m_topbarRight->setPosX(osu->getSkin()->getSongSelectTop()->getWidth() * m_fSongSelectTopScale *
                            osu_songbrowser_topbar_right_percent.getFloat());
                            osu_songbrowser_topbar_right_percent.getFloat());
-    m_topbarRight->setSize(m_osu->getScreenWidth() - m_topbarRight->getPos().x,
-                           m_osu->getSkin()->getSongSelectTop()->getHeight() * m_fSongSelectTopScale *
+    m_topbarRight->setSize(osu->getScreenWidth() - m_topbarRight->getPos().x,
+                           osu->getSkin()->getSongSelectTop()->getHeight() * m_fSongSelectTopScale *
                                osu_songbrowser_topbar_right_height_percent.getFloat());
                                osu_songbrowser_topbar_right_height_percent.getFloat());
 
 
     const int topbarRightTabButtonMargin = 10 * dpiScale;
     const int topbarRightTabButtonMargin = 10 * dpiScale;
@@ -2549,28 +2535,28 @@ void SongBrowser::updateLayout() {
     m_topbarRight->update_pos();
     m_topbarRight->update_pos();
 
 
     // bottombar
     // bottombar
-    const int bottomBarHeight = m_osu->getScreenHeight() * osu_songbrowser_bottombar_percent.getFloat() * uiScale;
+    const int bottomBarHeight = osu->getScreenHeight() * osu_songbrowser_bottombar_percent.getFloat() * uiScale;
 
 
-    m_bottombar->setPosY(m_osu->getScreenHeight() - bottomBarHeight);
-    m_bottombar->setSize(m_osu->getScreenWidth(), bottomBarHeight);
+    m_bottombar->setPosY(osu->getScreenHeight() - bottomBarHeight);
+    m_bottombar->setSize(osu->getScreenWidth(), bottomBarHeight);
 
 
     // nav bar
     // nav bar
     const bool isWidescreen =
     const bool isWidescreen =
-        ((int)(std::max(0, (int)((m_osu->getScreenWidth() - (m_osu->getScreenHeight() * 4.0f / 3.0f)) / 2.0f))) > 0);
-    const float navBarXCounter = Osu::getUIScale(m_osu, (isWidescreen ? 140.0f : 120.0f));
+        ((int)(std::max(0, (int)((osu->getScreenWidth() - (osu->getScreenHeight() * 4.0f / 3.0f)) / 2.0f))) > 0);
+    const float navBarXCounter = Osu::getUIScale((isWidescreen ? 140.0f : 120.0f));
 
 
     // bottombar cont
     // bottombar cont
     for(int i = 0; i < m_bottombarNavButtons.size(); i++) {
     for(int i = 0; i < m_bottombarNavButtons.size(); i++) {
-        m_bottombarNavButtons[i]->setSize(m_osu->getScreenWidth(), bottomBarHeight);
+        m_bottombarNavButtons[i]->setSize(osu->getScreenWidth(), bottomBarHeight);
     }
     }
     for(int i = 0; i < m_bottombarNavButtons.size(); i++) {
     for(int i = 0; i < m_bottombarNavButtons.size(); i++) {
-        const int gap = (i == 1 ? Osu::getUIScale(m_osu, 3.0f) : 0) + (i == 2 ? Osu::getUIScale(m_osu, 2.0f) : 0);
+        const int gap = (i == 1 ? Osu::getUIScale(3.0f) : 0) + (i == 2 ? Osu::getUIScale(2.0f) : 0);
 
 
         // new, hardcoded offsets instead of dynamically using the button skin image widths (except starting at 3rd
         // new, hardcoded offsets instead of dynamically using the button skin image widths (except starting at 3rd
         // button)
         // button)
         m_bottombarNavButtons[i]->setRelPosX(
         m_bottombarNavButtons[i]->setRelPosX(
-            navBarXCounter + gap + (i > 0 ? Osu::getUIScale(m_osu, 57.6f) : 0) +
-            (i > 1 ? std::max((i - 1) * Osu::getUIScale(m_osu, 48.0f), m_bottombarNavButtons[i - 1]->getSize().x) : 0));
+            navBarXCounter + gap + (i > 0 ? Osu::getUIScale(57.6f) : 0) +
+            (i > 1 ? std::max((i - 1) * Osu::getUIScale(48.0f), m_bottombarNavButtons[i - 1]->getSize().x) : 0));
 
 
         // old, overflows with some skins (e.g. kyu)
         // old, overflows with some skins (e.g. kyu)
         // m_bottombarNavButtons[i]->setRelPosX((i == 0 ? navBarXCounter : 0) + gap + (i > 0 ?
         // m_bottombarNavButtons[i]->setRelPosX((i == 0 ? navBarXCounter : 0) + gap + (i > 0 ?
@@ -2602,9 +2588,9 @@ void SongBrowser::updateLayout() {
     // song browser
     // song browser
     m_songBrowser->setPos(m_topbarLeft->getPos().x + m_topbarLeft->getSize().x + 1 + scoreBrowserExtraPaddingRight,
     m_songBrowser->setPos(m_topbarLeft->getPos().x + m_topbarLeft->getSize().x + 1 + scoreBrowserExtraPaddingRight,
                           m_topbarRight->getPos().y + m_topbarRight->getSize().y + 2);
                           m_topbarRight->getPos().y + m_topbarRight->getSize().y + 2);
-    m_songBrowser->setSize(m_osu->getScreenWidth() -
-                               (m_topbarLeft->getPos().x + m_topbarLeft->getSize().x + scoreBrowserExtraPaddingRight),
-                           m_osu->getScreenHeight() - m_songBrowser->getPos().y - m_bottombar->getSize().y + 2);
+    m_songBrowser->setSize(
+        osu->getScreenWidth() - (m_topbarLeft->getPos().x + m_topbarLeft->getSize().x + scoreBrowserExtraPaddingRight),
+        osu->getScreenHeight() - m_songBrowser->getPos().y - m_bottombar->getSize().y + 2);
     updateSongButtonLayout();
     updateSongButtonLayout();
 
 
     m_search->setPos(m_songBrowser->getPos());
     m_search->setPos(m_songBrowser->getPos());
@@ -2612,12 +2598,12 @@ void SongBrowser::updateLayout() {
 }
 }
 
 
 void SongBrowser::onBack() {
 void SongBrowser::onBack() {
-    engine->getSound()->play(m_osu->getSkin()->getMenuClick());
-    m_osu->toggleSongBrowser();
+    engine->getSound()->play(osu->getSkin()->getMenuClick());
+    osu->toggleSongBrowser();
 }
 }
 
 
 void SongBrowser::updateScoreBrowserLayout() {
 void SongBrowser::updateScoreBrowserLayout() {
-    const float dpiScale = Osu::getUIScale(m_osu);
+    const float dpiScale = Osu::getUIScale();
 
 
     const bool shouldScoreBrowserBeVisible =
     const bool shouldScoreBrowserBeVisible =
         (m_osu_scores_enabled->getBool() && osu_songbrowser_scorebrowser_enabled.getBool());
         (m_osu_scores_enabled->getBool() && osu_songbrowser_scorebrowser_enabled.getBool());
@@ -2633,10 +2619,10 @@ void SongBrowser::updateScoreBrowserLayout() {
     m_scoreBrowser->setSize(scoreButtonWidthMax + scoreBrowserExtraPaddingRight, browserHeight);
     m_scoreBrowser->setSize(scoreButtonWidthMax + scoreBrowserExtraPaddingRight, browserHeight);
     int scoreHeight = 100;
     int scoreHeight = 100;
     {
     {
-        Image *menuButtonBackground = m_osu->getSkin()->getMenuButtonBackground();
-        Vector2 minimumSize = Vector2(699.0f, 103.0f) * (m_osu->getSkin()->isMenuButtonBackground2x() ? 2.0f : 1.0f);
+        Image *menuButtonBackground = osu->getSkin()->getMenuButtonBackground();
+        Vector2 minimumSize = Vector2(699.0f, 103.0f) * (osu->getSkin()->isMenuButtonBackground2x() ? 2.0f : 1.0f);
         float minimumScale = Osu::getImageScaleToFitResolution(menuButtonBackground, minimumSize);
         float minimumScale = Osu::getImageScaleToFitResolution(menuButtonBackground, minimumSize);
-        float scoreScale = Osu::getImageScale(m_osu, menuButtonBackground->getSize() * minimumScale, 64.0f);
+        float scoreScale = Osu::getImageScale(menuButtonBackground->getSize() * minimumScale, 64.0f);
         scoreScale *= 0.5f;
         scoreScale *= 0.5f;
         scoreHeight = (int)(menuButtonBackground->getHeight() * scoreScale);
         scoreHeight = (int)(menuButtonBackground->getHeight() * scoreScale);
 
 
@@ -2726,7 +2712,7 @@ void SongBrowser::rebuildScoreButtons() {
                     }
                     }
                 } else {
                 } else {
                     SAFE_DELETE(m_localBestButton);
                     SAFE_DELETE(m_localBestButton);
-                    m_localBestButton = new ScoreButton(m_osu, m_contextMenu, 0, 0, 0, 0);
+                    m_localBestButton = new ScoreButton(m_contextMenu, 0, 0, 0, 0);
                     m_localBestButton->setClickCallback(fastdelegate::MakeDelegate(this, &SongBrowser::onScoreClicked));
                     m_localBestButton->setClickCallback(fastdelegate::MakeDelegate(this, &SongBrowser::onScoreClicked));
                     m_localBestButton->map_hash = m_selectedBeatmap->getSelectedDifficulty2()->getMD5Hash();
                     m_localBestButton->map_hash = m_selectedBeatmap->getSelectedDifficulty2()->getMD5Hash();
                     m_localBestButton->setScore(*local_best, m_selectedBeatmap->getSelectedDifficulty2());
                     m_localBestButton->setScore(*local_best, m_selectedBeatmap->getSelectedDifficulty2());
@@ -2747,7 +2733,7 @@ void SongBrowser::rebuildScoreButtons() {
                 // Display local best while scores are loading
                 // Display local best while scores are loading
                 if(local_best != local_scores.end()) {
                 if(local_best != local_scores.end()) {
                     SAFE_DELETE(m_localBestButton);
                     SAFE_DELETE(m_localBestButton);
-                    m_localBestButton = new ScoreButton(m_osu, m_contextMenu, 0, 0, 0, 0);
+                    m_localBestButton = new ScoreButton(m_contextMenu, 0, 0, 0, 0);
                     m_localBestButton->setClickCallback(fastdelegate::MakeDelegate(this, &SongBrowser::onScoreClicked));
                     m_localBestButton->setClickCallback(fastdelegate::MakeDelegate(this, &SongBrowser::onScoreClicked));
                     m_localBestButton->map_hash = m_selectedBeatmap->getSelectedDifficulty2()->getMD5Hash();
                     m_localBestButton->map_hash = m_selectedBeatmap->getSelectedDifficulty2()->getMD5Hash();
                     m_localBestButton->setScore(*local_best, m_selectedBeatmap->getSelectedDifficulty2());
                     m_localBestButton->setScore(*local_best, m_selectedBeatmap->getSelectedDifficulty2());
@@ -2768,7 +2754,7 @@ void SongBrowser::rebuildScoreButtons() {
     if(numScores > m_scoreButtonCache.size()) {
     if(numScores > m_scoreButtonCache.size()) {
         const int numNewButtons = numScores - m_scoreButtonCache.size();
         const int numNewButtons = numScores - m_scoreButtonCache.size();
         for(size_t i = 0; i < numNewButtons; i++) {
         for(size_t i = 0; i < numNewButtons; i++) {
-            ScoreButton *scoreButton = new ScoreButton(m_osu, m_contextMenu, 0, 0, 0, 0);
+            ScoreButton *scoreButton = new ScoreButton(m_contextMenu, 0, 0, 0, 0);
             scoreButton->setClickCallback(fastdelegate::MakeDelegate(this, &SongBrowser::onScoreClicked));
             scoreButton->setClickCallback(fastdelegate::MakeDelegate(this, &SongBrowser::onScoreClicked));
             m_scoreButtonCache.push_back(scoreButton);
             m_scoreButtonCache.push_back(scoreButton);
         }
         }
@@ -2943,8 +2929,8 @@ void SongBrowser::onDatabaseLoadingFinished() {
         {
         {
             // 0-9
             // 0-9
             {
             {
-                CollectionButton *b = new CollectionButton(m_osu, this, m_songBrowser, m_contextMenu, 250, 250, 200, 50,
-                                                           "", "0-9", std::vector<Button *>());
+                CollectionButton *b = new CollectionButton(this, m_songBrowser, m_contextMenu, 250, 250, 200, 50, "",
+                                                           "0-9", std::vector<Button *>());
                 m_artistCollectionButtons.push_back(b);
                 m_artistCollectionButtons.push_back(b);
             }
             }
 
 
@@ -2952,15 +2938,15 @@ void SongBrowser::onDatabaseLoadingFinished() {
             for(size_t i = 0; i < 26; i++) {
             for(size_t i = 0; i < 26; i++) {
                 UString artistCollectionName = UString::format("%c", 'A' + i);
                 UString artistCollectionName = UString::format("%c", 'A' + i);
 
 
-                CollectionButton *b = new CollectionButton(m_osu, this, m_songBrowser, m_contextMenu, 250, 250, 200, 50,
-                                                           "", artistCollectionName, std::vector<Button *>());
+                CollectionButton *b = new CollectionButton(this, m_songBrowser, m_contextMenu, 250, 250, 200, 50, "",
+                                                           artistCollectionName, std::vector<Button *>());
                 m_artistCollectionButtons.push_back(b);
                 m_artistCollectionButtons.push_back(b);
             }
             }
 
 
             // Other
             // Other
             {
             {
-                CollectionButton *b = new CollectionButton(m_osu, this, m_songBrowser, m_contextMenu, 250, 250, 200, 50,
-                                                           "", "Other", std::vector<Button *>());
+                CollectionButton *b = new CollectionButton(this, m_songBrowser, m_contextMenu, 250, 250, 200, 50, "",
+                                                           "Other", std::vector<Button *>());
                 m_artistCollectionButtons.push_back(b);
                 m_artistCollectionButtons.push_back(b);
             }
             }
         }
         }
@@ -2973,29 +2959,29 @@ void SongBrowser::onDatabaseLoadingFinished() {
 
 
             std::vector<Button *> children;
             std::vector<Button *> children;
 
 
-            CollectionButton *b = new CollectionButton(m_osu, this, m_songBrowser, m_contextMenu, 250, 250, 200, 50, "",
+            CollectionButton *b = new CollectionButton(this, m_songBrowser, m_contextMenu, 250, 250, 200, 50, "",
                                                        difficultyCollectionName, children);
                                                        difficultyCollectionName, children);
             m_difficultyCollectionButtons.push_back(b);
             m_difficultyCollectionButtons.push_back(b);
         }
         }
 
 
         // bpm
         // bpm
         {
         {
-            CollectionButton *b = new CollectionButton(m_osu, this, m_songBrowser, m_contextMenu, 250, 250, 200, 50, "",
+            CollectionButton *b = new CollectionButton(this, m_songBrowser, m_contextMenu, 250, 250, 200, 50, "",
                                                        "Under 60 BPM", std::vector<Button *>());
                                                        "Under 60 BPM", std::vector<Button *>());
             m_bpmCollectionButtons.push_back(b);
             m_bpmCollectionButtons.push_back(b);
-            b = new CollectionButton(m_osu, this, m_songBrowser, m_contextMenu, 250, 250, 200, 50, "", "Under 120 BPM",
+            b = new CollectionButton(this, m_songBrowser, m_contextMenu, 250, 250, 200, 50, "", "Under 120 BPM",
                                      std::vector<Button *>());
                                      std::vector<Button *>());
             m_bpmCollectionButtons.push_back(b);
             m_bpmCollectionButtons.push_back(b);
-            b = new CollectionButton(m_osu, this, m_songBrowser, m_contextMenu, 250, 250, 200, 50, "", "Under 180 BPM",
+            b = new CollectionButton(this, m_songBrowser, m_contextMenu, 250, 250, 200, 50, "", "Under 180 BPM",
                                      std::vector<Button *>());
                                      std::vector<Button *>());
             m_bpmCollectionButtons.push_back(b);
             m_bpmCollectionButtons.push_back(b);
-            b = new CollectionButton(m_osu, this, m_songBrowser, m_contextMenu, 250, 250, 200, 50, "", "Under 240 BPM",
+            b = new CollectionButton(this, m_songBrowser, m_contextMenu, 250, 250, 200, 50, "", "Under 240 BPM",
                                      std::vector<Button *>());
                                      std::vector<Button *>());
             m_bpmCollectionButtons.push_back(b);
             m_bpmCollectionButtons.push_back(b);
-            b = new CollectionButton(m_osu, this, m_songBrowser, m_contextMenu, 250, 250, 200, 50, "", "Under 300 BPM",
+            b = new CollectionButton(this, m_songBrowser, m_contextMenu, 250, 250, 200, 50, "", "Under 300 BPM",
                                      std::vector<Button *>());
                                      std::vector<Button *>());
             m_bpmCollectionButtons.push_back(b);
             m_bpmCollectionButtons.push_back(b);
-            b = new CollectionButton(m_osu, this, m_songBrowser, m_contextMenu, 250, 250, 200, 50, "", "Over 300 BPM",
+            b = new CollectionButton(this, m_songBrowser, m_contextMenu, 250, 250, 200, 50, "", "Over 300 BPM",
                                      std::vector<Button *>());
                                      std::vector<Button *>());
             m_bpmCollectionButtons.push_back(b);
             m_bpmCollectionButtons.push_back(b);
         }
         }
@@ -3004,8 +2990,8 @@ void SongBrowser::onDatabaseLoadingFinished() {
         {
         {
             // 0-9
             // 0-9
             {
             {
-                CollectionButton *b = new CollectionButton(m_osu, this, m_songBrowser, m_contextMenu, 250, 250, 200, 50,
-                                                           "", "0-9", std::vector<Button *>());
+                CollectionButton *b = new CollectionButton(this, m_songBrowser, m_contextMenu, 250, 250, 200, 50, "",
+                                                           "0-9", std::vector<Button *>());
                 m_creatorCollectionButtons.push_back(b);
                 m_creatorCollectionButtons.push_back(b);
             }
             }
 
 
@@ -3013,15 +2999,15 @@ void SongBrowser::onDatabaseLoadingFinished() {
             for(size_t i = 0; i < 26; i++) {
             for(size_t i = 0; i < 26; i++) {
                 UString artistCollectionName = UString::format("%c", 'A' + i);
                 UString artistCollectionName = UString::format("%c", 'A' + i);
 
 
-                CollectionButton *b = new CollectionButton(m_osu, this, m_songBrowser, m_contextMenu, 250, 250, 200, 50,
-                                                           "", artistCollectionName, std::vector<Button *>());
+                CollectionButton *b = new CollectionButton(this, m_songBrowser, m_contextMenu, 250, 250, 200, 50, "",
+                                                           artistCollectionName, std::vector<Button *>());
                 m_creatorCollectionButtons.push_back(b);
                 m_creatorCollectionButtons.push_back(b);
             }
             }
 
 
             // Other
             // Other
             {
             {
-                CollectionButton *b = new CollectionButton(m_osu, this, m_songBrowser, m_contextMenu, 250, 250, 200, 50,
-                                                           "", "Other", std::vector<Button *>());
+                CollectionButton *b = new CollectionButton(this, m_songBrowser, m_contextMenu, 250, 250, 200, 50, "",
+                                                           "Other", std::vector<Button *>());
                 m_creatorCollectionButtons.push_back(b);
                 m_creatorCollectionButtons.push_back(b);
             }
             }
         }
         }
@@ -3033,26 +3019,26 @@ void SongBrowser::onDatabaseLoadingFinished() {
 
 
         // length
         // length
         {
         {
-            CollectionButton *b = new CollectionButton(m_osu, this, m_songBrowser, m_contextMenu, 250, 250, 200, 50, "",
+            CollectionButton *b = new CollectionButton(this, m_songBrowser, m_contextMenu, 250, 250, 200, 50, "",
                                                        "1 minute or less", std::vector<Button *>());
                                                        "1 minute or less", std::vector<Button *>());
             m_lengthCollectionButtons.push_back(b);
             m_lengthCollectionButtons.push_back(b);
-            b = new CollectionButton(m_osu, this, m_songBrowser, m_contextMenu, 250, 250, 200, 50, "",
-                                     "2 minutes or less", std::vector<Button *>());
+            b = new CollectionButton(this, m_songBrowser, m_contextMenu, 250, 250, 200, 50, "", "2 minutes or less",
+                                     std::vector<Button *>());
             m_lengthCollectionButtons.push_back(b);
             m_lengthCollectionButtons.push_back(b);
-            b = new CollectionButton(m_osu, this, m_songBrowser, m_contextMenu, 250, 250, 200, 50, "",
-                                     "3 minutes or less", std::vector<Button *>());
+            b = new CollectionButton(this, m_songBrowser, m_contextMenu, 250, 250, 200, 50, "", "3 minutes or less",
+                                     std::vector<Button *>());
             m_lengthCollectionButtons.push_back(b);
             m_lengthCollectionButtons.push_back(b);
-            b = new CollectionButton(m_osu, this, m_songBrowser, m_contextMenu, 250, 250, 200, 50, "",
-                                     "4 minutes or less", std::vector<Button *>());
+            b = new CollectionButton(this, m_songBrowser, m_contextMenu, 250, 250, 200, 50, "", "4 minutes or less",
+                                     std::vector<Button *>());
             m_lengthCollectionButtons.push_back(b);
             m_lengthCollectionButtons.push_back(b);
-            b = new CollectionButton(m_osu, this, m_songBrowser, m_contextMenu, 250, 250, 200, 50, "",
-                                     "5 minutes or less", std::vector<Button *>());
+            b = new CollectionButton(this, m_songBrowser, m_contextMenu, 250, 250, 200, 50, "", "5 minutes or less",
+                                     std::vector<Button *>());
             m_lengthCollectionButtons.push_back(b);
             m_lengthCollectionButtons.push_back(b);
-            b = new CollectionButton(m_osu, this, m_songBrowser, m_contextMenu, 250, 250, 200, 50, "",
-                                     "10 minutes or less", std::vector<Button *>());
+            b = new CollectionButton(this, m_songBrowser, m_contextMenu, 250, 250, 200, 50, "", "10 minutes or less",
+                                     std::vector<Button *>());
             m_lengthCollectionButtons.push_back(b);
             m_lengthCollectionButtons.push_back(b);
-            b = new CollectionButton(m_osu, this, m_songBrowser, m_contextMenu, 250, 250, 200, 50, "",
-                                     "Over 10 minutes", std::vector<Button *>());
+            b = new CollectionButton(this, m_songBrowser, m_contextMenu, 250, 250, 200, 50, "", "Over 10 minutes",
+                                     std::vector<Button *>());
             m_lengthCollectionButtons.push_back(b);
             m_lengthCollectionButtons.push_back(b);
         }
         }
 
 
@@ -3060,8 +3046,8 @@ void SongBrowser::onDatabaseLoadingFinished() {
         {
         {
             // 0-9
             // 0-9
             {
             {
-                CollectionButton *b = new CollectionButton(m_osu, this, m_songBrowser, m_contextMenu, 250, 250, 200, 50,
-                                                           "", "0-9", std::vector<Button *>());
+                CollectionButton *b = new CollectionButton(this, m_songBrowser, m_contextMenu, 250, 250, 200, 50, "",
+                                                           "0-9", std::vector<Button *>());
                 m_titleCollectionButtons.push_back(b);
                 m_titleCollectionButtons.push_back(b);
             }
             }
 
 
@@ -3069,15 +3055,15 @@ void SongBrowser::onDatabaseLoadingFinished() {
             for(size_t i = 0; i < 26; i++) {
             for(size_t i = 0; i < 26; i++) {
                 UString artistCollectionName = UString::format("%c", 'A' + i);
                 UString artistCollectionName = UString::format("%c", 'A' + i);
 
 
-                CollectionButton *b = new CollectionButton(m_osu, this, m_songBrowser, m_contextMenu, 250, 250, 200, 50,
-                                                           "", artistCollectionName, std::vector<Button *>());
+                CollectionButton *b = new CollectionButton(this, m_songBrowser, m_contextMenu, 250, 250, 200, 50, "",
+                                                           artistCollectionName, std::vector<Button *>());
                 m_titleCollectionButtons.push_back(b);
                 m_titleCollectionButtons.push_back(b);
             }
             }
 
 
             // Other
             // Other
             {
             {
-                CollectionButton *b = new CollectionButton(m_osu, this, m_songBrowser, m_contextMenu, 250, 250, 200, 50,
-                                                           "", "Other", std::vector<Button *>());
+                CollectionButton *b = new CollectionButton(this, m_songBrowser, m_contextMenu, 250, 250, 200, 50, "",
+                                                           "Other", std::vector<Button *>());
                 m_titleCollectionButtons.push_back(b);
                 m_titleCollectionButtons.push_back(b);
             }
             }
         }
         }
@@ -3095,7 +3081,7 @@ void SongBrowser::onDatabaseLoadingFinished() {
     onSortScoresChange(osu_songbrowser_scores_sortingtype.getString());
     onSortScoresChange(osu_songbrowser_scores_sortingtype.getString());
 
 
     // update rich presence (discord total pp)
     // update rich presence (discord total pp)
-    RichPresence::onSongBrowser(m_osu);
+    RichPresence::onSongBrowser();
 
 
     // update user name/stats
     // update user name/stats
     onUserButtonChange(m_name_ref->getString(), -1);
     onUserButtonChange(m_name_ref->getString(), -1);
@@ -3104,14 +3090,14 @@ void SongBrowser::onDatabaseLoadingFinished() {
 
 
     // main menu starts playing a song before the database is loaded,
     // main menu starts playing a song before the database is loaded,
     // re-select it after the database has been loaded
     // re-select it after the database has been loaded
-    if(m_osu->m_mainMenu->preloaded_beatmapset != nullptr) {
-        auto matching_beatmap = getDatabase()->getBeatmapDifficulty(m_osu->m_mainMenu->preloaded_beatmap->getMD5Hash());
+    if(osu->m_mainMenu->preloaded_beatmapset != nullptr) {
+        auto matching_beatmap = getDatabase()->getBeatmapDifficulty(osu->m_mainMenu->preloaded_beatmap->getMD5Hash());
         if(matching_beatmap) {
         if(matching_beatmap) {
             onDifficultySelected(matching_beatmap, false);
             onDifficultySelected(matching_beatmap, false);
             selectSelectedBeatmapSongButton();
             selectSelectedBeatmapSongButton();
         }
         }
 
 
-        SAFE_DELETE(m_osu->m_mainMenu->preloaded_beatmapset);
+        SAFE_DELETE(osu->m_mainMenu->preloaded_beatmapset);
     }
     }
 
 
     // ok, if we still haven't selected a song, do so now
     // ok, if we still haven't selected a song, do so now
@@ -3324,7 +3310,7 @@ void SongBrowser::onSortScoresChange(UString text, int id) {
 void SongBrowser::onWebClicked(CBaseUIButton *button) {
 void SongBrowser::onWebClicked(CBaseUIButton *button) {
     if(m_songInfo->getBeatmapID() > 0) {
     if(m_songInfo->getBeatmapID() > 0) {
         env->openURLInDefaultBrowser(UString::format("https://osu.ppy.sh/b/%ld", m_songInfo->getBeatmapID()));
         env->openURLInDefaultBrowser(UString::format("https://osu.ppy.sh/b/%ld", m_songInfo->getBeatmapID()));
-        m_osu->getNotificationOverlay()->addNotification("Opening browser, please wait ...", 0xffffffff, false, 0.75f);
+        osu->getNotificationOverlay()->addNotification("Opening browser, please wait ...", 0xffffffff, false, 0.75f);
     }
     }
 }
 }
 
 
@@ -3645,7 +3631,7 @@ void SongBrowser::onAfterSortingOrGroupChangeUpdateInt(bool autoScroll) {
 }
 }
 
 
 void SongBrowser::onSelectionMode() {
 void SongBrowser::onSelectionMode() {
-    engine->getSound()->play(m_osu->getSkin()->getMenuClick());
+    engine->getSound()->play(osu->getSkin()->getMenuClick());
 
 
     m_contextMenu->setPos(m_bottombarNavButtons[0]->getPos());
     m_contextMenu->setPos(m_bottombarNavButtons[0]->getPos());
     m_contextMenu->setRelPos(m_bottombarNavButtons[0]->getRelPos());
     m_contextMenu->setRelPos(m_bottombarNavButtons[0]->getRelPos());
@@ -3680,12 +3666,12 @@ void SongBrowser::onSelectionMode() {
 }
 }
 
 
 void SongBrowser::onSelectionMods() {
 void SongBrowser::onSelectionMods() {
-    engine->getSound()->play(m_osu->getSkin()->getMenuClick());
-    m_osu->toggleModSelection(m_bF1Pressed);
+    engine->getSound()->play(osu->getSkin()->getMenuClick());
+    osu->toggleModSelection(m_bF1Pressed);
 }
 }
 
 
 void SongBrowser::onSelectionRandom() {
 void SongBrowser::onSelectionRandom() {
-    engine->getSound()->play(m_osu->getSkin()->getMenuClick());
+    engine->getSound()->play(osu->getSkin()->getMenuClick());
     if(m_bShiftPressed)
     if(m_bShiftPressed)
         m_bPreviousRandomBeatmapScheduled = true;
         m_bPreviousRandomBeatmapScheduled = true;
     else
     else
@@ -3693,7 +3679,7 @@ void SongBrowser::onSelectionRandom() {
 }
 }
 
 
 void SongBrowser::onSelectionOptions() {
 void SongBrowser::onSelectionOptions() {
-    engine->getSound()->play(m_osu->getSkin()->getMenuClick());
+    engine->getSound()->play(osu->getSkin()->getMenuClick());
 
 
     Button *currentlySelectedSongButton = findCurrentlySelectedSongButton();
     Button *currentlySelectedSongButton = findCurrentlySelectedSongButton();
     if(currentlySelectedSongButton != NULL) {
     if(currentlySelectedSongButton != NULL) {
@@ -3721,7 +3707,7 @@ void SongBrowser::onUserButtonClicked() {
     // Not allowed to switch user while online
     // Not allowed to switch user while online
     if(bancho.user_id > 0) return;
     if(bancho.user_id > 0) return;
 
 
-    engine->getSound()->play(m_osu->getSkin()->getMenuClick());
+    engine->getSound()->play(osu->getSkin()->getMenuClick());
 
 
     std::vector<UString> names = m_db->getPlayerNamesWithScoresForUserSwitcher();
     std::vector<UString> names = m_db->getPlayerNamesWithScoresForUserSwitcher();
     if(names.size() > 0) {
     if(names.size() > 0) {
@@ -3753,12 +3739,12 @@ void SongBrowser::onUserButtonChange(UString text, int id) {
     if(id == 0) return;
     if(id == 0) return;
 
 
     if(id == 1) {
     if(id == 1) {
-        m_osu->toggleUserStatsScreen();
+        osu->toggleUserStatsScreen();
         return;
         return;
     }
     }
 
 
     m_name_ref->setValue(text);
     m_name_ref->setValue(text);
-    m_osu->getOptionsMenu()->setUsername(text);  // NOTE: force update options textbox to avoid shutdown inconsistency
+    osu->getOptionsMenu()->setUsername(text);  // NOTE: force update options textbox to avoid shutdown inconsistency
     m_userButton->setText(text);
     m_userButton->setText(text);
 
 
     m_userButton->updateUserStats();
     m_userButton->updateUserStats();
@@ -3769,11 +3755,11 @@ void SongBrowser::onScoreClicked(CBaseUIButton *button) {
 
 
     // NOTE: the order of these two calls matters (score data overwrites relevant fields, but base values are coming
     // NOTE: the order of these two calls matters (score data overwrites relevant fields, but base values are coming
     // from the beatmap)
     // from the beatmap)
-    m_osu->getRankingScreen()->setBeatmapInfo(m_selectedBeatmap, m_selectedBeatmap->getSelectedDifficulty2());
-    m_osu->getRankingScreen()->setScore(scoreButton->getScore(), scoreButton->getDateTime());
+    osu->getRankingScreen()->setBeatmapInfo(m_selectedBeatmap, m_selectedBeatmap->getSelectedDifficulty2());
+    osu->getRankingScreen()->setScore(scoreButton->getScore(), scoreButton->getDateTime());
 
 
-    m_osu->getSongBrowser()->setVisible(false);
-    m_osu->getRankingScreen()->setVisible(true);
+    osu->getSongBrowser()->setVisible(false);
+    osu->getRankingScreen()->setVisible(true);
 }
 }
 
 
 void SongBrowser::onScoreContextMenu(ScoreButton *scoreButton, int id) {
 void SongBrowser::onScoreContextMenu(ScoreButton *scoreButton, int id) {
@@ -3967,7 +3953,7 @@ void SongBrowser::recalculateStarsForSelectedBeatmap(bool force) {
     // graph is enabled (or "Draw Stats: Stars* (Total)", or "Draw Stats: pp (SS)")
     // graph is enabled (or "Draw Stats: Stars* (Total)", or "Draw Stats: pp (SS)")
     if(!m_osu_draw_scrubbing_timeline_strain_graph_ref->getBool() && !m_osu_draw_statistics_perfectpp_ref->getBool() &&
     if(!m_osu_draw_scrubbing_timeline_strain_graph_ref->getBool() && !m_osu_draw_statistics_perfectpp_ref->getBool() &&
        !m_osu_draw_statistics_totalstars_ref->getBool()) {
        !m_osu_draw_statistics_totalstars_ref->getBool()) {
-        if(m_osu->isInPlayMode()) {
+        if(osu->isInPlayMode()) {
             m_bBackgroundStarCalcScheduled = true;
             m_bBackgroundStarCalcScheduled = true;
             m_bBackgroundStarCalcScheduledForce = (m_bBackgroundStarCalcScheduledForce || force);
             m_bBackgroundStarCalcScheduledForce = (m_bBackgroundStarCalcScheduledForce || force);
 
 
@@ -3986,10 +3972,9 @@ void SongBrowser::recalculateStarsForSelectedBeatmap(bool force) {
         const float AR = m_selectedBeatmap->getAR();
         const float AR = m_selectedBeatmap->getAR();
         const float CS = m_selectedBeatmap->getCS();
         const float CS = m_selectedBeatmap->getCS();
         const float OD = m_selectedBeatmap->getOD();
         const float OD = m_selectedBeatmap->getOD();
-        const float speedMultiplier =
-            m_osu->getSpeedMultiplier();  // NOTE: not m_selectedBeatmap->getSpeedMultiplier()!
-        const bool relax = m_osu->getModRelax();
-        const bool touchdevice = m_osu->getModTD();
+        const float speedMultiplier = osu->getSpeedMultiplier();  // NOTE: not m_selectedBeatmap->getSpeedMultiplier()!
+        const bool relax = osu->getModRelax();
+        const bool touchdevice = osu->getModTD();
 
 
         m_dynamicStarCalculator->setBeatmapDifficulty(m_selectedBeatmap->getSelectedDifficulty2(), AR, CS, OD,
         m_dynamicStarCalculator->setBeatmapDifficulty(m_selectedBeatmap->getSelectedDifficulty2(), AR, CS, OD,
                                                       speedMultiplier, relax, touchdevice);
                                                       speedMultiplier, relax, touchdevice);
@@ -4166,9 +4151,8 @@ void SongBrowser::recreateCollectionsButtons() {
 
 
         if(!folder.empty()) {
         if(!folder.empty()) {
             UString uname = collection->name.c_str();
             UString uname = collection->name.c_str();
-            m_collectionButtons.push_back(new CollectionButton(m_osu, this, m_songBrowser, m_contextMenu, 250,
-                                                               250 + m_beatmaps.size() * 50, 200, 50, "", uname,
-                                                               folder));
+            m_collectionButtons.push_back(new CollectionButton(
+                this, m_songBrowser, m_contextMenu, 250, 250 + m_beatmaps.size() * 50, 200, 50, "", uname, folder));
         }
         }
     }
     }
 
 

+ 2 - 4
src/App/Osu/SongBrowser/SongBrowser.h

@@ -2,7 +2,6 @@
 #include "MouseListener.h"
 #include "MouseListener.h"
 #include "ScreenBackable.h"
 #include "ScreenBackable.h"
 
 
-class Osu;
 class Beatmap;
 class Beatmap;
 class Database;
 class Database;
 class DatabaseBeatmap;
 class DatabaseBeatmap;
@@ -34,7 +33,7 @@ class SongBrowserBackgroundSearchMatcher;
 
 
 class SongBrowser : public ScreenBackable {
 class SongBrowser : public ScreenBackable {
    public:
    public:
-    static void drawSelectedBeatmapBackgroundImage(Graphics *g, Osu *osu, float alpha = 1.0f);
+    static void drawSelectedBeatmapBackgroundImage(Graphics *g, float alpha = 1.0f);
 
 
     struct SORTING_COMPARATOR {
     struct SORTING_COMPARATOR {
         virtual ~SORTING_COMPARATOR() { ; }
         virtual ~SORTING_COMPARATOR() { ; }
@@ -90,7 +89,7 @@ class SongBrowser : public ScreenBackable {
 
 
     friend class SongBrowserBackgroundSearchMatcher;
     friend class SongBrowserBackgroundSearchMatcher;
 
 
-    SongBrowser(Osu *osu);
+    SongBrowser();
     virtual ~SongBrowser();
     virtual ~SongBrowser();
 
 
     virtual void draw(Graphics *g);
     virtual void draw(Graphics *g);
@@ -262,7 +261,6 @@ class SongBrowser : public ScreenBackable {
 
 
     ConVar *m_osu_mod_fposu_ref;
     ConVar *m_osu_mod_fposu_ref;
 
 
-    Osu *m_osu;
     GROUP m_group;
     GROUP m_group;
     std::vector<GROUPING> m_groupings;
     std::vector<GROUPING> m_groupings;
     SORT m_sortingMethod;
     SORT m_sortingMethod;

+ 19 - 19
src/App/Osu/SongBrowser/SongButton.cpp

@@ -25,9 +25,9 @@ ConVar osu_songbrowser_thumbnail_fade_in_duration("osu_songbrowser_thumbnail_fad
 
 
 float SongButton::thumbnailYRatio = 1.333333f;
 float SongButton::thumbnailYRatio = 1.333333f;
 
 
-SongButton::SongButton(Osu *osu, SongBrowser *songBrowser, CBaseUIScrollView *view, UIContextMenu *contextMenu,
-                       float xPos, float yPos, float xSize, float ySize, UString name, DatabaseBeatmap *databaseBeatmap)
-    : Button(osu, songBrowser, view, contextMenu, xPos, yPos, xSize, ySize, name) {
+SongButton::SongButton(SongBrowser *songBrowser, CBaseUIScrollView *view, UIContextMenu *contextMenu, float xPos,
+                       float yPos, float xSize, float ySize, UString name, DatabaseBeatmap *databaseBeatmap)
+    : Button(songBrowser, view, contextMenu, xPos, yPos, xSize, ySize, name) {
     m_databaseBeatmap = databaseBeatmap;
     m_databaseBeatmap = databaseBeatmap;
 
 
     m_grade = FinishedScore::Grade::D;
     m_grade = FinishedScore::Grade::D;
@@ -52,8 +52,8 @@ SongButton::SongButton(Osu *osu, SongBrowser *songBrowser, CBaseUIScrollView *vi
 
 
         // and add them
         // and add them
         for(int i = 0; i < difficulties.size(); i++) {
         for(int i = 0; i < difficulties.size(); i++) {
-            SongButton *songButton = new SongDifficultyButton(m_osu, m_songBrowser, m_view, m_contextMenu, 0, 0, 0, 0,
-                                                              "", difficulties[i], this);
+            SongButton *songButton =
+                new SongDifficultyButton(m_songBrowser, m_view, m_contextMenu, 0, 0, 0, 0, "", difficulties[i], this);
 
 
             m_children.push_back(songButton);
             m_children.push_back(songButton);
         }
         }
@@ -89,7 +89,7 @@ void SongButton::draw(Graphics *g) {
                 m_sMapper = representative_beatmap->getCreator();
                 m_sMapper = representative_beatmap->getCreator();
 
 
                 drawBeatmapBackgroundThumbnail(
                 drawBeatmapBackgroundThumbnail(
-                    g, m_osu->getBackgroundImageHandler()->getLoadBackgroundImage(representative_beatmap));
+                    g, osu->getBackgroundImageHandler()->getLoadBackgroundImage(representative_beatmap));
 
 
                 break;
                 break;
             }
             }
@@ -101,7 +101,7 @@ void SongButton::draw(Graphics *g) {
 }
 }
 
 
 void SongButton::drawBeatmapBackgroundThumbnail(Graphics *g, Image *image) {
 void SongButton::drawBeatmapBackgroundThumbnail(Graphics *g, Image *image) {
-    if(!osu_draw_songbrowser_thumbnails.getBool() || m_osu->getSkin()->getVersion() < 2.2f) return;
+    if(!osu_draw_songbrowser_thumbnails.getBool() || osu->getSkin()->getVersion() < 2.2f) return;
 
 
     float alpha = 1.0f;
     float alpha = 1.0f;
     if(osu_songbrowser_thumbnail_fade_in_duration.getFloat() > 0.0f) {
     if(osu_songbrowser_thumbnail_fade_in_duration.getFloat() > 0.0f) {
@@ -159,7 +159,7 @@ void SongButton::drawGrade(Graphics *g) {
     const Vector2 pos = getActualPos();
     const Vector2 pos = getActualPos();
     const Vector2 size = getActualSize();
     const Vector2 size = getActualSize();
 
 
-    SkinImage *grade = ScoreButton::getGradeImage(m_osu, m_grade);
+    SkinImage *grade = ScoreButton::getGradeImage(m_grade);
     g->pushTransform();
     g->pushTransform();
     {
     {
         const float scale = calculateGradeScale();
         const float scale = calculateGradeScale();
@@ -177,8 +177,8 @@ void SongButton::drawTitle(Graphics *g, float deselectedAlpha, bool forceSelecte
     const Vector2 size = getActualSize();
     const Vector2 size = getActualSize();
 
 
     const float titleScale = (size.y * m_fTitleScale) / m_font->getHeight();
     const float titleScale = (size.y * m_fTitleScale) / m_font->getHeight();
-    g->setColor((m_bSelected || forceSelectedStyle) ? m_osu->getSkin()->getSongSelectActiveText()
-                                                    : m_osu->getSkin()->getSongSelectInactiveText());
+    g->setColor((m_bSelected || forceSelectedStyle) ? osu->getSkin()->getSongSelectActiveText()
+                                                    : osu->getSkin()->getSongSelectInactiveText());
     if(!(m_bSelected || forceSelectedStyle)) g->setAlpha(deselectedAlpha);
     if(!(m_bSelected || forceSelectedStyle)) g->setAlpha(deselectedAlpha);
 
 
     g->pushTransform();
     g->pushTransform();
@@ -198,8 +198,8 @@ void SongButton::drawSubTitle(Graphics *g, float deselectedAlpha, bool forceSele
 
 
     const float titleScale = (size.y * m_fTitleScale) / m_font->getHeight();
     const float titleScale = (size.y * m_fTitleScale) / m_font->getHeight();
     const float subTitleScale = (size.y * m_fSubTitleScale) / m_font->getHeight();
     const float subTitleScale = (size.y * m_fSubTitleScale) / m_font->getHeight();
-    g->setColor((m_bSelected || forceSelectedStyle) ? m_osu->getSkin()->getSongSelectActiveText()
-                                                    : m_osu->getSkin()->getSongSelectInactiveText());
+    g->setColor((m_bSelected || forceSelectedStyle) ? osu->getSkin()->getSongSelectActiveText()
+                                                    : osu->getSkin()->getSongSelectInactiveText());
     if(!(m_bSelected || forceSelectedStyle)) g->setAlpha(deselectedAlpha);
     if(!(m_bSelected || forceSelectedStyle)) g->setAlpha(deselectedAlpha);
 
 
     g->pushTransform();
     g->pushTransform();
@@ -230,7 +230,7 @@ void SongButton::updateLayoutEx() {
 
 
     if(m_bHasGrade) m_fTextOffset += calculateGradeWidth();
     if(m_bHasGrade) m_fTextOffset += calculateGradeWidth();
 
 
-    if(m_osu->getSkin()->getVersion() < 2.2f) {
+    if(osu->getSkin()->getVersion() < 2.2f) {
         m_fTextOffset += size.x * 0.02f * 2.0f;
         m_fTextOffset += size.x * 0.02f * 2.0f;
         if(m_bHasGrade) m_fGradeOffset += calculateGradeWidth() / 2;
         if(m_bHasGrade) m_fGradeOffset += calculateGradeWidth() / 2;
     } else {
     } else {
@@ -280,7 +280,7 @@ void SongButton::triggerContextMenu(Vector2 pos) {
 
 
             m_contextMenu->addButton("[+Set]   Add to Collection", 2);
             m_contextMenu->addButton("[+Set]   Add to Collection", 2);
 
 
-            if(m_osu->getSongBrowser()->getGroupingMode() == SongBrowser::GROUP::GROUP_COLLECTIONS) {
+            if(osu->getSongBrowser()->getGroupingMode() == SongBrowser::GROUP::GROUP_COLLECTIONS) {
                 CBaseUIButton *spacer = m_contextMenu->addButton("---");
                 CBaseUIButton *spacer = m_contextMenu->addButton("---");
                 spacer->setTextLeft(false);
                 spacer->setTextLeft(false);
                 spacer->setEnabled(false);
                 spacer->setEnabled(false);
@@ -353,7 +353,7 @@ void SongButton::onContextMenu(UString text, int id) {
     } else if(id == 3 || id == 4) {
     } else if(id == 3 || id == 4) {
         // 3 = remove map from collection
         // 3 = remove map from collection
         // 4 = remove set from collection
         // 4 = remove set from collection
-        m_osu->getSongBrowser()->onSongButtonContextMenu(this, text, id);
+        osu->getSongBrowser()->onSongButtonContextMenu(this, text, id);
     }
     }
 }
 }
 
 
@@ -390,27 +390,27 @@ void SongButton::onAddToCollectionConfirmed(UString text, int id) {
         UIContextMenu::clampToBottomScreenEdge(m_contextMenu);
         UIContextMenu::clampToBottomScreenEdge(m_contextMenu);
     } else {
     } else {
         // just forward it
         // just forward it
-        m_osu->getSongBrowser()->onSongButtonContextMenu(this, text, id);
+        osu->getSongBrowser()->onSongButtonContextMenu(this, text, id);
     }
     }
 }
 }
 
 
 void SongButton::onCreateNewCollectionConfirmed(UString text, int id) {
 void SongButton::onCreateNewCollectionConfirmed(UString text, int id) {
     if(id == -2 || id == -4) {
     if(id == -2 || id == -4) {
         // just forward it
         // just forward it
-        m_osu->getSongBrowser()->onSongButtonContextMenu(this, text, id);
+        osu->getSongBrowser()->onSongButtonContextMenu(this, text, id);
     }
     }
 }
 }
 
 
 float SongButton::calculateGradeScale() {
 float SongButton::calculateGradeScale() {
     const Vector2 size = getActualSize();
     const Vector2 size = getActualSize();
 
 
-    SkinImage *grade = ScoreButton::getGradeImage(m_osu, m_grade);
+    SkinImage *grade = ScoreButton::getGradeImage(m_grade);
 
 
     return Osu::getImageScaleToFitResolution(grade->getSizeBaseRaw(), Vector2(size.x, size.y * m_fGradeScale));
     return Osu::getImageScaleToFitResolution(grade->getSizeBaseRaw(), Vector2(size.x, size.y * m_fGradeScale));
 }
 }
 
 
 float SongButton::calculateGradeWidth() {
 float SongButton::calculateGradeWidth() {
-    SkinImage *grade = ScoreButton::getGradeImage(m_osu, m_grade);
+    SkinImage *grade = ScoreButton::getGradeImage(m_grade);
 
 
     return grade->getSizeBaseRaw().x * calculateGradeScale();
     return grade->getSizeBaseRaw().x * calculateGradeScale();
 }
 }

+ 2 - 2
src/App/Osu/SongBrowser/SongButton.h

@@ -7,8 +7,8 @@ class DatabaseBeatmap;
 
 
 class SongButton : public Button {
 class SongButton : public Button {
    public:
    public:
-    SongButton(Osu *osu, SongBrowser *songBrowser, CBaseUIScrollView *view, UIContextMenu *contextMenu, float xPos,
-               float yPos, float xSize, float ySize, UString name, DatabaseBeatmap *databaseBeatmap);
+    SongButton(SongBrowser *songBrowser, CBaseUIScrollView *view, UIContextMenu *contextMenu, float xPos, float yPos,
+               float xSize, float ySize, UString name, DatabaseBeatmap *databaseBeatmap);
     virtual ~SongButton();
     virtual ~SongButton();
 
 
     virtual void draw(Graphics *g);
     virtual void draw(Graphics *g);

+ 10 - 10
src/App/Osu/SongBrowser/SongDifficultyButton.cpp

@@ -27,10 +27,10 @@ ConVar osu_songbrowser_button_difficulty_inactive_color_b("osu_songbrowser_butto
 ConVar *SongDifficultyButton::m_osu_scores_enabled = NULL;
 ConVar *SongDifficultyButton::m_osu_scores_enabled = NULL;
 ConVar *SongDifficultyButton::m_osu_songbrowser_dynamic_star_recalc_ref = NULL;
 ConVar *SongDifficultyButton::m_osu_songbrowser_dynamic_star_recalc_ref = NULL;
 
 
-SongDifficultyButton::SongDifficultyButton(Osu *osu, SongBrowser *songBrowser, CBaseUIScrollView *view,
+SongDifficultyButton::SongDifficultyButton(SongBrowser *songBrowser, CBaseUIScrollView *view,
                                            UIContextMenu *contextMenu, float xPos, float yPos, float xSize, float ySize,
                                            UIContextMenu *contextMenu, float xPos, float yPos, float xSize, float ySize,
                                            UString name, DatabaseBeatmap *diff2, SongButton *parentSongButton)
                                            UString name, DatabaseBeatmap *diff2, SongButton *parentSongButton)
-    : SongButton(osu, songBrowser, view, contextMenu, xPos, yPos, xSize, ySize, name, NULL) {
+    : SongButton(songBrowser, view, contextMenu, xPos, yPos, xSize, ySize, name, NULL) {
     m_databaseBeatmap = diff2;  // NOTE: can't use parent constructor for passing this argument, as it would otherwise
     m_databaseBeatmap = diff2;  // NOTE: can't use parent constructor for passing this argument, as it would otherwise
                                 // try to build a full button (and not just a diff button)
                                 // try to build a full button (and not just a diff button)
     m_parentSongButton = parentSongButton;
     m_parentSongButton = parentSongButton;
@@ -71,14 +71,14 @@ void SongDifficultyButton::draw(Graphics *g) {
 
 
     const bool isIndependentDiff = isIndependentDiffButton();
     const bool isIndependentDiff = isIndependentDiffButton();
 
 
-    Skin *skin = m_osu->getSkin();
+    Skin *skin = osu->getSkin();
 
 
     // scaling
     // scaling
     const Vector2 pos = getActualPos();
     const Vector2 pos = getActualPos();
     const Vector2 size = getActualSize();
     const Vector2 size = getActualSize();
 
 
     // draw background image
     // draw background image
-    drawBeatmapBackgroundThumbnail(g, m_osu->getBackgroundImageHandler()->getLoadBackgroundImage(m_databaseBeatmap));
+    drawBeatmapBackgroundThumbnail(g, osu->getBackgroundImageHandler()->getLoadBackgroundImage(m_databaseBeatmap));
 
 
     if(m_bHasGrade) drawGrade(g);
     if(m_bHasGrade) drawGrade(g);
 
 
@@ -104,11 +104,11 @@ void SongDifficultyButton::draw(Graphics *g) {
     // draw stars
     // draw stars
     const float starsNoMod =
     const float starsNoMod =
         m_databaseBeatmap->getStarsNomod();  // NOTE: this can sometimes be infinity! (e.g. broken osu!.db database)
         m_databaseBeatmap->getStarsNomod();  // NOTE: this can sometimes be infinity! (e.g. broken osu!.db database)
-    const bool areStarsInaccurate = (m_osu->getSongBrowser()->getDynamicStarCalculator()->isDead() ||
-                                     !m_osu->getSongBrowser()->getDynamicStarCalculator()->isAsyncReady());
+    const bool areStarsInaccurate = (osu->getSongBrowser()->getDynamicStarCalculator()->isDead() ||
+                                     !osu->getSongBrowser()->getDynamicStarCalculator()->isAsyncReady());
     const float stars = (areStarsInaccurate || !m_osu_songbrowser_dynamic_star_recalc_ref->getBool() || !m_bSelected
     const float stars = (areStarsInaccurate || !m_osu_songbrowser_dynamic_star_recalc_ref->getBool() || !m_bSelected
                              ? starsNoMod
                              ? starsNoMod
-                             : m_osu->getSongBrowser()->getDynamicStarCalculator()->getTotalStars());
+                             : osu->getSongBrowser()->getDynamicStarCalculator()->getTotalStars());
     if(stars > 0) {
     if(stars > 0) {
         const float starOffsetY = (size.y * 0.85);
         const float starOffsetY = (size.y * 0.85);
         const float starWidth = (size.y * 0.2);
         const float starWidth = (size.y * 0.2);
@@ -203,10 +203,10 @@ void SongDifficultyButton::updateGrade() {
     bool hasGrade = false;
     bool hasGrade = false;
     FinishedScore::Grade grade;
     FinishedScore::Grade grade;
 
 
-    m_osu->getSongBrowser()->getDatabase()->sortScores(m_databaseBeatmap->getMD5Hash());
-    if((*m_osu->getSongBrowser()->getDatabase()->getScores())[m_databaseBeatmap->getMD5Hash()].size() > 0) {
+    osu->getSongBrowser()->getDatabase()->sortScores(m_databaseBeatmap->getMD5Hash());
+    if((*osu->getSongBrowser()->getDatabase()->getScores())[m_databaseBeatmap->getMD5Hash()].size() > 0) {
         const FinishedScore &score =
         const FinishedScore &score =
-            (*m_osu->getSongBrowser()->getDatabase()->getScores())[m_databaseBeatmap->getMD5Hash()][0];
+            (*osu->getSongBrowser()->getDatabase()->getScores())[m_databaseBeatmap->getMD5Hash()][0];
         hasGrade = true;
         hasGrade = true;
         grade = LiveScore::calculateGrade(score.num300s, score.num100s, score.num50s, score.numMisses,
         grade = LiveScore::calculateGrade(score.num300s, score.num100s, score.num50s, score.numMisses,
                                           score.modsLegacy & ModFlags::Hidden, score.modsLegacy & ModFlags::Flashlight);
                                           score.modsLegacy & ModFlags::Hidden, score.modsLegacy & ModFlags::Flashlight);

+ 2 - 2
src/App/Osu/SongBrowser/SongDifficultyButton.h

@@ -5,8 +5,8 @@ class ConVar;
 
 
 class SongDifficultyButton : public SongButton {
 class SongDifficultyButton : public SongButton {
    public:
    public:
-    SongDifficultyButton(Osu *osu, SongBrowser *songBrowser, CBaseUIScrollView *view, UIContextMenu *contextMenu,
-                         float xPos, float yPos, float xSize, float ySize, UString name, DatabaseBeatmap *diff2,
+    SongDifficultyButton(SongBrowser *songBrowser, CBaseUIScrollView *view, UIContextMenu *contextMenu, float xPos,
+                         float yPos, float xSize, float ySize, UString name, DatabaseBeatmap *diff2,
                          SongButton *parentSongButton);
                          SongButton *parentSongButton);
     virtual ~SongDifficultyButton();
     virtual ~SongDifficultyButton();
 
 

+ 7 - 9
src/App/Osu/SongBrowser/UserButton.cpp

@@ -24,9 +24,7 @@ ConVar osu_user_draw_accuracy("osu_user_draw_accuracy", true, FCVAR_DEFAULT);
 ConVar osu_user_draw_level("osu_user_draw_level", true, FCVAR_DEFAULT);
 ConVar osu_user_draw_level("osu_user_draw_level", true, FCVAR_DEFAULT);
 ConVar osu_user_draw_level_bar("osu_user_draw_level_bar", true, FCVAR_DEFAULT);
 ConVar osu_user_draw_level_bar("osu_user_draw_level_bar", true, FCVAR_DEFAULT);
 
 
-UserButton::UserButton(Osu *osu) : CBaseUIButton() {
-    m_osu = osu;
-
+UserButton::UserButton() : CBaseUIButton() {
     m_osu_scores_enabled_ref = convar->getConVarByName("osu_scores_enabled");
     m_osu_scores_enabled_ref = convar->getConVarByName("osu_scores_enabled");
 
 
     m_fPP = 0.0f;
     m_fPP = 0.0f;
@@ -69,17 +67,17 @@ void UserButton::draw(Graphics *g) {
         g->pushTransform();
         g->pushTransform();
         {
         {
             const float scale =
             const float scale =
-                Osu::getImageScaleToFillResolution(m_osu->getSkin()->getUserIcon(), Vector2(iconWidth, iconHeight));
+                Osu::getImageScaleToFillResolution(osu->getSkin()->getUserIcon(), Vector2(iconWidth, iconHeight));
             g->scale(scale, scale);
             g->scale(scale, scale);
             g->translate(m_vPos.x + iconBorder + iconWidth / 2 + 1, m_vPos.y + iconBorder + iconHeight / 2 + 1);
             g->translate(m_vPos.x + iconBorder + iconWidth / 2 + 1, m_vPos.y + iconBorder + iconHeight / 2 + 1);
-            g->drawImage(m_osu->getSkin()->getUserIcon());
+            g->drawImage(osu->getSkin()->getUserIcon());
         }
         }
         g->popTransform();
         g->popTransform();
         g->popClipRect();
         g->popClipRect();
     }
     }
 
 
     // draw username
     // draw username
-    McFont *usernameFont = m_osu->getSongBrowserFont();
+    McFont *usernameFont = osu->getSongBrowserFont();
     const float usernameScale = 0.5f;
     const float usernameScale = 0.5f;
     float usernamePaddingLeft = 0.0f;
     float usernamePaddingLeft = 0.0f;
     g->pushClipRect(McRect(m_vPos.x + iconBorder, m_vPos.y + iconBorder, m_vSize.x - 2 * iconBorder, iconHeight));
     g->pushClipRect(McRect(m_vPos.x + iconBorder, m_vPos.y + iconBorder, m_vSize.x - 2 * iconBorder, iconHeight));
@@ -104,7 +102,7 @@ void UserButton::draw(Graphics *g) {
 
 
     if(m_osu_scores_enabled_ref->getBool()) {
     if(m_osu_scores_enabled_ref->getBool()) {
         // draw performance (pp), and accuracy
         // draw performance (pp), and accuracy
-        McFont *performanceFont = m_osu->getSubTitleFont();
+        McFont *performanceFont = osu->getSubTitleFont();
         const float performanceScale = 0.3f;
         const float performanceScale = 0.3f;
         g->pushTransform();
         g->pushTransform();
         {
         {
@@ -133,7 +131,7 @@ void UserButton::draw(Graphics *g) {
         g->popTransform();
         g->popTransform();
 
 
         // draw level
         // draw level
-        McFont *scoreFont = m_osu->getSubTitleFont();
+        McFont *scoreFont = osu->getSubTitleFont();
         const float scoreScale = 0.3f;
         const float scoreScale = 0.3f;
         g->pushTransform();
         g->pushTransform();
         {
         {
@@ -224,7 +222,7 @@ void UserButton::mouse_update(bool *propagate_clicks) {
 }
 }
 
 
 void UserButton::updateUserStats() {
 void UserButton::updateUserStats() {
-    Database::PlayerStats stats = m_osu->getSongBrowser()->getDatabase()->calculatePlayerStats(m_sText);
+    Database::PlayerStats stats = osu->getSongBrowser()->getDatabase()->calculatePlayerStats(m_sText);
 
 
     if(bancho.user_id > 0) {
     if(bancho.user_id > 0) {
         UserInfo *my = get_user_info(bancho.user_id);
         UserInfo *my = get_user_info(bancho.user_id);

+ 1 - 4
src/App/Osu/SongBrowser/UserButton.h

@@ -3,12 +3,11 @@
 
 
 class ConVar;
 class ConVar;
 
 
-class Osu;
 class UIAvatar;
 class UIAvatar;
 
 
 class UserButton : public CBaseUIButton {
 class UserButton : public CBaseUIButton {
    public:
    public:
-    UserButton(Osu *osu);
+    UserButton();
 
 
     virtual void draw(Graphics *g);
     virtual void draw(Graphics *g);
     virtual void mouse_update(bool *propagate_clicks);
     virtual void mouse_update(bool *propagate_clicks);
@@ -25,8 +24,6 @@ class UserButton : public CBaseUIButton {
 
 
     ConVar *m_osu_scores_enabled_ref;
     ConVar *m_osu_scores_enabled_ref;
 
 
-    Osu *m_osu;
-
     float m_fPP;
     float m_fPP;
     float m_fAcc;
     float m_fAcc;
     int m_iLevel;
     int m_iLevel;

+ 13 - 15
src/App/Osu/Spinner.cpp

@@ -117,7 +117,7 @@ void Spinner::draw(Graphics *g) {
         }
         }
 
 
         // draw approach circle
         // draw approach circle
-        if(!m_beatmap->getOsu()->getModHD() && m_fPercent > 0.0f) {
+        if(!osu->getModHD() && m_fPercent > 0.0f) {
             const float spinnerApproachCircleImageScale =
             const float spinnerApproachCircleImageScale =
                 globalBaseSize / ((globalBaseSkinSize / 2) * (skin->isSpinnerApproachCircle2x() ? 2.0f : 1.0f));
                 globalBaseSize / ((globalBaseSkinSize / 2) * (skin->isSpinnerApproachCircle2x() ? 2.0f : 1.0f));
 
 
@@ -205,7 +205,7 @@ void Spinner::draw(Graphics *g) {
         }
         }
 
 
         // approach circle
         // approach circle
-        if(!m_beatmap->getOsu()->getModHD() && m_fPercent > 0.0f) {
+        if(!osu->getModHD() && m_fPercent > 0.0f) {
             const float spinnerApproachCircleImageScale =
             const float spinnerApproachCircleImageScale =
                 globalBaseSize / ((globalBaseSkinSize / 2) * (skin->isSpinnerApproachCircle2x() ? 2.0f : 1.0f));
                 globalBaseSize / ((globalBaseSkinSize / 2) * (skin->isSpinnerApproachCircle2x() ? 2.0f : 1.0f));
 
 
@@ -224,7 +224,7 @@ void Spinner::draw(Graphics *g) {
 
 
     // "CLEAR!"
     // "CLEAR!"
     if(m_fRatio >= 1.0f) {
     if(m_fRatio >= 1.0f) {
-        const float spinnerClearImageScale = Osu::getImageScale(m_beatmap->getOsu(), skin->getSpinnerClear(), 80);
+        const float spinnerClearImageScale = Osu::getImageScale(skin->getSpinnerClear(), 80);
 
 
         g->setColor(0xffffffff);
         g->setColor(0xffffffff);
         g->setAlpha(alphaMultiplier);
         g->setAlpha(alphaMultiplier);
@@ -239,7 +239,7 @@ void Spinner::draw(Graphics *g) {
 
 
     // "SPIN!"
     // "SPIN!"
     if(clampedRatio < 0.03f) {
     if(clampedRatio < 0.03f) {
-        const float spinerSpinImageScale = Osu::getImageScale(m_beatmap->getOsu(), skin->getSpinnerSpin(), 80);
+        const float spinerSpinImageScale = Osu::getImageScale(skin->getSpinnerSpin(), 80);
 
 
         g->setColor(0xffffffff);
         g->setColor(0xffffffff);
         g->setAlpha(m_fAlphaWithoutHidden * alphaMultiplier);
         g->setAlpha(m_fAlphaWithoutHidden * alphaMultiplier);
@@ -260,9 +260,9 @@ void Spinner::draw(Graphics *g) {
         g->setAlpha(m_fAlphaWithoutHidden * m_fAlphaWithoutHidden * m_fAlphaWithoutHidden * alphaMultiplier);
         g->setAlpha(m_fAlphaWithoutHidden * m_fAlphaWithoutHidden * m_fAlphaWithoutHidden * alphaMultiplier);
         g->pushTransform();
         g->pushTransform();
         {
         {
-            g->translate((int)(m_beatmap->getOsu()->getScreenWidth() / 2 - stringWidth / 2),
-                         (int)(m_beatmap->getOsu()->getScreenHeight() - 5 +
-                               (5 + rpmFont->getHeight()) * (1.0f - m_fAlphaWithoutHidden)));
+            g->translate(
+                (int)(osu->getScreenWidth() / 2 - stringWidth / 2),
+                (int)(osu->getScreenHeight() - 5 + (5 + rpmFont->getHeight()) * (1.0f - m_fAlphaWithoutHidden)));
             g->drawString(rpmFont, UString::format("RPM: %i", (int)(m_fRPM + 0.4f)));
             g->drawString(rpmFont, UString::format("RPM: %i", (int)(m_fRPM + 0.4f)));
         }
         }
         g->popTransform();
         g->popTransform();
@@ -301,9 +301,8 @@ void Spinner::update(long curPos) {
 
 
         // handle auto, mouse spinning movement
         // handle auto, mouse spinning movement
         float angleDiff = 0;
         float angleDiff = 0;
-        if(m_beatmap->getOsu()->getModAuto() || m_beatmap->getOsu()->getModAutopilot() ||
-           m_beatmap->getOsu()->getModSpunout())
-            angleDiff = engine->getFrameTime() * 1000.0f * AUTO_MULTIPLIER * m_beatmap->getOsu()->getSpeedMultiplier();
+        if(osu->getModAuto() || osu->getModAutopilot() || osu->getModSpunout())
+            angleDiff = engine->getFrameTime() * 1000.0f * AUTO_MULTIPLIER * osu->getSpeedMultiplier();
         else  // user spin
         else  // user spin
         {
         {
             Vector2 mouseDelta = m_beatmap->getCursorPos() - m_beatmap->osuCoords2Pixels(m_vRawPos);
             Vector2 mouseDelta = m_beatmap->getCursorPos() - m_beatmap->osuCoords2Pixels(m_vRawPos);
@@ -319,8 +318,8 @@ void Spinner::update(long curPos) {
         // handle spinning
         // handle spinning
         // HACKHACK: rewrite this
         // HACKHACK: rewrite this
         if(delta <= 0) {
         if(delta <= 0) {
-            bool isSpinning = m_beatmap->isClickHeld() || m_beatmap->getOsu()->getModAuto() ||
-                              m_beatmap->getOsu()->getModRelax() || m_beatmap->getOsu()->getModSpunout();
+            bool isSpinning =
+                m_beatmap->isClickHeld() || osu->getModAuto() || osu->getModRelax() || osu->getModSpunout();
 
 
             m_fDeltaOverflow += engine->getFrameTime() * 1000.0f;
             m_fDeltaOverflow += engine->getFrameTime() * 1000.0f;
 
 
@@ -419,7 +418,7 @@ void Spinner::onHit() {
 
 
     // calculate hit result
     // calculate hit result
     LiveScore::HIT result = LiveScore::HIT::HIT_NULL;
     LiveScore::HIT result = LiveScore::HIT::HIT_NULL;
-    if(m_fRatio >= 1.0f || m_beatmap->getOsu()->getModAuto())
+    if(m_fRatio >= 1.0f || osu->getModAuto())
         result = LiveScore::HIT::HIT_300;
         result = LiveScore::HIT::HIT_300;
     else if(m_fRatio >= 0.9f && !GameRules::osu_mod_ming3012.getBool() && !GameRules::osu_mod_no100s.getBool())
     else if(m_fRatio >= 0.9f && !GameRules::osu_mod_ming3012.getBool() && !GameRules::osu_mod_no100s.getBool())
         result = LiveScore::HIT::HIT_100;
         result = LiveScore::HIT::HIT_100;
@@ -493,8 +492,7 @@ Vector2 Spinner::getAutoCursorPos(long curPos) {
 
 
     Vector2 actualPos = m_beatmap->osuCoords2Pixels(m_vRawPos);
     Vector2 actualPos = m_beatmap->osuCoords2Pixels(m_vRawPos);
     const float AUTO_MULTIPLIER = (1.0f / 20.0f);
     const float AUTO_MULTIPLIER = (1.0f / 20.0f);
-    float multiplier =
-        (m_beatmap->getOsu()->getModAuto() || m_beatmap->getOsu()->getModAutopilot()) ? AUTO_MULTIPLIER : 1.0f;
+    float multiplier = (osu->getModAuto() || osu->getModAutopilot()) ? AUTO_MULTIPLIER : 1.0f;
     float angle = (delta * multiplier) - PI / 2.0f;
     float angle = (delta * multiplier) - PI / 2.0f;
     float r = m_beatmap->getPlayfieldSize().y / 10.0f;
     float r = m_beatmap->getPlayfieldSize().y / 10.0f;
     return Vector2((float)(actualPos.x + r * std::cos(angle)), (float)(actualPos.y + r * std::sin(angle)));
     return Vector2((float)(actualPos.x + r * std::cos(angle)), (float)(actualPos.y + r * std::sin(angle)));

+ 6 - 6
src/App/Osu/TooltipOverlay.cpp

@@ -16,7 +16,7 @@
 
 
 ConVar osu_tooltip_anim_duration("osu_tooltip_anim_duration", 0.4f, FCVAR_DEFAULT);
 ConVar osu_tooltip_anim_duration("osu_tooltip_anim_duration", 0.4f, FCVAR_DEFAULT);
 
 
-TooltipOverlay::TooltipOverlay(Osu *osu) : OsuScreen(osu) {
+TooltipOverlay::TooltipOverlay() : OsuScreen() {
     m_fAnim = 0.0f;
     m_fAnim = 0.0f;
     m_bDelayFadeout = false;
     m_bDelayFadeout = false;
 }
 }
@@ -25,7 +25,7 @@ TooltipOverlay::~TooltipOverlay() {}
 
 
 void TooltipOverlay::draw(Graphics *g) {
 void TooltipOverlay::draw(Graphics *g) {
     if(m_fAnim > 0.0f) {
     if(m_fAnim > 0.0f) {
-        const float dpiScale = Osu::getUIScale(m_osu);
+        const float dpiScale = Osu::getUIScale();
 
 
         McFont *font = engine->getResourceManager()->getFont("FONT_DEFAULT");
         McFont *font = engine->getResourceManager()->getFont("FONT_DEFAULT");
 
 
@@ -44,12 +44,12 @@ void TooltipOverlay::draw(Graphics *g) {
         Vector2 cursorPos = engine->getMouse()->getPos();
         Vector2 cursorPos = engine->getMouse()->getPos();
 
 
         // clamp to right edge
         // clamp to right edge
-        if(cursorPos.x + width + offset.x + 2 * margin > m_osu->getScreenWidth())
-            cursorPos.x -= (cursorPos.x + width + offset.x + 2 * margin) - m_osu->getScreenWidth() + 1;
+        if(cursorPos.x + width + offset.x + 2 * margin > osu->getScreenWidth())
+            cursorPos.x -= (cursorPos.x + width + offset.x + 2 * margin) - osu->getScreenWidth() + 1;
 
 
         // clamp to bottom edge
         // clamp to bottom edge
-        if(cursorPos.y + height + offset.y + 2 * margin > m_osu->getScreenHeight())
-            cursorPos.y -= (cursorPos.y + height + offset.y + 2 * margin) - m_osu->getScreenHeight() + 1;
+        if(cursorPos.y + height + offset.y + 2 * margin > osu->getScreenHeight())
+            cursorPos.y -= (cursorPos.y + height + offset.y + 2 * margin) - osu->getScreenHeight() + 1;
 
 
         // clamp to left edge
         // clamp to left edge
         if(cursorPos.x < 0) cursorPos.x += std::abs(cursorPos.x);
         if(cursorPos.x < 0) cursorPos.x += std::abs(cursorPos.x);

+ 2 - 15
src/App/Osu/TooltipOverlay.h

@@ -1,20 +1,9 @@
-//================ Copyright (c) 2016, PG, All rights reserved. =================//
-//
-// Purpose:		tooltips
-//
-// $NoKeywords: $osutt
-//===============================================================================//
-
-#ifndef OSUTOOLTIPOVERLAY_H
-#define OSUTOOLTIPOVERLAY_H
-
+#pragma once
 #include "OsuScreen.h"
 #include "OsuScreen.h"
 
 
-class Osu;
-
 class TooltipOverlay : public OsuScreen {
 class TooltipOverlay : public OsuScreen {
    public:
    public:
-    TooltipOverlay(Osu *osu);
+    TooltipOverlay();
     virtual ~TooltipOverlay();
     virtual ~TooltipOverlay();
 
 
     virtual void draw(Graphics *g);
     virtual void draw(Graphics *g);
@@ -30,5 +19,3 @@ class TooltipOverlay : public OsuScreen {
 
 
     bool m_bDelayFadeout;
     bool m_bDelayFadeout;
 };
 };
-
-#endif

+ 3 - 3
src/App/Osu/UIAvatar.cpp

@@ -89,7 +89,7 @@ void UIAvatar::draw_avatar(Graphics *g, float alpha) {
 
 
     if(avatar == nullptr) {
     if(avatar == nullptr) {
         // Don't download during gameplay to avoid lagspikes
         // Don't download during gameplay to avoid lagspikes
-        if(!bancho.osu->isInPlayMode()) {
+        if(!osu->isInPlayMode()) {
             if(download_avatar(m_player_id)) {
             if(download_avatar(m_player_id)) {
                 avatar = engine->getResourceManager()->loadImageAbs(avatar_path, avatar_path);
                 avatar = engine->getResourceManager()->loadImageAbs(avatar_path, avatar_path);
             }
             }
@@ -119,10 +119,10 @@ void UIAvatar::draw_avatar(Graphics *g, float alpha) {
 }
 }
 
 
 void UIAvatar::onAvatarClicked(CBaseUIButton *btn) {
 void UIAvatar::onAvatarClicked(CBaseUIButton *btn) {
-    if(bancho.osu->isInPlayMode()) {
+    if(osu->isInPlayMode()) {
         // Don't want context menu to pop up while playing a map
         // Don't want context menu to pop up while playing a map
         return;
         return;
     }
     }
 
 
-    bancho.osu->m_user_actions->open(m_player_id);
+    osu->m_user_actions->open(m_player_id);
 }
 }

+ 6 - 14
src/App/Osu/UIBackButton.cpp

@@ -1,10 +1,3 @@
-//================ Copyright (c) 2016, PG, All rights reserved. =================//
-//
-// Purpose:		big ass back button (options, songbrowser)
-//
-// $NoKeywords: $osubbt
-//===============================================================================//
-
 #include "UIBackButton.h"
 #include "UIBackButton.h"
 
 
 #include "AnimationHandler.h"
 #include "AnimationHandler.h"
@@ -14,9 +7,8 @@
 #include "Skin.h"
 #include "Skin.h"
 #include "SkinImage.h"
 #include "SkinImage.h"
 
 
-UIBackButton::UIBackButton(Osu *osu, float xPos, float yPos, float xSize, float ySize, UString name)
+UIBackButton::UIBackButton(float xPos, float yPos, float xSize, float ySize, UString name)
     : CBaseUIButton(xPos, yPos, xSize, ySize, name, "") {
     : CBaseUIButton(xPos, yPos, xSize, ySize, name, "") {
-    m_osu = osu;
     m_fAnimation = 0.0f;
     m_fAnimation = 0.0f;
     m_fImageScale = 1.0f;
     m_fImageScale = 1.0f;
 }
 }
@@ -33,8 +25,8 @@ void UIBackButton::draw(Graphics *g) {
         g->scale((1.0f + m_fAnimation * scaleAnimMultiplier), (1.0f + m_fAnimation * scaleAnimMultiplier));
         g->scale((1.0f + m_fAnimation * scaleAnimMultiplier), (1.0f + m_fAnimation * scaleAnimMultiplier));
         g->translate(-m_vSize.x / 2, m_vSize.y / 2);
         g->translate(-m_vSize.x / 2, m_vSize.y / 2);
         g->setColor(0xffffffff);
         g->setColor(0xffffffff);
-        m_osu->getSkin()->getMenuBack2()->draw(
-            g, m_vPos + (m_osu->getSkin()->getMenuBack2()->getSize() / 2) * m_fImageScale, m_fImageScale);
+        osu->getSkin()->getMenuBack2()->draw(
+            g, m_vPos + (osu->getSkin()->getMenuBack2()->getSize() / 2) * m_fImageScale, m_fImageScale);
     }
     }
     g->popTransform();
     g->popTransform();
 
 
@@ -74,12 +66,12 @@ void UIBackButton::onMouseOutside() {
 void UIBackButton::updateLayout() {
 void UIBackButton::updateLayout() {
     const float uiScale = Osu::ui_scale->getFloat();
     const float uiScale = Osu::ui_scale->getFloat();
 
 
-    Vector2 newSize = m_osu->getSkin()->getMenuBack2()->getSize();
+    Vector2 newSize = osu->getSkin()->getMenuBack2()->getSize();
     newSize.y = clamp<float>(newSize.y, 0,
     newSize.y = clamp<float>(newSize.y, 0,
-                             m_osu->getSkin()->getMenuBack2()->getSizeBase().y *
+                             osu->getSkin()->getMenuBack2()->getSizeBase().y *
                                  1.5f);  // clamp the height down if it exceeds 1.5x the base height
                                  1.5f);  // clamp the height down if it exceeds 1.5x the base height
     newSize *= uiScale;
     newSize *= uiScale;
-    m_fImageScale = (newSize.y / m_osu->getSkin()->getMenuBack2()->getSize().y);
+    m_fImageScale = (newSize.y / osu->getSkin()->getMenuBack2()->getSize().y);
     setSize(newSize);
     setSize(newSize);
 }
 }
 
 

+ 2 - 15
src/App/Osu/UIBackButton.h

@@ -1,20 +1,9 @@
-//================ Copyright (c) 2016, PG, All rights reserved. =================//
-//
-// Purpose:		big ass back button (options, songbrowser)
-//
-// $NoKeywords: $osubbt
-//===============================================================================//
-
-#ifndef OSUUIBACKBUTTON_H
-#define OSUUIBACKBUTTON_H
-
+#pragma once
 #include "CBaseUIButton.h"
 #include "CBaseUIButton.h"
 
 
-class Osu;
-
 class UIBackButton : public CBaseUIButton {
 class UIBackButton : public CBaseUIButton {
    public:
    public:
-    UIBackButton(Osu *osu, float xPos, float yPos, float xSize, float ySize, UString name);
+    UIBackButton(float xPos, float yPos, float xSize, float ySize, UString name);
 
 
     virtual void draw(Graphics *g);
     virtual void draw(Graphics *g);
     virtual void mouse_update(bool *propagate_clicks);
     virtual void mouse_update(bool *propagate_clicks);
@@ -27,8 +16,6 @@ class UIBackButton : public CBaseUIButton {
     void resetAnimation();
     void resetAnimation();
 
 
    private:
    private:
-    Osu *m_osu;
     float m_fAnimation;
     float m_fAnimation;
     float m_fImageScale;
     float m_fImageScale;
 };
 };
-#endif

+ 11 - 22
src/App/Osu/UIButton.cpp

@@ -1,10 +1,3 @@
-//================ Copyright (c) 2016, PG, All rights reserved. =================//
-//
-// Purpose:		generic button (context menu items, mod selection screen, etc.)
-//
-// $NoKeywords: $osubt
-//===============================================================================//
-
 #include "UIButton.h"
 #include "UIButton.h"
 
 
 #include "AnimationHandler.h"
 #include "AnimationHandler.h"
@@ -14,10 +7,8 @@
 #include "Skin.h"
 #include "Skin.h"
 #include "TooltipOverlay.h"
 #include "TooltipOverlay.h"
 
 
-UIButton::UIButton(Osu *osu, float xPos, float yPos, float xSize, float ySize, UString name, UString text)
+UIButton::UIButton(float xPos, float yPos, float xSize, float ySize, UString name, UString text)
     : CBaseUIButton(xPos, yPos, xSize, ySize, name, text) {
     : CBaseUIButton(xPos, yPos, xSize, ySize, name, text) {
-    m_osu = osu;
-
     m_bDefaultSkin = false;
     m_bDefaultSkin = false;
     m_color = 0xffffffff;
     m_color = 0xffffffff;
     m_backupColor = m_color;
     m_backupColor = m_color;
@@ -31,16 +22,14 @@ UIButton::UIButton(Osu *osu, float xPos, float yPos, float xSize, float ySize, U
 void UIButton::draw(Graphics *g) {
 void UIButton::draw(Graphics *g) {
     if(!m_bVisible) return;
     if(!m_bVisible) return;
 
 
-    Image *buttonLeft = m_bDefaultSkin ? m_osu->getSkin()->getDefaultButtonLeft() : m_osu->getSkin()->getButtonLeft();
-    Image *buttonMiddle =
-        m_bDefaultSkin ? m_osu->getSkin()->getDefaultButtonMiddle() : m_osu->getSkin()->getButtonMiddle();
-    Image *buttonRight =
-        m_bDefaultSkin ? m_osu->getSkin()->getDefaultButtonRight() : m_osu->getSkin()->getButtonRight();
+    Image *buttonLeft = m_bDefaultSkin ? osu->getSkin()->getDefaultButtonLeft() : osu->getSkin()->getButtonLeft();
+    Image *buttonMiddle = m_bDefaultSkin ? osu->getSkin()->getDefaultButtonMiddle() : osu->getSkin()->getButtonMiddle();
+    Image *buttonRight = m_bDefaultSkin ? osu->getSkin()->getDefaultButtonRight() : osu->getSkin()->getButtonRight();
 
 
-    float leftScale = m_osu->getImageScaleToFitResolution(buttonLeft, m_vSize);
+    float leftScale = osu->getImageScaleToFitResolution(buttonLeft, m_vSize);
     float leftWidth = buttonLeft->getWidth() * leftScale;
     float leftWidth = buttonLeft->getWidth() * leftScale;
 
 
-    float rightScale = m_osu->getImageScaleToFitResolution(buttonRight, m_vSize);
+    float rightScale = osu->getImageScaleToFitResolution(buttonRight, m_vSize);
     float rightWidth = buttonRight->getWidth() * rightScale;
     float rightWidth = buttonRight->getWidth() * rightScale;
 
 
     float middleWidth = m_vSize.x - leftWidth - rightWidth;
     float middleWidth = m_vSize.x - leftWidth - rightWidth;
@@ -66,13 +55,13 @@ void UIButton::draw(Graphics *g) {
     buttonRight->unbind();
     buttonRight->unbind();
 
 
     if(is_loading) {
     if(is_loading) {
-        const float scale = (m_vSize.y * 0.8) / m_osu->getSkin()->getLoadingSpinner()->getSize().y;
+        const float scale = (m_vSize.y * 0.8) / osu->getSkin()->getLoadingSpinner()->getSize().y;
         g->setColor(0xffffffff);
         g->setColor(0xffffffff);
         g->pushTransform();
         g->pushTransform();
         g->rotate(engine->getTime() * 180, 0, 0, 1);
         g->rotate(engine->getTime() * 180, 0, 0, 1);
         g->scale(scale, scale);
         g->scale(scale, scale);
         g->translate(m_vPos.x + m_vSize.x / 2.0f, m_vPos.y + m_vSize.y / 2.0f);
         g->translate(m_vPos.x + m_vSize.x / 2.0f, m_vPos.y + m_vSize.y / 2.0f);
-        g->drawImage(m_osu->getSkin()->getLoadingSpinner());
+        g->drawImage(osu->getSkin()->getLoadingSpinner());
         g->popTransform();
         g->popTransform();
     } else {
     } else {
         drawText(g);
         drawText(g);
@@ -84,13 +73,13 @@ void UIButton::mouse_update(bool *propagate_clicks) {
     CBaseUIButton::mouse_update(propagate_clicks);
     CBaseUIButton::mouse_update(propagate_clicks);
 
 
     if(isMouseInside() && m_tooltipTextLines.size() > 0 && !m_bFocusStolenDelay) {
     if(isMouseInside() && m_tooltipTextLines.size() > 0 && !m_bFocusStolenDelay) {
-        m_osu->getTooltipOverlay()->begin();
+        osu->getTooltipOverlay()->begin();
         {
         {
             for(int i = 0; i < m_tooltipTextLines.size(); i++) {
             for(int i = 0; i < m_tooltipTextLines.size(); i++) {
-                m_osu->getTooltipOverlay()->addLine(m_tooltipTextLines[i]);
+                osu->getTooltipOverlay()->addLine(m_tooltipTextLines[i]);
             }
             }
         }
         }
-        m_osu->getTooltipOverlay()->end();
+        osu->getTooltipOverlay()->end();
     }
     }
 
 
     m_bFocusStolenDelay = false;
     m_bFocusStolenDelay = false;

+ 2 - 17
src/App/Osu/UIButton.h

@@ -1,20 +1,9 @@
-//================ Copyright (c) 2016, PG, All rights reserved. =================//
-//
-// Purpose:		generic button (context menu items, mod selection screen, etc.)
-//
-// $NoKeywords: $osubt
-//===============================================================================//
-
-#ifndef OSUBUTTON_H
-#define OSUBUTTON_H
-
+#pragma once
 #include "CBaseUIButton.h"
 #include "CBaseUIButton.h"
 
 
-class Osu;
-
 class UIButton : public CBaseUIButton {
 class UIButton : public CBaseUIButton {
    public:
    public:
-    UIButton(Osu *osu, float xPos, float yPos, float xSize, float ySize, UString name, UString text);
+    UIButton(float xPos, float yPos, float xSize, float ySize, UString name, UString text);
 
 
     virtual void draw(Graphics *g);
     virtual void draw(Graphics *g);
     virtual void mouse_update(bool *propagate_clicks);
     virtual void mouse_update(bool *propagate_clicks);
@@ -38,8 +27,6 @@ class UIButton : public CBaseUIButton {
     virtual void onClicked();
     virtual void onClicked();
     virtual void onFocusStolen();
     virtual void onFocusStolen();
 
 
-    Osu *m_osu;
-
     bool m_bDefaultSkin;
     bool m_bDefaultSkin;
     Color m_color;
     Color m_color;
     Color m_backupColor;
     Color m_backupColor;
@@ -50,5 +37,3 @@ class UIButton : public CBaseUIButton {
     std::vector<UString> m_tooltipTextLines;
     std::vector<UString> m_tooltipTextLines;
     bool m_bFocusStolenDelay;
     bool m_bFocusStolenDelay;
 };
 };
-
-#endif

+ 4 - 13
src/App/Osu/UICheckbox.cpp

@@ -1,20 +1,11 @@
-//================ Copyright (c) 2016, PG, All rights reserved. =================//
-//
-// Purpose:		generic checkbox
-//
-// $NoKeywords: $osucb
-//===============================================================================//
-
 #include "UICheckbox.h"
 #include "UICheckbox.h"
 
 
 #include "Engine.h"
 #include "Engine.h"
 #include "Osu.h"
 #include "Osu.h"
 #include "TooltipOverlay.h"
 #include "TooltipOverlay.h"
 
 
-UICheckbox::UICheckbox(Osu *osu, float xPos, float yPos, float xSize, float ySize, UString name, UString text)
+UICheckbox::UICheckbox(float xPos, float yPos, float xSize, float ySize, UString name, UString text)
     : CBaseUICheckbox(xPos, yPos, xSize, ySize, name, text) {
     : CBaseUICheckbox(xPos, yPos, xSize, ySize, name, text) {
-    m_osu = osu;
-
     m_bFocusStolenDelay = false;
     m_bFocusStolenDelay = false;
 }
 }
 
 
@@ -23,13 +14,13 @@ void UICheckbox::mouse_update(bool *propagate_clicks) {
     CBaseUICheckbox::mouse_update(propagate_clicks);
     CBaseUICheckbox::mouse_update(propagate_clicks);
 
 
     if(isMouseInside() && m_tooltipTextLines.size() > 0 && !m_bFocusStolenDelay) {
     if(isMouseInside() && m_tooltipTextLines.size() > 0 && !m_bFocusStolenDelay) {
-        m_osu->getTooltipOverlay()->begin();
+        osu->getTooltipOverlay()->begin();
         {
         {
             for(int i = 0; i < m_tooltipTextLines.size(); i++) {
             for(int i = 0; i < m_tooltipTextLines.size(); i++) {
-                m_osu->getTooltipOverlay()->addLine(m_tooltipTextLines[i]);
+                osu->getTooltipOverlay()->addLine(m_tooltipTextLines[i]);
             }
             }
         }
         }
-        m_osu->getTooltipOverlay()->end();
+        osu->getTooltipOverlay()->end();
     }
     }
 
 
     m_bFocusStolenDelay = false;
     m_bFocusStolenDelay = false;

+ 2 - 16
src/App/Osu/UICheckbox.h

@@ -1,20 +1,9 @@
-//================ Copyright (c) 2016, PG, All rights reserved. =================//
-//
-// Purpose:		generic checkbox
-//
-// $NoKeywords: $osucb
-//===============================================================================//
-
-#ifndef OSUUICHECKBOX_H
-#define OSUUICHECKBOX_H
-
+#pragma once
 #include "CBaseUICheckbox.h"
 #include "CBaseUICheckbox.h"
 
 
-class Osu;
-
 class UICheckbox : public CBaseUICheckbox {
 class UICheckbox : public CBaseUICheckbox {
    public:
    public:
-    UICheckbox(Osu *osu, float xPos, float yPos, float xSize, float ySize, UString name, UString text);
+    UICheckbox(float xPos, float yPos, float xSize, float ySize, UString name, UString text);
 
 
     virtual void mouse_update(bool *propagate_clicks);
     virtual void mouse_update(bool *propagate_clicks);
 
 
@@ -23,10 +12,7 @@ class UICheckbox : public CBaseUICheckbox {
    private:
    private:
     virtual void onFocusStolen();
     virtual void onFocusStolen();
 
 
-    Osu *m_osu;
     std::vector<UString> m_tooltipTextLines;
     std::vector<UString> m_tooltipTextLines;
 
 
     bool m_bFocusStolenDelay;
     bool m_bFocusStolenDelay;
 };
 };
-
-#endif

+ 21 - 31
src/App/Osu/UIContextMenu.cpp

@@ -1,10 +1,3 @@
-//================ Copyright (c) 2016, PG, All rights reserved. =================//
-//
-// Purpose:		context menu, dropdown style
-//
-// $NoKeywords: $
-//===============================================================================//
-
 #include "UIContextMenu.h"
 #include "UIContextMenu.h"
 
 
 #include "AnimationHandler.h"
 #include "AnimationHandler.h"
@@ -17,10 +10,9 @@
 #include "Osu.h"
 #include "Osu.h"
 #include "TooltipOverlay.h"
 #include "TooltipOverlay.h"
 
 
-UIContextMenuButton::UIContextMenuButton(Osu *osu, float xPos, float yPos, float xSize, float ySize, UString name,
-                                         UString text, int id)
+UIContextMenuButton::UIContextMenuButton(float xPos, float yPos, float xSize, float ySize, UString name, UString text,
+                                         int id)
     : CBaseUIButton(xPos, yPos, xSize, ySize, name, text) {
     : CBaseUIButton(xPos, yPos, xSize, ySize, name, text) {
-    m_osu = osu;
     m_iID = id;
     m_iID = id;
 }
 }
 
 
@@ -29,13 +21,13 @@ void UIContextMenuButton::mouse_update(bool *propagate_clicks) {
     CBaseUIButton::mouse_update(propagate_clicks);
     CBaseUIButton::mouse_update(propagate_clicks);
 
 
     if(isMouseInside() && m_tooltipTextLines.size() > 0) {
     if(isMouseInside() && m_tooltipTextLines.size() > 0) {
-        m_osu->getTooltipOverlay()->begin();
+        osu->getTooltipOverlay()->begin();
         {
         {
             for(int i = 0; i < m_tooltipTextLines.size(); i++) {
             for(int i = 0; i < m_tooltipTextLines.size(); i++) {
-                m_osu->getTooltipOverlay()->addLine(m_tooltipTextLines[i]);
+                osu->getTooltipOverlay()->addLine(m_tooltipTextLines[i]);
             }
             }
         }
         }
-        m_osu->getTooltipOverlay()->end();
+        osu->getTooltipOverlay()->end();
     }
     }
 }
 }
 
 
@@ -46,10 +38,8 @@ UIContextMenuTextbox::UIContextMenuTextbox(float xPos, float yPos, float xSize,
     m_iID = id;
     m_iID = id;
 }
 }
 
 
-UIContextMenu::UIContextMenu(Osu *osu, float xPos, float yPos, float xSize, float ySize, UString name,
-                             CBaseUIScrollView *parent)
+UIContextMenu::UIContextMenu(float xPos, float yPos, float xSize, float ySize, UString name, CBaseUIScrollView *parent)
     : CBaseUIScrollView(xPos, yPos, xSize, ySize, name) {
     : CBaseUIScrollView(xPos, yPos, xSize, ySize, name) {
-    m_osu = osu;
     m_parent = parent;
     m_parent = parent;
 
 
     setPos(xPos, yPos);
     setPos(xPos, yPos);
@@ -185,16 +175,16 @@ void UIContextMenu::begin(int minWidth, bool bigStyle) {
 }
 }
 
 
 UIContextMenuButton *UIContextMenu::addButton(UString text, int id) {
 UIContextMenuButton *UIContextMenu::addButton(UString text, int id) {
-    const int buttonHeight = 30 * Osu::getUIScale(m_osu) * (m_bBigStyle ? 1.27f : 1.0f);
-    const int margin = 9 * Osu::getUIScale(m_osu);
+    const int buttonHeight = 30 * Osu::getUIScale() * (m_bBigStyle ? 1.27f : 1.0f);
+    const int margin = 9 * Osu::getUIScale();
 
 
     UIContextMenuButton *button =
     UIContextMenuButton *button =
-        new UIContextMenuButton(m_osu, margin, m_iYCounter + margin, 0, buttonHeight, text, text, id);
+        new UIContextMenuButton(margin, m_iYCounter + margin, 0, buttonHeight, text, text, id);
     {
     {
-        if(m_bBigStyle) button->setFont(m_osu->getSubTitleFont());
+        if(m_bBigStyle) button->setFont(osu->getSubTitleFont());
 
 
         button->setClickCallback(fastdelegate::MakeDelegate(this, &UIContextMenu::onClick));
         button->setClickCallback(fastdelegate::MakeDelegate(this, &UIContextMenu::onClick));
-        button->setWidthToContent(3 * Osu::getUIScale(m_osu));
+        button->setWidthToContent(3 * Osu::getUIScale());
         button->setTextLeft(true);
         button->setTextLeft(true);
         button->setDrawFrame(false);
         button->setDrawFrame(false);
         button->setDrawBackground(false);
         button->setDrawBackground(false);
@@ -213,14 +203,14 @@ UIContextMenuButton *UIContextMenu::addButton(UString text, int id) {
 }
 }
 
 
 UIContextMenuTextbox *UIContextMenu::addTextbox(UString text, int id) {
 UIContextMenuTextbox *UIContextMenu::addTextbox(UString text, int id) {
-    const int buttonHeight = 30 * Osu::getUIScale(m_osu) * (m_bBigStyle ? 1.27f : 1.0f);
-    const int margin = 9 * Osu::getUIScale(m_osu);
+    const int buttonHeight = 30 * Osu::getUIScale() * (m_bBigStyle ? 1.27f : 1.0f);
+    const int margin = 9 * Osu::getUIScale();
 
 
     UIContextMenuTextbox *textbox = new UIContextMenuTextbox(margin, m_iYCounter + margin, 0, buttonHeight, text, id);
     UIContextMenuTextbox *textbox = new UIContextMenuTextbox(margin, m_iYCounter + margin, 0, buttonHeight, text, id);
     {
     {
         textbox->setText(text);
         textbox->setText(text);
 
 
-        if(m_bBigStyle) textbox->setFont(m_osu->getSubTitleFont());
+        if(m_bBigStyle) textbox->setFont(osu->getSubTitleFont());
 
 
         textbox->setActive(true);
         textbox->setActive(true);
     }
     }
@@ -239,7 +229,7 @@ void UIContextMenu::end(bool invertAnimation, bool clampUnderflowAndOverflowAndE
     m_bInvertAnimation = invertAnimation;
     m_bInvertAnimation = invertAnimation;
     m_bClampUnderflowAndOverflowAndEnableScrollingIfNecessary = clampUnderflowAndOverflowAndEnableScrollingIfNecessary;
     m_bClampUnderflowAndOverflowAndEnableScrollingIfNecessary = clampUnderflowAndOverflowAndEnableScrollingIfNecessary;
 
 
-    const int margin = 9 * Osu::getUIScale(m_osu);
+    const int margin = 9 * Osu::getUIScale();
 
 
     const std::vector<CBaseUIElement *> &elements = getContainer()->getElements();
     const std::vector<CBaseUIElement *> &elements = getContainer()->getElements();
     for(size_t i = 0; i < elements.size(); i++) {
     for(size_t i = 0; i < elements.size(); i++) {
@@ -261,8 +251,8 @@ void UIContextMenu::end(bool invertAnimation, bool clampUnderflowAndOverflowAndE
                 setVerticalScrolling(true);
                 setVerticalScrolling(true);
             }
             }
 
 
-            if(m_vPos.y + m_vSize.y > m_osu->getScreenHeight()) {
-                const float overflow = std::abs(m_vPos.y + m_vSize.y - m_osu->getScreenHeight());
+            if(m_vPos.y + m_vSize.y > osu->getScreenHeight()) {
+                const float overflow = std::abs(m_vPos.y + m_vSize.y - osu->getScreenHeight());
 
 
                 setSizeY(m_vSize.y - overflow - 1);
                 setSizeY(m_vSize.y - overflow - 1);
 
 
@@ -315,16 +305,16 @@ void UIContextMenu::onHitEnter(UIContextMenuTextbox *textbox) {
 }
 }
 
 
 void UIContextMenu::clampToBottomScreenEdge(UIContextMenu *menu) {
 void UIContextMenu::clampToBottomScreenEdge(UIContextMenu *menu) {
-    if(menu->getRelPos().y + menu->getSize().y > menu->m_osu->getScreenHeight()) {
-        int newRelPosY = menu->m_osu->getScreenHeight() - menu->getSize().y - 1;
+    if(menu->getRelPos().y + menu->getSize().y > osu->getScreenHeight()) {
+        int newRelPosY = osu->getScreenHeight() - menu->getSize().y - 1;
         menu->setRelPosY(newRelPosY);
         menu->setRelPosY(newRelPosY);
         menu->setPosY(newRelPosY);
         menu->setPosY(newRelPosY);
     }
     }
 }
 }
 
 
 void UIContextMenu::clampToRightScreenEdge(UIContextMenu *menu) {
 void UIContextMenu::clampToRightScreenEdge(UIContextMenu *menu) {
-    if(menu->getRelPos().x + menu->getSize().x > menu->m_osu->getScreenWidth()) {
-        const int newRelPosX = menu->m_osu->getScreenWidth() - menu->getSize().x - 1;
+    if(menu->getRelPos().x + menu->getSize().x > osu->getScreenWidth()) {
+        const int newRelPosX = osu->getScreenWidth() - menu->getSize().x - 1;
         menu->setRelPosX(newRelPosX);
         menu->setRelPosX(newRelPosX);
         menu->setPosX(newRelPosX);
         menu->setPosX(newRelPosX);
     }
     }

+ 3 - 20
src/App/Osu/UIContextMenu.h

@@ -1,21 +1,10 @@
-//================ Copyright (c) 2016, PG, All rights reserved. =================//
-//
-// Purpose:		context menu, dropdown style
-//
-// $NoKeywords: $
-//===============================================================================//
-
-#ifndef OSUUICONTEXTMENU_H
-#define OSUUICONTEXTMENU_H
-
+#pragma once
 #include "CBaseUIButton.h"
 #include "CBaseUIButton.h"
 #include "CBaseUIScrollView.h"
 #include "CBaseUIScrollView.h"
 #include "CBaseUITextbox.h"
 #include "CBaseUITextbox.h"
 
 
 class CBaseUIContainer;
 class CBaseUIContainer;
 
 
-class Osu;
-
 class UIContextMenuButton;
 class UIContextMenuButton;
 class UIContextMenuTextbox;
 class UIContextMenuTextbox;
 
 
@@ -25,7 +14,7 @@ class UIContextMenu : public CBaseUIScrollView {
     static void clampToRightScreenEdge(UIContextMenu *menu);
     static void clampToRightScreenEdge(UIContextMenu *menu);
 
 
    public:
    public:
-    UIContextMenu(Osu *osu, float xPos = 0, float yPos = 0, float xSize = 0, float ySize = 0, UString name = "",
+    UIContextMenu(float xPos = 0, float yPos = 0, float xSize = 0, float ySize = 0, UString name = "",
                   CBaseUIScrollView *parent = NULL);
                   CBaseUIScrollView *parent = NULL);
 
 
     virtual void draw(Graphics *g);
     virtual void draw(Graphics *g);
@@ -56,8 +45,6 @@ class UIContextMenu : public CBaseUIScrollView {
     void onClick(CBaseUIButton *button);
     void onClick(CBaseUIButton *button);
     void onHitEnter(UIContextMenuTextbox *textbox);
     void onHitEnter(UIContextMenuTextbox *textbox);
 
 
-    Osu *m_osu;
-
     CBaseUIScrollView *m_parent;
     CBaseUIScrollView *m_parent;
 
 
     UIContextMenuTextbox *m_containedTextbox;
     UIContextMenuTextbox *m_containedTextbox;
@@ -79,7 +66,7 @@ class UIContextMenu : public CBaseUIScrollView {
 
 
 class UIContextMenuButton : public CBaseUIButton {
 class UIContextMenuButton : public CBaseUIButton {
    public:
    public:
-    UIContextMenuButton(Osu *osu, float xPos, float yPos, float xSize, float ySize, UString name, UString text, int id);
+    UIContextMenuButton(float xPos, float yPos, float xSize, float ySize, UString name, UString text, int id);
     virtual ~UIContextMenuButton() { ; }
     virtual ~UIContextMenuButton() { ; }
 
 
     virtual void mouse_update(bool *propagate_clicks);
     virtual void mouse_update(bool *propagate_clicks);
@@ -89,8 +76,6 @@ class UIContextMenuButton : public CBaseUIButton {
     void setTooltipText(UString text);
     void setTooltipText(UString text);
 
 
    private:
    private:
-    Osu *m_osu;
-
     int m_iID;
     int m_iID;
 
 
     std::vector<UString> m_tooltipTextLines;
     std::vector<UString> m_tooltipTextLines;
@@ -106,5 +91,3 @@ class UIContextMenuTextbox : public CBaseUITextbox {
    private:
    private:
     int m_iID;
     int m_iID;
 };
 };
-
-#endif

+ 12 - 20
src/App/Osu/UIModSelectorModButton.cpp

@@ -1,10 +1,3 @@
-//================ Copyright (c) 2016, PG, All rights reserved. =================//
-//
-// Purpose:		mod image buttons (EZ, HD, HR, HT, DT, etc.)
-//
-// $NoKeywords: $osumsmb
-//===============================================================================//
-
 #include "UIModSelectorModButton.h"
 #include "UIModSelectorModButton.h"
 
 
 #include "AnimationHandler.h"
 #include "AnimationHandler.h"
@@ -22,10 +15,9 @@
 #include "SoundEngine.h"
 #include "SoundEngine.h"
 #include "TooltipOverlay.h"
 #include "TooltipOverlay.h"
 
 
-UIModSelectorModButton::UIModSelectorModButton(Osu *osu, ModSelector *osuModSelector, float xPos, float yPos,
-                                               float xSize, float ySize, UString name)
+UIModSelectorModButton::UIModSelectorModButton(ModSelector *osuModSelector, float xPos, float yPos, float xSize,
+                                               float ySize, UString name)
     : CBaseUIButton(xPos, yPos, xSize, ySize, name, "") {
     : CBaseUIButton(xPos, yPos, xSize, ySize, name, "") {
-    m_osu = osu;
     m_osuModSelector = osuModSelector;
     m_osuModSelector = osuModSelector;
     m_iState = 0;
     m_iState = 0;
     m_vScale = m_vBaseScale = Vector2(1, 1);
     m_vScale = m_vBaseScale = Vector2(1, 1);
@@ -77,11 +69,11 @@ void UIModSelectorModButton::mouse_update(bool *propagate_clicks) {
 
 
     // handle tooltips
     // handle tooltips
     if(isMouseInside() && m_bAvailable && m_states.size() > 0 && !m_bFocusStolenDelay) {
     if(isMouseInside() && m_bAvailable && m_states.size() > 0 && !m_bFocusStolenDelay) {
-        m_osu->getTooltipOverlay()->begin();
+        osu->getTooltipOverlay()->begin();
         for(int i = 0; i < m_states[m_iState].tooltipTextLines.size(); i++) {
         for(int i = 0; i < m_states[m_iState].tooltipTextLines.size(); i++) {
-            m_osu->getTooltipOverlay()->addLine(m_states[m_iState].tooltipTextLines[i]);
+            osu->getTooltipOverlay()->addLine(m_states[m_iState].tooltipTextLines[i]);
         }
         }
-        m_osu->getTooltipOverlay()->end();
+        osu->getTooltipOverlay()->end();
     }
     }
 
 
     m_bFocusStolenDelay = false;
     m_bFocusStolenDelay = false;
@@ -141,7 +133,7 @@ void UIModSelectorModButton::onClicked() {
             write<u32>(&packet, bancho.room.slots[i].mods);
             write<u32>(&packet, bancho.room.slots[i].mods);
             send_packet(packet);
             send_packet(packet);
 
 
-            m_osu->m_room->on_room_updated(bancho.room);
+            osu->m_room->on_room_updated(bancho.room);
             break;
             break;
         }
         }
     }
     }
@@ -178,10 +170,10 @@ void UIModSelectorModButton::setOn(bool on, bool silent) {
     // Prevent DT and HT from being selected at the same time
     // Prevent DT and HT from being selected at the same time
     if(on && !silent && !m_states.empty()) {
     if(on && !silent && !m_states.empty()) {
         if(m_states[0].modName == UString("dt") || m_states[0].modName == UString("nc")) {
         if(m_states[0].modName == UString("dt") || m_states[0].modName == UString("nc")) {
-            m_osu->m_modSelector->m_modButtonHalftime->setOn(false, true);
+            osu->m_modSelector->m_modButtonHalftime->setOn(false, true);
             convar->getConVarByName("osu_speed_override")->setValue(-1.0f);
             convar->getConVarByName("osu_speed_override")->setValue(-1.0f);
         } else if(m_states[0].modName == UString("ht") || m_states[0].modName == UString("dc")) {
         } else if(m_states[0].modName == UString("ht") || m_states[0].modName == UString("dc")) {
-            m_osu->m_modSelector->m_modButtonDoubletime->setOn(false, true);
+            osu->m_modSelector->m_modButtonDoubletime->setOn(false, true);
             convar->getConVarByName("osu_speed_override")->setValue(-1.0f);
             convar->getConVarByName("osu_speed_override")->setValue(-1.0f);
         }
         }
     }
     }
@@ -209,7 +201,7 @@ void UIModSelectorModButton::setOn(bool on, bool silent) {
         }
         }
 
 
         if(!silent) {
         if(!silent) {
-            engine->getSound()->play(m_osu->getSkin()->getCheckOn());
+            engine->getSound()->play(osu->getSkin()->getCheckOn());
         }
         }
     } else {
     } else {
         anim->moveLinear(&m_fRot, 0.0f, animationDuration, true);
         anim->moveLinear(&m_fRot, 0.0f, animationDuration, true);
@@ -218,7 +210,7 @@ void UIModSelectorModButton::setOn(bool on, bool silent) {
 
 
         if(prevState && !m_bOn && !silent) {
         if(prevState && !m_bOn && !silent) {
             // only play sound on specific change
             // only play sound on specific change
-            engine->getSound()->play(m_osu->getSkin()->getCheckOff());
+            engine->getSound()->play(osu->getSkin()->getCheckOff());
         }
         }
     }
     }
 }
 }
@@ -235,9 +227,9 @@ void UIModSelectorModButton::setState(int state, bool updateModConVar) {
         // We want to sync "nightcore" status between both buttons
         // We want to sync "nightcore" status between both buttons
         if(!m_states.empty()) {
         if(!m_states.empty()) {
             if(m_states[0].modName == UString("dt") || m_states[0].modName == UString("nc")) {
             if(m_states[0].modName == UString("dt") || m_states[0].modName == UString("nc")) {
-                m_osu->m_modSelector->m_modButtonHalftime->setState(m_iState, false);
+                osu->m_modSelector->m_modButtonHalftime->setState(m_iState, false);
             } else if(m_states[0].modName == UString("ht") || m_states[0].modName == UString("dc")) {
             } else if(m_states[0].modName == UString("ht") || m_states[0].modName == UString("dc")) {
-                m_osu->m_modSelector->m_modButtonDoubletime->setState(m_iState, false);
+                osu->m_modSelector->m_modButtonDoubletime->setState(m_iState, false);
             }
             }
         }
         }
 
 

+ 2 - 16
src/App/Osu/UIModSelectorModButton.h

@@ -1,23 +1,12 @@
-//================ Copyright (c) 2016, PG, All rights reserved. =================//
-//
-// Purpose:		mod image buttons (EZ, HD, HR, HT, DT, etc.)
-//
-// $NoKeywords: $osumsmb
-//===============================================================================//
-
-#ifndef OSUUIMODSELECTORMODBUTTON_H
-#define OSUUIMODSELECTORMODBUTTON_H
-
+#pragma once
 #include "CBaseUIImageButton.h"
 #include "CBaseUIImageButton.h"
 
 
-class Osu;
 class SkinImage;
 class SkinImage;
 class ModSelector;
 class ModSelector;
 
 
 class UIModSelectorModButton : public CBaseUIButton {
 class UIModSelectorModButton : public CBaseUIButton {
    public:
    public:
-    UIModSelectorModButton(Osu *osu, ModSelector *osuModSelector, float xPos, float yPos, float xSize, float ySize,
-                           UString name);
+    UIModSelectorModButton(ModSelector *osuModSelector, float xPos, float yPos, float xSize, float ySize, UString name);
 
 
     virtual void draw(Graphics *g);
     virtual void draw(Graphics *g);
     virtual void mouse_update(bool *propagate_clicks);
     virtual void mouse_update(bool *propagate_clicks);
@@ -39,7 +28,6 @@ class UIModSelectorModButton : public CBaseUIButton {
    private:
    private:
     virtual void onFocusStolen();
     virtual void onFocusStolen();
 
 
-    Osu *m_osu;
     ModSelector *m_osuModSelector;
     ModSelector *m_osuModSelector;
 
 
     bool m_bOn;
     bool m_bOn;
@@ -62,5 +50,3 @@ class UIModSelectorModButton : public CBaseUIButton {
 
 
     bool m_bFocusStolenDelay;
     bool m_bFocusStolenDelay;
 };
 };
-
-#endif

+ 3 - 11
src/App/Osu/UIPauseMenuButton.cpp

@@ -1,10 +1,3 @@
-//================ Copyright (c) 2018, PG, All rights reserved. =================//
-//
-// Purpose:		pause menu button
-//
-// $NoKeywords: $
-//===============================================================================//
-
 #include "UIPauseMenuButton.h"
 #include "UIPauseMenuButton.h"
 
 
 #include "AnimationHandler.h"
 #include "AnimationHandler.h"
@@ -13,10 +6,9 @@
 #include "Skin.h"
 #include "Skin.h"
 #include "SoundEngine.h"
 #include "SoundEngine.h"
 
 
-UIPauseMenuButton::UIPauseMenuButton(Osu *osu, std::function<Image *()> getImageFunc, float xPos, float yPos,
-                                     float xSize, float ySize, UString name)
+UIPauseMenuButton::UIPauseMenuButton(std::function<Image *()> getImageFunc, float xPos, float yPos, float xSize,
+                                     float ySize, UString name)
     : CBaseUIButton(xPos, yPos, xSize, ySize, name) {
     : CBaseUIButton(xPos, yPos, xSize, ySize, name) {
-    m_osu = osu;
     this->getImageFunc = getImageFunc;
     this->getImageFunc = getImageFunc;
 
 
     m_vScale = Vector2(1, 1);
     m_vScale = Vector2(1, 1);
@@ -55,7 +47,7 @@ void UIPauseMenuButton::setBaseScale(float xScale, float yScale) {
 void UIPauseMenuButton::onMouseInside() {
 void UIPauseMenuButton::onMouseInside() {
     CBaseUIButton::onMouseInside();
     CBaseUIButton::onMouseInside();
 
 
-    if(engine->hasFocus()) engine->getSound()->play(m_osu->getSkin()->getMenuClick());
+    if(engine->hasFocus()) engine->getSound()->play(osu->getSkin()->getMenuClick());
 
 
     const float animationDuration = 0.09f;
     const float animationDuration = 0.09f;
     anim->moveLinear(&m_vScale.x, m_vBaseScale.x * m_fScaleMultiplier, animationDuration, true);
     anim->moveLinear(&m_vScale.x, m_vBaseScale.x * m_fScaleMultiplier, animationDuration, true);

+ 2 - 17
src/App/Osu/UIPauseMenuButton.h

@@ -1,22 +1,11 @@
-//================ Copyright (c) 2018, PG, All rights reserved. =================//
-//
-// Purpose:		pause menu button
-//
-// $NoKeywords: $
-//===============================================================================//
-
-#ifndef OSUUIPAUSEMENUBUTTON_H
-#define OSUUIPAUSEMENUBUTTON_H
-
+#pragma once
 #include "CBaseUIButton.h"
 #include "CBaseUIButton.h"
 
 
-class Osu;
-
 class Image;
 class Image;
 
 
 class UIPauseMenuButton : public CBaseUIButton {
 class UIPauseMenuButton : public CBaseUIButton {
    public:
    public:
-    UIPauseMenuButton(Osu *osu, std::function<Image *()> getImageFunc, float xPos, float yPos, float xSize, float ySize,
+    UIPauseMenuButton(std::function<Image *()> getImageFunc, float xPos, float yPos, float xSize, float ySize,
                       UString name);
                       UString name);
 
 
     virtual void draw(Graphics *g);
     virtual void draw(Graphics *g);
@@ -30,8 +19,6 @@ class UIPauseMenuButton : public CBaseUIButton {
     Image *getImage() { return getImageFunc != NULL ? getImageFunc() : NULL; }
     Image *getImage() { return getImageFunc != NULL ? getImageFunc() : NULL; }
 
 
    private:
    private:
-    Osu *m_osu;
-
     Vector2 m_vScale;
     Vector2 m_vScale;
     Vector2 m_vBaseScale;
     Vector2 m_vBaseScale;
     float m_fScaleMultiplier;
     float m_fScaleMultiplier;
@@ -40,5 +27,3 @@ class UIPauseMenuButton : public CBaseUIButton {
 
 
     std::function<Image *()> getImageFunc;
     std::function<Image *()> getImageFunc;
 };
 };
-
-#endif

+ 2 - 11
src/App/Osu/UIRankingScreenInfoLabel.cpp

@@ -1,10 +1,3 @@
-//================ Copyright (c) 2016, PG, All rights reserved. =================//
-//
-// Purpose:		analog to UIRankingScreenInfoLabel, but for the ranking screen
-//
-// $NoKeywords: $osursil
-//===============================================================================//
-
 #include "UIRankingScreenInfoLabel.h"
 #include "UIRankingScreenInfoLabel.h"
 
 
 #include <chrono>
 #include <chrono>
@@ -15,11 +8,9 @@
 #include "Osu.h"
 #include "Osu.h"
 #include "ResourceManager.h"
 #include "ResourceManager.h"
 
 
-UIRankingScreenInfoLabel::UIRankingScreenInfoLabel(Osu *osu, float xPos, float yPos, float xSize, float ySize,
-                                                   UString name)
+UIRankingScreenInfoLabel::UIRankingScreenInfoLabel(float xPos, float yPos, float xSize, float ySize, UString name)
     : CBaseUIElement(xPos, yPos, xSize, ySize, name) {
     : CBaseUIElement(xPos, yPos, xSize, ySize, name) {
-    m_osu = osu;
-    m_font = m_osu->getSubTitleFont();
+    m_font = osu->getSubTitleFont();
 
 
     m_iMargin = 10;
     m_iMargin = 10;
 
 

+ 2 - 15
src/App/Osu/UIRankingScreenInfoLabel.h

@@ -1,24 +1,14 @@
-//================ Copyright (c) 2016, PG, All rights reserved. =================//
-//
-// Purpose:		analog to InfoLabel, but for the ranking screen
-//
-// $NoKeywords: $osursil
-//===============================================================================//
-
-#ifndef OSUUIRANKINGSCREENINFOLABEL_H
-#define OSUUIRANKINGSCREENINFOLABEL_H
-
+#pragma once
 #include "CBaseUIElement.h"
 #include "CBaseUIElement.h"
 
 
 class McFont;
 class McFont;
 
 
-class Osu;
 class Beatmap;
 class Beatmap;
 class DatabaseBeatmap;
 class DatabaseBeatmap;
 
 
 class UIRankingScreenInfoLabel : public CBaseUIElement {
 class UIRankingScreenInfoLabel : public CBaseUIElement {
    public:
    public:
-    UIRankingScreenInfoLabel(Osu *osu, float xPos, float yPos, float xSize, float ySize, UString name);
+    UIRankingScreenInfoLabel(float xPos, float yPos, float xSize, float ySize, UString name);
 
 
     void draw(Graphics *g);
     void draw(Graphics *g);
 
 
@@ -37,7 +27,6 @@ class UIRankingScreenInfoLabel : public CBaseUIElement {
    private:
    private:
     UString buildPlayerString();
     UString buildPlayerString();
 
 
-    Osu *m_osu;
     McFont *m_font;
     McFont *m_font;
 
 
     int m_iMargin;
     int m_iMargin;
@@ -50,5 +39,3 @@ class UIRankingScreenInfoLabel : public CBaseUIElement {
     std::string m_sPlayer;
     std::string m_sPlayer;
     std::string m_sDate;
     std::string m_sDate;
 };
 };
-
-#endif

+ 50 - 61
src/App/Osu/UIRankingScreenRankingPanel.cpp

@@ -1,10 +1,3 @@
-//================ Copyright (c) 2016, PG, All rights reserved. =================//
-//
-// Purpose:		score + results panel (300, 100, 50, miss, combo, accuracy, score)
-//
-// $NoKeywords: $osursp
-//===============================================================================//
-
 #include "UIRankingScreenRankingPanel.h"
 #include "UIRankingScreenRankingPanel.h"
 
 
 #include "ConVar.h"
 #include "ConVar.h"
@@ -16,10 +9,8 @@
 #include "SkinImage.h"
 #include "SkinImage.h"
 #include "score.h"
 #include "score.h"
 
 
-UIRankingScreenRankingPanel::UIRankingScreenRankingPanel(Osu *osu) : CBaseUIImage("", 0, 0, 0, 0, "") {
-    m_osu = osu;
-
-    setImage(m_osu->getSkin()->getRankingPanel());
+UIRankingScreenRankingPanel::UIRankingScreenRankingPanel() : CBaseUIImage("", 0, 0, 0, 0, "") {
+    setImage(osu->getSkin()->getRankingPanel());
     setDrawFrame(true);
     setDrawFrame(true);
 
 
     m_iScore = 0;
     m_iScore = 0;
@@ -41,21 +32,21 @@ void UIRankingScreenRankingPanel::draw(Graphics *g) {
     const float uiScale = /*Osu::ui_scale->getFloat()*/ 1.0f;  // NOTE: commented for now, doesn't really work due to
     const float uiScale = /*Osu::ui_scale->getFloat()*/ 1.0f;  // NOTE: commented for now, doesn't really work due to
                                                                // legacy layout expectations
                                                                // legacy layout expectations
 
 
-    const float globalScoreScale = (m_osu->getSkin()->getVersion() > 1.0f ? 1.3f : 1.05f) * uiScale;
+    const float globalScoreScale = (osu->getSkin()->getVersion() > 1.0f ? 1.3f : 1.05f) * uiScale;
 
 
     const int globalYOffsetRaw = -1;
     const int globalYOffsetRaw = -1;
-    const int globalYOffset = m_osu->getUIScale(m_osu, globalYOffsetRaw);
+    const int globalYOffset = osu->getUIScale(globalYOffsetRaw);
 
 
     // draw score
     // draw score
     g->setColor(0xffffffff);
     g->setColor(0xffffffff);
-    float scale = m_osu->getImageScale(m_osu, m_osu->getSkin()->getScore0(), 20.0f) * globalScoreScale;
+    float scale = osu->getImageScale(osu->getSkin()->getScore0(), 20.0f) * globalScoreScale;
     g->pushTransform();
     g->pushTransform();
     {
     {
         g->scale(scale, scale);
         g->scale(scale, scale);
-        g->translate(m_vPos.x + m_osu->getUIScale(m_osu, 111.0f) * uiScale,
-                     m_vPos.y + (m_osu->getSkin()->getScore0()->getHeight() / 2) * scale +
-                         (m_osu->getUIScale(m_osu, 11.0f) + globalYOffset) * uiScale);
-        m_osu->getHUD()->drawScoreNumber(g, m_iScore, scale);
+        g->translate(m_vPos.x + osu->getUIScale(111.0f) * uiScale,
+                     m_vPos.y + (osu->getSkin()->getScore0()->getHeight() / 2) * scale +
+                         (osu->getUIScale(11.0f) + globalYOffset) * uiScale);
+        osu->getHUD()->drawScoreNumber(g, m_iScore, scale);
     }
     }
     g->popTransform();
     g->popTransform();
 
 
@@ -64,16 +55,16 @@ void UIRankingScreenRankingPanel::draw(Graphics *g) {
     const Vector2 hitGridOffsetX = Vector2(200, 0);
     const Vector2 hitGridOffsetX = Vector2(200, 0);
     const Vector2 hitGridOffsetY = Vector2(0, 60);
     const Vector2 hitGridOffsetY = Vector2(0, 60);
 
 
-    drawHitImage(g, m_osu->getSkin()->getHit300(), scale, hitImageStartPos);
-    drawHitImage(g, m_osu->getSkin()->getHit100(), scale, hitImageStartPos + hitGridOffsetY);
-    drawHitImage(g, m_osu->getSkin()->getHit50(), scale, hitImageStartPos + hitGridOffsetY * 2);
-    drawHitImage(g, m_osu->getSkin()->getHit300g(), scale, hitImageStartPos + hitGridOffsetX);
-    drawHitImage(g, m_osu->getSkin()->getHit100k(), scale, hitImageStartPos + hitGridOffsetX + hitGridOffsetY);
-    drawHitImage(g, m_osu->getSkin()->getHit0(), scale, hitImageStartPos + hitGridOffsetX + hitGridOffsetY * 2);
+    drawHitImage(g, osu->getSkin()->getHit300(), scale, hitImageStartPos);
+    drawHitImage(g, osu->getSkin()->getHit100(), scale, hitImageStartPos + hitGridOffsetY);
+    drawHitImage(g, osu->getSkin()->getHit50(), scale, hitImageStartPos + hitGridOffsetY * 2);
+    drawHitImage(g, osu->getSkin()->getHit300g(), scale, hitImageStartPos + hitGridOffsetX);
+    drawHitImage(g, osu->getSkin()->getHit100k(), scale, hitImageStartPos + hitGridOffsetX + hitGridOffsetY);
+    drawHitImage(g, osu->getSkin()->getHit0(), scale, hitImageStartPos + hitGridOffsetX + hitGridOffsetY * 2);
 
 
     // draw numHits
     // draw numHits
-    const Vector2 numHitStartPos = hitImageStartPos + Vector2(40, m_osu->getSkin()->getVersion() > 1.0f ? -16 : -25);
-    scale = m_osu->getImageScale(m_osu, m_osu->getSkin()->getScore0(), 17.0f) * globalScoreScale;
+    const Vector2 numHitStartPos = hitImageStartPos + Vector2(40, osu->getSkin()->getVersion() > 1.0f ? -16 : -25);
+    scale = osu->getImageScale(osu->getSkin()->getScore0(), 17.0f) * globalScoreScale;
 
 
     drawNumHits(g, m_iNum300s, scale, numHitStartPos);
     drawNumHits(g, m_iNum300s, scale, numHitStartPos);
     drawNumHits(g, m_iNum100s, scale, numHitStartPos + hitGridOffsetY);
     drawNumHits(g, m_iNum100s, scale, numHitStartPos + hitGridOffsetY);
@@ -84,70 +75,70 @@ void UIRankingScreenRankingPanel::draw(Graphics *g) {
     drawNumHits(g, m_iNumMisses, scale, numHitStartPos + hitGridOffsetX + hitGridOffsetY * 2);
     drawNumHits(g, m_iNumMisses, scale, numHitStartPos + hitGridOffsetX + hitGridOffsetY * 2);
 
 
     const int row4 = 260;
     const int row4 = 260;
-    const int row4ImageOffset = (m_osu->getSkin()->getVersion() > 1.0f ? 20 : 8) - 20;
+    const int row4ImageOffset = (osu->getSkin()->getVersion() > 1.0f ? 20 : 8) - 20;
 
 
     // draw combo
     // draw combo
-    scale = m_osu->getImageScale(m_osu, m_osu->getSkin()->getScore0(), 17.0f) * globalScoreScale;
+    scale = osu->getImageScale(osu->getSkin()->getScore0(), 17.0f) * globalScoreScale;
     g->pushTransform();
     g->pushTransform();
     {
     {
         g->scale(scale, scale);
         g->scale(scale, scale);
-        g->translate(m_vPos.x + m_osu->getUIScale(m_osu, 15.0f) * uiScale,
-                     m_vPos.y + (m_osu->getSkin()->getScore0()->getHeight() / 2) * scale +
-                         (m_osu->getUIScale(m_osu, row4 + 10) + globalYOffset) * uiScale);
-        m_osu->getHUD()->drawComboSimple(g, m_iCombo, scale);
+        g->translate(m_vPos.x + osu->getUIScale(15.0f) * uiScale,
+                     m_vPos.y + (osu->getSkin()->getScore0()->getHeight() / 2) * scale +
+                         (osu->getUIScale(row4 + 10) + globalYOffset) * uiScale);
+        osu->getHUD()->drawComboSimple(g, m_iCombo, scale);
     }
     }
     g->popTransform();
     g->popTransform();
 
 
     // draw maxcombo label
     // draw maxcombo label
     Vector2 hardcodedOsuRankingMaxComboImageSize =
     Vector2 hardcodedOsuRankingMaxComboImageSize =
-        Vector2(162, 50) * (m_osu->getSkin()->isRankingMaxCombo2x() ? 2.0f : 1.0f);
-    scale = m_osu->getImageScale(m_osu, hardcodedOsuRankingMaxComboImageSize, 32.0f) * uiScale;
+        Vector2(162, 50) * (osu->getSkin()->isRankingMaxCombo2x() ? 2.0f : 1.0f);
+    scale = osu->getImageScale(hardcodedOsuRankingMaxComboImageSize, 32.0f) * uiScale;
     g->pushTransform();
     g->pushTransform();
     {
     {
         g->scale(scale, scale);
         g->scale(scale, scale);
-        g->translate(m_vPos.x + m_osu->getSkin()->getRankingMaxCombo()->getWidth() * scale * 0.5f +
-                         m_osu->getUIScale(m_osu, 4.0f) * uiScale,
-                     m_vPos.y + (m_osu->getUIScale(m_osu, row4 - 5 - row4ImageOffset) + globalYOffset) * uiScale);
-        g->drawImage(m_osu->getSkin()->getRankingMaxCombo());
+        g->translate(m_vPos.x + osu->getSkin()->getRankingMaxCombo()->getWidth() * scale * 0.5f +
+                         osu->getUIScale(4.0f) * uiScale,
+                     m_vPos.y + (osu->getUIScale(row4 - 5 - row4ImageOffset) + globalYOffset) * uiScale);
+        g->drawImage(osu->getSkin()->getRankingMaxCombo());
     }
     }
     g->popTransform();
     g->popTransform();
 
 
     // draw accuracy
     // draw accuracy
-    scale = m_osu->getImageScale(m_osu, m_osu->getSkin()->getScore0(), 17.0f) * globalScoreScale;
+    scale = osu->getImageScale(osu->getSkin()->getScore0(), 17.0f) * globalScoreScale;
     g->pushTransform();
     g->pushTransform();
     {
     {
         g->scale(scale, scale);
         g->scale(scale, scale);
-        g->translate(m_vPos.x + m_osu->getUIScale(m_osu, 195.0f) * uiScale,
-                     m_vPos.y + (m_osu->getSkin()->getScore0()->getHeight() / 2) * scale +
-                         (m_osu->getUIScale(m_osu, row4 + 10) + globalYOffset) * uiScale);
-        m_osu->getHUD()->drawAccuracySimple(g, m_fAccuracy * 100.0f, scale);
+        g->translate(m_vPos.x + osu->getUIScale(195.0f) * uiScale,
+                     m_vPos.y + (osu->getSkin()->getScore0()->getHeight() / 2) * scale +
+                         (osu->getUIScale(row4 + 10) + globalYOffset) * uiScale);
+        osu->getHUD()->drawAccuracySimple(g, m_fAccuracy * 100.0f, scale);
     }
     }
     g->popTransform();
     g->popTransform();
 
 
     // draw accuracy label
     // draw accuracy label
     Vector2 hardcodedOsuRankingAccuracyImageSize =
     Vector2 hardcodedOsuRankingAccuracyImageSize =
-        Vector2(192, 58) * (m_osu->getSkin()->isRankingAccuracy2x() ? 2.0f : 1.0f);
-    scale = m_osu->getImageScale(m_osu, hardcodedOsuRankingAccuracyImageSize, 36.0f) * uiScale;
+        Vector2(192, 58) * (osu->getSkin()->isRankingAccuracy2x() ? 2.0f : 1.0f);
+    scale = osu->getImageScale(hardcodedOsuRankingAccuracyImageSize, 36.0f) * uiScale;
     g->pushTransform();
     g->pushTransform();
     {
     {
         g->scale(scale, scale);
         g->scale(scale, scale);
-        g->translate(m_vPos.x + m_osu->getSkin()->getRankingAccuracy()->getWidth() * scale * 0.5f +
-                         m_osu->getUIScale(m_osu, 183.0f) * uiScale,
-                     m_vPos.y + (m_osu->getUIScale(m_osu, row4 - 3 - row4ImageOffset) + globalYOffset) * uiScale);
-        g->drawImage(m_osu->getSkin()->getRankingAccuracy());
+        g->translate(m_vPos.x + osu->getSkin()->getRankingAccuracy()->getWidth() * scale * 0.5f +
+                         osu->getUIScale(183.0f) * uiScale,
+                     m_vPos.y + (osu->getUIScale(row4 - 3 - row4ImageOffset) + globalYOffset) * uiScale);
+        g->drawImage(osu->getSkin()->getRankingAccuracy());
     }
     }
     g->popTransform();
     g->popTransform();
 
 
     // draw perfect
     // draw perfect
     if(m_bPerfect) {
     if(m_bPerfect) {
-        scale = m_osu->getImageScale(m_osu, m_osu->getSkin()->getRankingPerfect()->getSizeBaseRaw(), 94.0f) * uiScale;
-        m_osu->getSkin()->getRankingPerfect()->drawRaw(
+        scale = osu->getImageScale(osu->getSkin()->getRankingPerfect()->getSizeBaseRaw(), 94.0f) * uiScale;
+        osu->getSkin()->getRankingPerfect()->drawRaw(
             g,
             g,
             m_vPos +
             m_vPos +
-                Vector2(m_osu->getUIScale(m_osu, m_osu->getSkin()->getVersion() > 1.0f ? 260 : 200),
-                        m_osu->getUIScale(m_osu, 430.0f) + globalYOffset) *
+                Vector2(osu->getUIScale(osu->getSkin()->getVersion() > 1.0f ? 260 : 200),
+                        osu->getUIScale(430.0f) + globalYOffset) *
                     Vector2(1.0f, 0.97f) * uiScale -
                     Vector2(1.0f, 0.97f) * uiScale -
-                Vector2(0, m_osu->getSkin()->getRankingPerfect()->getSizeBaseRaw().y) * scale * 0.5f,
+                Vector2(0, osu->getSkin()->getRankingPerfect()->getSizeBaseRaw().y) * scale * 0.5f,
             scale);
             scale);
     }
     }
 }
 }
@@ -157,9 +148,7 @@ void UIRankingScreenRankingPanel::drawHitImage(Graphics *g, SkinImage *img, floa
                                                                // legacy layout expectations
                                                                // legacy layout expectations
 
 
     /// img->setAnimationFrameForce(0);
     /// img->setAnimationFrameForce(0);
-    img->draw(g,
-              Vector2(m_vPos.x + m_osu->getUIScale(m_osu, pos.x) * uiScale,
-                      m_vPos.y + m_osu->getUIScale(m_osu, pos.y) * uiScale),
+    img->draw(g, Vector2(m_vPos.x + osu->getUIScale(pos.x) * uiScale, m_vPos.y + osu->getUIScale(pos.y) * uiScale),
               uiScale);
               uiScale);
 }
 }
 
 
@@ -170,10 +159,10 @@ void UIRankingScreenRankingPanel::drawNumHits(Graphics *g, int numHits, float sc
     g->pushTransform();
     g->pushTransform();
     {
     {
         g->scale(scale, scale);
         g->scale(scale, scale);
-        g->translate(m_vPos.x + m_osu->getUIScale(m_osu, pos.x) * uiScale,
-                     m_vPos.y + (m_osu->getSkin()->getScore0()->getHeight() / 2) * scale +
-                         m_osu->getUIScale(m_osu, pos.y) * uiScale);
-        m_osu->getHUD()->drawComboSimple(g, numHits, scale);
+        g->translate(
+            m_vPos.x + osu->getUIScale(pos.x) * uiScale,
+            m_vPos.y + (osu->getSkin()->getScore0()->getHeight() / 2) * scale + osu->getUIScale(pos.y) * uiScale);
+        osu->getHUD()->drawComboSimple(g, numHits, scale);
     }
     }
     g->popTransform();
     g->popTransform();
 }
 }

+ 1 - 4
src/App/Osu/UIRankingScreenRankingPanel.h

@@ -2,14 +2,13 @@
 #include "CBaseUIImage.h"
 #include "CBaseUIImage.h"
 #include "Database.h"
 #include "Database.h"
 
 
-class Osu;
 class LiveScore;
 class LiveScore;
 class SkinImage;
 class SkinImage;
 struct FinishedScore;
 struct FinishedScore;
 
 
 class UIRankingScreenRankingPanel : public CBaseUIImage {
 class UIRankingScreenRankingPanel : public CBaseUIImage {
    public:
    public:
-    UIRankingScreenRankingPanel(Osu *osu);
+    UIRankingScreenRankingPanel();
 
 
     virtual void draw(Graphics *g);
     virtual void draw(Graphics *g);
 
 
@@ -20,8 +19,6 @@ class UIRankingScreenRankingPanel : public CBaseUIImage {
     void drawHitImage(Graphics *g, SkinImage *img, float scale, Vector2 pos);
     void drawHitImage(Graphics *g, SkinImage *img, float scale, Vector2 pos);
     void drawNumHits(Graphics *g, int numHits, float scale, Vector2 pos);
     void drawNumHits(Graphics *g, int numHits, float scale, Vector2 pos);
 
 
-    Osu *m_osu;
-
     unsigned long long m_iScore;
     unsigned long long m_iScore;
     int m_iNum300s;
     int m_iNum300s;
     int m_iNum300gs;
     int m_iNum300gs;

+ 2 - 11
src/App/Osu/UISearchOverlay.cpp

@@ -1,20 +1,11 @@
-//================ Copyright (c) 2017, PG, All rights reserved. =================//
-//
-// Purpose:		search text overlay
-//
-// $NoKeywords: $osufind
-//===============================================================================//
-
 #include "UISearchOverlay.h"
 #include "UISearchOverlay.h"
 
 
 #include "Engine.h"
 #include "Engine.h"
 #include "Osu.h"
 #include "Osu.h"
 #include "ResourceManager.h"
 #include "ResourceManager.h"
 
 
-UISearchOverlay::UISearchOverlay(Osu *osu, float xPos, float yPos, float xSize, float ySize, UString name)
+UISearchOverlay::UISearchOverlay(float xPos, float yPos, float xSize, float ySize, UString name)
     : CBaseUIElement(xPos, yPos, xSize, ySize, name) {
     : CBaseUIElement(xPos, yPos, xSize, ySize, name) {
-    m_osu = osu;
-
     m_font = engine->getResourceManager()->getFont("FONT_DEFAULT");
     m_font = engine->getResourceManager()->getFont("FONT_DEFAULT");
 
 
     m_iOffsetRight = 0;
     m_iOffsetRight = 0;
@@ -61,7 +52,7 @@ void UISearchOverlay::draw(Graphics *g) {
                                      (searchTextFont->getHeight() * searchTextScale) * 0.5f - m_iOffsetRight) +
                                      (searchTextFont->getHeight() * searchTextScale) * 0.5f - m_iOffsetRight) +
                                (int)(searchTextFont->getStringWidth(searchText1) * searchTextScale) +
                                (int)(searchTextFont->getStringWidth(searchText1) * searchTextScale) +
                                (int)(searchStringWidth * searchTextScale);
                                (int)(searchStringWidth * searchTextScale);
-        if(actualXEnd > m_osu->getScreenWidth()) textOverflowXOffset = actualXEnd - m_osu->getScreenWidth();
+        if(actualXEnd > osu->getScreenWidth()) textOverflowXOffset = actualXEnd - osu->getScreenWidth();
     }
     }
 
 
     // draw background
     // draw background

+ 2 - 17
src/App/Osu/UISearchOverlay.h

@@ -1,20 +1,9 @@
-//================ Copyright (c) 2017, PG, All rights reserved. =================//
-//
-// Purpose:		search text overlay
-//
-// $NoKeywords: $osufind
-//===============================================================================//
-
-#ifndef OSUUISEARCHOVERLAY_H
-#define OSUUISEARCHOVERLAY_H
-
+#pragma once
 #include "CBaseUIElement.h"
 #include "CBaseUIElement.h"
 
 
-class Osu;
-
 class UISearchOverlay : public CBaseUIElement {
 class UISearchOverlay : public CBaseUIElement {
    public:
    public:
-    UISearchOverlay(Osu *osu, float xPos, float yPos, float xSize, float ySize, UString name);
+    UISearchOverlay(float xPos, float yPos, float xSize, float ySize, UString name);
 
 
     virtual void draw(Graphics *g);
     virtual void draw(Graphics *g);
 
 
@@ -30,8 +19,6 @@ class UISearchOverlay : public CBaseUIElement {
     void setSearching(bool searching) { m_bSearching = searching; }
     void setSearching(bool searching) { m_bSearching = searching; }
 
 
    private:
    private:
-    Osu *m_osu;
-
     McFont *m_font;
     McFont *m_font;
 
 
     int m_iOffsetRight;
     int m_iOffsetRight;
@@ -43,5 +30,3 @@ class UISearchOverlay : public CBaseUIElement {
 
 
     bool m_bSearching;
     bool m_bSearching;
 };
 };
-
-#endif

+ 3 - 11
src/App/Osu/UISlider.cpp

@@ -1,10 +1,3 @@
-//================ Copyright (c) 2016, PG, All rights reserved. =================//
-//
-// Purpose:		generic slider (mod overrides, options, etc.)
-//
-// $NoKeywords: $osusl
-//===============================================================================//
-
 #include "UISlider.h"
 #include "UISlider.h"
 
 
 #include "AnimationHandler.h"
 #include "AnimationHandler.h"
@@ -12,16 +5,15 @@
 #include "ResourceManager.h"
 #include "ResourceManager.h"
 #include "Skin.h"
 #include "Skin.h"
 
 
-UISlider::UISlider(Osu *osu, float xPos, float yPos, float xSize, float ySize, UString name)
+UISlider::UISlider(float xPos, float yPos, float xSize, float ySize, UString name)
     : CBaseUISlider(xPos, yPos, xSize, ySize, name) {
     : CBaseUISlider(xPos, yPos, xSize, ySize, name) {
-    m_osu = osu;
     setBlockSize(20, 20);
     setBlockSize(20, 20);
 }
 }
 
 
 void UISlider::draw(Graphics *g) {
 void UISlider::draw(Graphics *g) {
     if(!m_bVisible) return;
     if(!m_bVisible) return;
 
 
-    Image *img = m_osu->getSkin()->getCircleEmpty();
+    Image *img = osu->getSkin()->getCircleEmpty();
     if(img == NULL) {
     if(img == NULL) {
         CBaseUISlider::draw(g);
         CBaseUISlider::draw(g);
         return;
         return;
@@ -52,7 +44,7 @@ void UISlider::draw(Graphics *g) {
     {
     {
         g->scale(scale.x, scale.y);
         g->scale(scale.x, scale.y);
         g->translate(blockCenter.x, blockCenter.y + 1);
         g->translate(blockCenter.x, blockCenter.y + 1);
-        g->drawImage(m_osu->getSkin()->getCircleEmpty());
+        g->drawImage(osu->getSkin()->getCircleEmpty());
     }
     }
     g->popTransform();
     g->popTransform();
 }
 }

+ 2 - 18
src/App/Osu/UISlider.h

@@ -1,25 +1,9 @@
-//================ Copyright (c) 2016, PG, All rights reserved. =================//
-//
-// Purpose:		generic slider (mod overrides, options, etc.)
-//
-// $NoKeywords: $osusl
-//===============================================================================//
-
-#ifndef OSUUISLIDER_H
-#define OSUUISLIDER_H
-
+#pragma once
 #include "CBaseUISlider.h"
 #include "CBaseUISlider.h"
 
 
-class Osu;
-
 class UISlider : public CBaseUISlider {
 class UISlider : public CBaseUISlider {
    public:
    public:
-    UISlider(Osu *osu, float xPos, float yPos, float xSize, float ySize, UString name);
+    UISlider(float xPos, float yPos, float xSize, float ySize, UString name);
 
 
     virtual void draw(Graphics *g);
     virtual void draw(Graphics *g);
-
-   private:
-    Osu *m_osu;
 };
 };
-
-#endif

Some files were not shown because too many files changed in this diff