|
@@ -4,8 +4,19 @@
|
|
// Include order matters
|
|
// Include order matters
|
|
#include "cbase.h"
|
|
#include "cbase.h"
|
|
#include <dwmapi.h>
|
|
#include <dwmapi.h>
|
|
|
|
+#include <shellapi.h>
|
|
// clang-format on
|
|
// clang-format on
|
|
|
|
|
|
|
|
+#include "Database.h"
|
|
|
|
+#include "DatabaseBeatmap.h"
|
|
|
|
+#include "Downloader.h" // for extract_beatmapset
|
|
|
|
+#include "File.h"
|
|
|
|
+#include "MainMenu.h"
|
|
|
|
+#include "OptionsMenu.h"
|
|
|
|
+#include "Osu.h"
|
|
|
|
+#include "SongBrowser/SongBrowser.h"
|
|
|
|
+#include "Skin.h"
|
|
|
|
+
|
|
// NEXTRAWINPUTBLOCK macro requires this
|
|
// NEXTRAWINPUTBLOCK macro requires this
|
|
typedef uint64_t QWORD;
|
|
typedef uint64_t QWORD;
|
|
|
|
|
|
@@ -154,15 +165,6 @@ extern ConVar *win_realtimestylus;
|
|
|
|
|
|
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
|
|
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
|
|
switch(msg) {
|
|
switch(msg) {
|
|
-#ifdef WINDOW_GHOST
|
|
|
|
-
|
|
|
|
- // window click-through
|
|
|
|
- // case WM_NCHITTEST:
|
|
|
|
- // return HTNOWHERE;
|
|
|
|
- // break;
|
|
|
|
-
|
|
|
|
-#endif
|
|
|
|
-
|
|
|
|
case WM_NCCREATE:
|
|
case WM_NCCREATE:
|
|
if(g_bSupportsPerMonitorDpiAwareness) {
|
|
if(g_bSupportsPerMonitorDpiAwareness) {
|
|
typedef BOOL(WINAPI * EPNCDS)(HWND);
|
|
typedef BOOL(WINAPI * EPNCDS)(HWND);
|
|
@@ -172,46 +174,80 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
|
|
}
|
|
}
|
|
return DefWindowProcW(hwnd, msg, wParam, lParam);
|
|
return DefWindowProcW(hwnd, msg, wParam, lParam);
|
|
|
|
|
|
-#if defined(WINDOW_FRAMELESS) && !defined(WINDOW_GHOST)
|
|
|
|
|
|
+ case WM_DROPFILES: {
|
|
|
|
+ HDROP hDrop = (HDROP)wParam;
|
|
|
|
+ UINT fileCount = DragQueryFileW(hDrop, 0xFFFFFFFF, NULL, 0);
|
|
|
|
+
|
|
|
|
+ std::string first_skin;
|
|
|
|
+
|
|
|
|
+ for (UINT i = 0; i < fileCount; i++) {
|
|
|
|
+ UINT pathLength = DragQueryFileW(hDrop, i, NULL, 0);
|
|
|
|
+ wchar_t *filePath = new wchar_t[pathLength + 1];
|
|
|
|
+ DragQueryFileW(hDrop, i, filePath, pathLength + 1);
|
|
|
|
+
|
|
|
|
+ // Convert filepath to UTF-8
|
|
|
|
+ int size = WideCharToMultiByte(CP_UTF8, 0, filePath, pathLength, NULL, 0, NULL, NULL);
|
|
|
|
+ std::string utf8filepath(size, 0);
|
|
|
|
+ WideCharToMultiByte(CP_UTF8, 0, filePath, size, (LPSTR)utf8filepath.c_str(), size, NULL, NULL);
|
|
|
|
+ delete[] filePath;
|
|
|
|
+
|
|
|
|
+ if(utf8filepath.length() < 4) continue;
|
|
|
|
+ auto extension = env->getFileExtensionFromFilePath(utf8filepath);
|
|
|
|
+ if(!extension.compare("osz")) {
|
|
|
|
+ File osz(utf8filepath);
|
|
|
|
+ i32 set_id = extract_beatmapset_id(osz.readFile(), osz.getFileSize());
|
|
|
|
+ if(set_id == -1) {
|
|
|
|
+ osu->getNotificationOverlay()->addNotification("Beatmapset doesn't have a valid ID.");
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
|
|
- // ignore
|
|
|
|
- /*
|
|
|
|
- case WM_ERASEBKGND:
|
|
|
|
- return 1;
|
|
|
|
- */
|
|
|
|
|
|
+ std::string mapset_dir = MCENGINE_DATA_DIR "maps\\";
|
|
|
|
+ mapset_dir.append(std::to_string(set_id));
|
|
|
|
+ mapset_dir.append("\\");
|
|
|
|
+ if(!env->directoryExists(mapset_dir)) {
|
|
|
|
+ env->createDirectory(mapset_dir);
|
|
|
|
+ }
|
|
|
|
+ if(!extract_beatmapset(osz.readFile(), osz.getFileSize(), mapset_dir)) {
|
|
|
|
+ osu->getNotificationOverlay()->addNotification("Failed to extract beatmapset");
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
|
|
- // window border paint
|
|
|
|
- /*
|
|
|
|
- case WM_NCPAINT:
|
|
|
|
- {
|
|
|
|
- // draw beautifully blurred windows 7 background + shadows
|
|
|
|
- return DefWindowProcW(hwnd, msg, wParam, lParam);
|
|
|
|
-
|
|
|
|
- // draw white rectangle over everything except the shadows
|
|
|
|
- //HDC hdc;
|
|
|
|
- //hdc = GetDCEx(hwnd, (HRGN)wParam, DCX_WINDOW|DCX_INTERSECTRGN);
|
|
|
|
- //PAINTSTRUCT ps;
|
|
|
|
- //hdc = BeginPaint(hwnd, &ps);
|
|
|
|
- //RECT wr;
|
|
|
|
- //GetClientRect(hwnd, &wr);
|
|
|
|
- //HBRUSH br;
|
|
|
|
- //br = GetSysColorBrush(COLOR_WINDOW);
|
|
|
|
- //FillRect(hdc, &wr, br);
|
|
|
|
- //ReleaseDC(hwnd, hdc);
|
|
|
|
|
|
+ osu->getSongBrowser()->getDatabase()->addBeatmap(mapset_dir);
|
|
|
|
+ if(!osu->getSongBrowser()->selectBeatmapset(set_id)) {
|
|
|
|
+ osu->getNotificationOverlay()->addNotification("Failed to import beatmapset");
|
|
|
|
+ continue;
|
|
}
|
|
}
|
|
- /// return 0;
|
|
|
|
- */
|
|
|
|
|
|
|
|
|
|
+ // prevent song browser from picking main menu song after database loads
|
|
|
|
+ // (we just loaded and selected another song, so previous no longer applies)
|
|
|
|
+ SAFE_DELETE(osu->m_mainMenu->preloaded_beatmapset);
|
|
|
|
+ } else if(!extension.compare("osk") || !extension.compare("zip")) {
|
|
|
|
+ Skin::unpack(utf8filepath.c_str());
|
|
|
|
+ if(first_skin.length() == 0) {
|
|
|
|
+ first_skin = utf8filepath;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ DragFinish(hDrop);
|
|
|
|
+
|
|
|
|
+ if(first_skin.length() > 0) {
|
|
|
|
+ auto folder_name = env->getFileNameFromFilePath(first_skin);
|
|
|
|
+ folder_name.erase(folder_name.size() - 4); // remove .osk extension
|
|
|
|
+
|
|
|
|
+ convar->getConVarByName("osu_skin")->setValue(env->getFileNameFromFilePath(folder_name).c_str());
|
|
|
|
+ osu->m_optionsMenu->updateSkinNameLabel();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+#if defined(WINDOW_FRAMELESS) && !defined(WINDOW_GHOST)
|
|
case WM_NCCALCSIZE: {
|
|
case WM_NCCALCSIZE: {
|
|
if(wParam == TRUE) {
|
|
if(wParam == TRUE) {
|
|
LPNCCALCSIZE_PARAMS pncc = (LPNCCALCSIZE_PARAMS)lParam;
|
|
LPNCCALCSIZE_PARAMS pncc = (LPNCCALCSIZE_PARAMS)lParam;
|
|
|
|
|
|
- // debugLog("new rectang: top = %i, right = %i, bottom = %i, left = %i\n", pncc->rgrc[0].top,
|
|
|
|
- // pncc->rgrc[0].right, pncc->rgrc[0].bottom, pncc->rgrc[0].left); debugLog("old rectang: top = %i,
|
|
|
|
- // right = %i, bottom = %i, left = %i\n", pncc->rgrc[1].top, pncc->rgrc[1].right, pncc->rgrc[1].bottom,
|
|
|
|
- // pncc->rgrc[1].left); debugLog("client rect: top = %i, right = %i, bottom = %i, left = %i\n",
|
|
|
|
- // pncc->rgrc[2].top, pncc->rgrc[2].right, pncc->rgrc[2].bottom, pncc->rgrc[2].left);
|
|
|
|
-
|
|
|
|
if(IsZoomed(hwnd)) {
|
|
if(IsZoomed(hwnd)) {
|
|
// HACKHACK: use center instead of MonitorFromWindow() in order to workaround windows display
|
|
// HACKHACK: use center instead of MonitorFromWindow() in order to workaround windows display
|
|
// scaling bullshit bug
|
|
// scaling bullshit bug
|
|
@@ -226,26 +262,11 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
|
|
info.cbSize = sizeof(MONITORINFO);
|
|
info.cbSize = sizeof(MONITORINFO);
|
|
GetMonitorInfo(monitor, &info);
|
|
GetMonitorInfo(monitor, &info);
|
|
|
|
|
|
- // McRect mr(info.rcMonitor.left, info.rcMonitor.top, std::abs(info.rcMonitor.left -
|
|
|
|
- // info.rcMonitor.right), std::abs(info.rcMonitor.top - info.rcMonitor.bottom)); printf("monitor.x =
|
|
|
|
- // %i, y = %i, width = %i, height = %i\n", (int)mr.getX(), (int)mr.getY(), (int)mr.getWidth(),
|
|
|
|
- // (int)mr.getHeight());
|
|
|
|
-
|
|
|
|
- // old (broken for multi-monitor setups)
|
|
|
|
- // pncc->rgrc[0].right += pncc->rgrc[0].left;
|
|
|
|
- // pncc->rgrc[0].bottom += pncc->rgrc[0].top;
|
|
|
|
- // pncc->rgrc[0].top = 0;
|
|
|
|
- // pncc->rgrc[0].left = 0;
|
|
|
|
-
|
|
|
|
- // new (still feels incorrect and fragile, but works for what I've tested it on)
|
|
|
|
pncc->rgrc[0].right += pncc->rgrc[0].left - info.rcMonitor.left;
|
|
pncc->rgrc[0].right += pncc->rgrc[0].left - info.rcMonitor.left;
|
|
pncc->rgrc[0].bottom += pncc->rgrc[0].top - info.rcMonitor.top;
|
|
pncc->rgrc[0].bottom += pncc->rgrc[0].top - info.rcMonitor.top;
|
|
pncc->rgrc[0].top = info.rcMonitor.top;
|
|
pncc->rgrc[0].top = info.rcMonitor.top;
|
|
pncc->rgrc[0].left = info.rcMonitor.left;
|
|
pncc->rgrc[0].left = info.rcMonitor.left;
|
|
}
|
|
}
|
|
-
|
|
|
|
- // printf("after: right = %i, bottom = %i, top = %i, left = %i\n", (int)pncc->rgrc[0].right,
|
|
|
|
- // (int)pncc->rgrc[0].bottom, (int)pncc->rgrc[0].top, (int)pncc->rgrc[0].left);
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// "When wParam is TRUE, simply returning 0 without processing the NCCALCSIZE_PARAMS rectangles will cause
|
|
// "When wParam is TRUE, simply returning 0 without processing the NCCALCSIZE_PARAMS rectangles will cause
|
|
@@ -310,34 +331,9 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
|
|
|
|
|
|
// paint nothing on repaint
|
|
// paint nothing on repaint
|
|
case WM_PAINT: {
|
|
case WM_PAINT: {
|
|
- // variant 1 (apparently not the correct way of doing this?):
|
|
|
|
- /*
|
|
|
|
- ValidateRect(hwnd, NULL);
|
|
|
|
- */
|
|
|
|
-
|
|
|
|
- // variant 2 (seems to be what DefWindowProc is doing):
|
|
|
|
PAINTSTRUCT ps;
|
|
PAINTSTRUCT ps;
|
|
BeginPaint(hwnd, &ps);
|
|
BeginPaint(hwnd, &ps);
|
|
EndPaint(hwnd, &ps);
|
|
EndPaint(hwnd, &ps);
|
|
-
|
|
|
|
- // debug:
|
|
|
|
- /*
|
|
|
|
- PAINTSTRUCT ps;
|
|
|
|
- HDC hdc = BeginPaint(hwnd, &ps);
|
|
|
|
-
|
|
|
|
- RECT wr;
|
|
|
|
- GetClientRect(hwnd, &wr);
|
|
|
|
- HBRUSH br;
|
|
|
|
- br = (HBRUSH)GetStockObject(BLACK_BRUSH);
|
|
|
|
- FillRect(hdc, &wr, br);
|
|
|
|
-
|
|
|
|
- ///br = (HBRUSH)GetStockObject(GRAY_BRUSH);
|
|
|
|
- ///wr.right = 100;
|
|
|
|
- ///wr.bottom = 100;
|
|
|
|
- ///FillRect(hdc, &wr, br);
|
|
|
|
-
|
|
|
|
- EndPaint(hwnd,&ps);
|
|
|
|
- */
|
|
|
|
}
|
|
}
|
|
return 0;
|
|
return 0;
|
|
|
|
|
|
@@ -1104,6 +1100,8 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
|
|
|
|
|
if(g_bHasFocus) g_engine->onFocusGained();
|
|
if(g_bHasFocus) g_engine->onFocusGained();
|
|
|
|
|
|
|
|
+ DragAcceptFiles(hwnd, TRUE);
|
|
|
|
+
|
|
frameTimer->update();
|
|
frameTimer->update();
|
|
deltaTimer->update();
|
|
deltaTimer->update();
|
|
|
|
|