2015-06-12 13:14:38 +00:00
|
|
|
namespace hiro {
|
2013-03-15 13:11:33 +00:00
|
|
|
|
2012-01-15 08:29:57 +00:00
|
|
|
static const unsigned Windows2000 = 0x0500;
|
|
|
|
static const unsigned WindowsXP = 0x0501;
|
|
|
|
static const unsigned WindowsVista = 0x0600;
|
|
|
|
static const unsigned Windows7 = 0x0601;
|
|
|
|
|
2015-10-10 02:16:12 +00:00
|
|
|
static auto Button_CustomDraw(HWND, PAINTSTRUCT&, bool, bool, bool, unsigned, const Font&, const Image&, Orientation, const string&) -> void;
|
Update to v094r43 release.
byuu says:
Updated to compile with all of the new hiro changes. My next step is to
write up hiro API documentation, and move the API from alpha (constantly
changing) to beta (rarely changing), in preparation for the first stable
release (backward-compatible changes only.)
Added "--fullscreen" command-line option. I like this over
a configuration file option. Lets you use the emulator in both modes
without having to modify the config file each time.
Also enhanced the command-line game loading. You can now use any of
these methods:
higan /path/to/game-folder.sfc
higan /path/to/game-folder.sfc/
higan /path/to/game-folder.sfc/program.rom
The idea is to support launchers that insist on loading files only.
Technically, the file can be any name (manifest.bml also works); the
only criteria is that the file actually exists and is a file, and not
a directory. This is a requirement to support the first version (a
directory lacking the trailing / identifier), because I don't want my
nall::string class to query the file system to determine if the string
is an actual existing file or directory for its pathname() / dirname()
functions.
Anyway, every game folder I've made so far has program.rom, and that's
very unlikely to change, so this should be fine.
Now, of course, if you drop a regular "game.sfc" file on the emulator,
it won't even try to load it, unless it's in a folder that ends in .fc,
.sfc, etc. In which case, it'll bail out immediately by being unable to
produce a manifest for what is obviously not really a game folder.
2015-08-30 02:08:26 +00:00
|
|
|
|
2015-06-12 13:14:38 +00:00
|
|
|
static auto OsVersion() -> unsigned {
|
2015-08-24 09:42:11 +00:00
|
|
|
OSVERSIONINFO versionInfo{0};
|
2012-01-15 08:29:57 +00:00
|
|
|
versionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
|
|
|
GetVersionEx(&versionInfo);
|
|
|
|
return (versionInfo.dwMajorVersion << 8) + (versionInfo.dwMajorVersion << 0);
|
|
|
|
}
|
|
|
|
|
Update to v094r43 release.
byuu says:
Updated to compile with all of the new hiro changes. My next step is to
write up hiro API documentation, and move the API from alpha (constantly
changing) to beta (rarely changing), in preparation for the first stable
release (backward-compatible changes only.)
Added "--fullscreen" command-line option. I like this over
a configuration file option. Lets you use the emulator in both modes
without having to modify the config file each time.
Also enhanced the command-line game loading. You can now use any of
these methods:
higan /path/to/game-folder.sfc
higan /path/to/game-folder.sfc/
higan /path/to/game-folder.sfc/program.rom
The idea is to support launchers that insist on loading files only.
Technically, the file can be any name (manifest.bml also works); the
only criteria is that the file actually exists and is a file, and not
a directory. This is a requirement to support the first version (a
directory lacking the trailing / identifier), because I don't want my
nall::string class to query the file system to determine if the string
is an actual existing file or directory for its pathname() / dirname()
functions.
Anyway, every game folder I've made so far has program.rom, and that's
very unlikely to change, so this should be fine.
Now, of course, if you drop a regular "game.sfc" file on the emulator,
it won't even try to load it, unless it's in a folder that ends in .fc,
.sfc, etc. In which case, it'll bail out immediately by being unable to
produce a manifest for what is obviously not really a game folder.
2015-08-30 02:08:26 +00:00
|
|
|
static auto CreateBitmap(image icon) -> HBITMAP {
|
|
|
|
icon.alphaMultiply(); //Windows AlphaBlend() requires premultiplied image data
|
|
|
|
icon.transform();
|
2012-01-15 08:29:57 +00:00
|
|
|
HDC hdc = GetDC(0);
|
|
|
|
BITMAPINFO bitmapInfo;
|
|
|
|
memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
|
|
|
|
bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
2015-06-18 10:48:53 +00:00
|
|
|
bitmapInfo.bmiHeader.biWidth = icon.width();
|
|
|
|
bitmapInfo.bmiHeader.biHeight = -(signed)icon.height(); //bitmaps are stored upside down unless we negate height
|
2012-01-15 08:29:57 +00:00
|
|
|
bitmapInfo.bmiHeader.biPlanes = 1;
|
|
|
|
bitmapInfo.bmiHeader.biBitCount = 32;
|
|
|
|
bitmapInfo.bmiHeader.biCompression = BI_RGB;
|
2015-06-18 10:48:53 +00:00
|
|
|
bitmapInfo.bmiHeader.biSizeImage = icon.size();
|
2013-05-02 11:25:45 +00:00
|
|
|
void* bits = nullptr;
|
2012-01-15 08:29:57 +00:00
|
|
|
HBITMAP hbitmap = CreateDIBSection(hdc, &bitmapInfo, DIB_RGB_COLORS, &bits, NULL, 0);
|
2015-06-18 10:48:53 +00:00
|
|
|
if(bits) memory::copy(bits, icon.data(), icon.size());
|
2012-01-15 08:29:57 +00:00
|
|
|
ReleaseDC(0, hdc);
|
|
|
|
return hbitmap;
|
|
|
|
}
|
|
|
|
|
Update to v094r43 release.
byuu says:
Updated to compile with all of the new hiro changes. My next step is to
write up hiro API documentation, and move the API from alpha (constantly
changing) to beta (rarely changing), in preparation for the first stable
release (backward-compatible changes only.)
Added "--fullscreen" command-line option. I like this over
a configuration file option. Lets you use the emulator in both modes
without having to modify the config file each time.
Also enhanced the command-line game loading. You can now use any of
these methods:
higan /path/to/game-folder.sfc
higan /path/to/game-folder.sfc/
higan /path/to/game-folder.sfc/program.rom
The idea is to support launchers that insist on loading files only.
Technically, the file can be any name (manifest.bml also works); the
only criteria is that the file actually exists and is a file, and not
a directory. This is a requirement to support the first version (a
directory lacking the trailing / identifier), because I don't want my
nall::string class to query the file system to determine if the string
is an actual existing file or directory for its pathname() / dirname()
functions.
Anyway, every game folder I've made so far has program.rom, and that's
very unlikely to change, so this should be fine.
Now, of course, if you drop a regular "game.sfc" file on the emulator,
it won't even try to load it, unless it's in a folder that ends in .fc,
.sfc, etc. In which case, it'll bail out immediately by being unable to
produce a manifest for what is obviously not really a game folder.
2015-08-30 02:08:26 +00:00
|
|
|
static auto CreateBitmap(const Image& image) -> HBITMAP {
|
|
|
|
HDC hdc = GetDC(0);
|
|
|
|
BITMAPINFO bitmapInfo{0};
|
|
|
|
bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
|
|
|
bitmapInfo.bmiHeader.biWidth = image.width();
|
|
|
|
bitmapInfo.bmiHeader.biHeight = -image.height(); //bitmaps are stored upside down unless we negate height
|
|
|
|
bitmapInfo.bmiHeader.biPlanes = 1;
|
|
|
|
bitmapInfo.bmiHeader.biBitCount = 32;
|
|
|
|
bitmapInfo.bmiHeader.biCompression = BI_RGB;
|
|
|
|
bitmapInfo.bmiHeader.biSizeImage = image.width() * image.height() * sizeof(uint32_t);
|
|
|
|
void* bits = nullptr;
|
|
|
|
HBITMAP hbitmap = CreateDIBSection(hdc, &bitmapInfo, DIB_RGB_COLORS, &bits, nullptr, 0);
|
|
|
|
if(bits) {
|
|
|
|
auto source = (const uint8_t*)image.data();
|
|
|
|
auto target = (uint8_t*)bits;
|
|
|
|
for(auto n : range(image.width() * image.height())) {
|
|
|
|
target[0] = (source[0] * source[3]) / 255;
|
|
|
|
target[1] = (source[1] * source[3]) / 255;
|
|
|
|
target[2] = (source[2] * source[3]) / 255;
|
|
|
|
target[3] = (source[3]);
|
|
|
|
source += 4, target += 4;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ReleaseDC(0, hdc);
|
|
|
|
return hbitmap;
|
|
|
|
}
|
|
|
|
|
2015-06-12 13:14:38 +00:00
|
|
|
static auto CreateRGB(const Color& color) -> COLORREF {
|
|
|
|
return RGB(color.red(), color.green(), color.blue());
|
|
|
|
}
|
|
|
|
|
|
|
|
static auto DropPaths(WPARAM wparam) -> lstring {
|
2013-07-29 09:42:45 +00:00
|
|
|
auto dropList = HDROP(wparam);
|
|
|
|
auto fileCount = DragQueryFile(dropList, ~0u, nullptr, 0);
|
|
|
|
|
|
|
|
lstring paths;
|
2015-06-12 13:14:38 +00:00
|
|
|
for(auto n : range(fileCount)) {
|
2013-07-29 09:42:45 +00:00
|
|
|
auto length = DragQueryFile(dropList, n, nullptr, 0);
|
|
|
|
auto buffer = new wchar_t[length + 1];
|
|
|
|
|
|
|
|
if(DragQueryFile(dropList, n, buffer, length + 1)) {
|
|
|
|
string path = (const char*)utf8_t(buffer);
|
|
|
|
path.transform("\\", "/");
|
2013-12-03 10:01:59 +00:00
|
|
|
if(directory::exists(path) && !path.endsWith("/")) path.append("/");
|
2013-07-29 09:42:45 +00:00
|
|
|
paths.append(path);
|
|
|
|
}
|
|
|
|
|
|
|
|
delete[] buffer;
|
|
|
|
}
|
|
|
|
|
|
|
|
return paths;
|
|
|
|
}
|
|
|
|
|
2015-06-12 13:14:38 +00:00
|
|
|
static auto GetWindowZOrder(HWND hwnd) -> unsigned {
|
2013-11-28 10:29:01 +00:00
|
|
|
unsigned z = 0;
|
|
|
|
for(HWND next = hwnd; next != NULL; next = GetWindow(next, GW_HWNDPREV)) z++;
|
|
|
|
return z;
|
|
|
|
}
|
|
|
|
|
Update to v094r43 release.
byuu says:
Updated to compile with all of the new hiro changes. My next step is to
write up hiro API documentation, and move the API from alpha (constantly
changing) to beta (rarely changing), in preparation for the first stable
release (backward-compatible changes only.)
Added "--fullscreen" command-line option. I like this over
a configuration file option. Lets you use the emulator in both modes
without having to modify the config file each time.
Also enhanced the command-line game loading. You can now use any of
these methods:
higan /path/to/game-folder.sfc
higan /path/to/game-folder.sfc/
higan /path/to/game-folder.sfc/program.rom
The idea is to support launchers that insist on loading files only.
Technically, the file can be any name (manifest.bml also works); the
only criteria is that the file actually exists and is a file, and not
a directory. This is a requirement to support the first version (a
directory lacking the trailing / identifier), because I don't want my
nall::string class to query the file system to determine if the string
is an actual existing file or directory for its pathname() / dirname()
functions.
Anyway, every game folder I've made so far has program.rom, and that's
very unlikely to change, so this should be fine.
Now, of course, if you drop a regular "game.sfc" file on the emulator,
it won't even try to load it, unless it's in a folder that ends in .fc,
.sfc, etc. In which case, it'll bail out immediately by being unable to
produce a manifest for what is obviously not really a game folder.
2015-08-30 02:08:26 +00:00
|
|
|
static auto ImageList_Append(HIMAGELIST imageList, const Image& image, unsigned scale) -> void {
|
|
|
|
nall::image icon;
|
|
|
|
if(image) {
|
|
|
|
icon.allocate(image.width(), image.height());
|
|
|
|
memory::copy(icon.data(), image.data(), icon.size());
|
|
|
|
icon.scale(scale, scale);
|
|
|
|
} else {
|
|
|
|
icon.allocate(scale, scale);
|
|
|
|
icon.fill(GetSysColor(COLOR_WINDOW));
|
2013-11-28 10:32:53 +00:00
|
|
|
}
|
Update to v094r43 release.
byuu says:
Updated to compile with all of the new hiro changes. My next step is to
write up hiro API documentation, and move the API from alpha (constantly
changing) to beta (rarely changing), in preparation for the first stable
release (backward-compatible changes only.)
Added "--fullscreen" command-line option. I like this over
a configuration file option. Lets you use the emulator in both modes
without having to modify the config file each time.
Also enhanced the command-line game loading. You can now use any of
these methods:
higan /path/to/game-folder.sfc
higan /path/to/game-folder.sfc/
higan /path/to/game-folder.sfc/program.rom
The idea is to support launchers that insist on loading files only.
Technically, the file can be any name (manifest.bml also works); the
only criteria is that the file actually exists and is a file, and not
a directory. This is a requirement to support the first version (a
directory lacking the trailing / identifier), because I don't want my
nall::string class to query the file system to determine if the string
is an actual existing file or directory for its pathname() / dirname()
functions.
Anyway, every game folder I've made so far has program.rom, and that's
very unlikely to change, so this should be fine.
Now, of course, if you drop a regular "game.sfc" file on the emulator,
it won't even try to load it, unless it's in a folder that ends in .fc,
.sfc, etc. In which case, it'll bail out immediately by being unable to
produce a manifest for what is obviously not really a game folder.
2015-08-30 02:08:26 +00:00
|
|
|
HBITMAP bitmap = CreateBitmap(icon);
|
|
|
|
ImageList_Add(imageList, bitmap, nullptr);
|
2013-11-28 10:32:53 +00:00
|
|
|
DeleteObject(bitmap);
|
|
|
|
}
|
|
|
|
|
2015-06-12 13:14:38 +00:00
|
|
|
//post message only if said message is not already pending in the queue
|
|
|
|
static auto PostMessageOnce(HWND hwnd, UINT id, WPARAM wparam, LPARAM lparam) -> void {
|
|
|
|
MSG msg;
|
|
|
|
if(!PeekMessage(&msg, hwnd, id, id, PM_NOREMOVE)) {
|
|
|
|
PostMessage(hwnd, id, wparam, lparam);
|
2012-01-15 08:29:57 +00:00
|
|
|
}
|
|
|
|
}
|
2013-03-15 13:11:33 +00:00
|
|
|
|
2015-06-12 13:14:38 +00:00
|
|
|
static auto ScrollEvent(HWND hwnd, WPARAM wparam) -> unsigned {
|
2013-11-28 10:29:01 +00:00
|
|
|
SCROLLINFO info;
|
|
|
|
memset(&info, 0, sizeof(SCROLLINFO));
|
|
|
|
info.cbSize = sizeof(SCROLLINFO);
|
|
|
|
info.fMask = SIF_ALL;
|
|
|
|
GetScrollInfo(hwnd, SB_CTL, &info);
|
|
|
|
|
|
|
|
switch(LOWORD(wparam)) {
|
|
|
|
case SB_LEFT: info.nPos = info.nMin; break;
|
|
|
|
case SB_RIGHT: info.nPos = info.nMax; break;
|
|
|
|
case SB_LINELEFT: info.nPos--; break;
|
|
|
|
case SB_LINERIGHT: info.nPos++; break;
|
|
|
|
case SB_PAGELEFT: info.nPos -= info.nMax >> 3; break;
|
|
|
|
case SB_PAGERIGHT: info.nPos += info.nMax >> 3; break;
|
|
|
|
case SB_THUMBTRACK: info.nPos = info.nTrackPos; break;
|
|
|
|
}
|
|
|
|
|
|
|
|
info.fMask = SIF_POS;
|
|
|
|
SetScrollInfo(hwnd, SB_CTL, &info, TRUE);
|
|
|
|
|
2015-08-21 10:56:39 +00:00
|
|
|
//Windows may clamp position to scrollbar range
|
2013-11-28 10:29:01 +00:00
|
|
|
GetScrollInfo(hwnd, SB_CTL, &info);
|
|
|
|
return info.nPos;
|
|
|
|
}
|
|
|
|
|
2015-06-12 13:14:38 +00:00
|
|
|
//separate because PopupMenu HWND does not contain GWLP_USERDATA pointing at Window needed for Shared_windowProc
|
|
|
|
static auto CALLBACK Menu_windowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) -> LRESULT {
|
|
|
|
switch(msg) {
|
|
|
|
case WM_MENUCOMMAND: {
|
|
|
|
MENUITEMINFO mii{sizeof(MENUITEMINFO)};
|
|
|
|
mii.fMask = MIIM_DATA;
|
|
|
|
GetMenuItemInfo((HMENU)lparam, wparam, true, &mii);
|
|
|
|
|
|
|
|
auto object = (mObject*)mii.dwItemData;
|
|
|
|
if(!object) break;
|
|
|
|
|
|
|
|
#if defined(Hiro_MenuItem)
|
|
|
|
if(auto menuItem = dynamic_cast<mMenuItem*>(object)) {
|
|
|
|
return menuItem->self()->onActivate(), false;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined(Hiro_MenuCheckItem)
|
|
|
|
if(auto menuCheckItem = dynamic_cast<mMenuCheckItem*>(object)) {
|
|
|
|
return menuCheckItem->self()->onToggle(), false;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined(Hiro_MenuRadioItem)
|
|
|
|
if(auto menuRadioItem = dynamic_cast<mMenuRadioItem*>(object)) {
|
|
|
|
return menuRadioItem->self()->onActivate(), false;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return DefWindowProc(hwnd, msg, wparam, lparam);
|
|
|
|
}
|
|
|
|
|
|
|
|
static auto CALLBACK Shared_windowProc(WindowProc windowProc, HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) -> LRESULT {
|
2015-06-15 22:16:43 +00:00
|
|
|
if(Application::state.quit) return DefWindowProc(hwnd, msg, wparam, lparam);
|
|
|
|
|
2015-06-12 13:14:38 +00:00
|
|
|
auto object = (mObject*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
|
|
|
|
if(!object) return DefWindowProc(hwnd, msg, wparam, lparam);
|
|
|
|
auto window = dynamic_cast<mWindow*>(object);
|
|
|
|
if(!window) window = object->parentWindow(true);
|
|
|
|
if(!window) return DefWindowProc(hwnd, msg, wparam, lparam);
|
2015-06-15 22:16:43 +00:00
|
|
|
auto pWindow = window->self();
|
|
|
|
if(!pWindow) return DefWindowProc(hwnd, msg, wparam, lparam);
|
2013-11-28 10:29:01 +00:00
|
|
|
|
2015-06-15 22:16:43 +00:00
|
|
|
if(pWindow->_modalityDisabled()) return DefWindowProc(hwnd, msg, wparam, lparam);
|
2013-11-28 10:29:01 +00:00
|
|
|
|
|
|
|
switch(msg) {
|
2013-11-28 10:32:53 +00:00
|
|
|
case WM_CTLCOLORBTN:
|
Update to v094r09 release.
byuu says:
This will easily be the biggest diff in the history of higan. And not in
a good way.
* target-higan and target-loki have been blown away completely
* nall and ruby massively updated
* phoenix replaced with hiro (pretty near a total rewrite)
* target-higan restarted using hiro (just a window for now)
* all emulation cores updated to compile again
* installation changed to not require root privileges (installs locally)
For the foreseeable future (maybe even permanently?), the new higan UI
will only build under Linux/BSD with GTK+ 2.20+. Probably the most
likely route for Windows/OS X will be to try and figure out how to build
hiro/GTK on those platforms, as awful as that would be. The other
alternative would be to produce new UIs for those platforms ... which
would actually be a good opportunity to make something much more user
friendly.
Being that I just started on this a few hours ago, that means that for
at least a few weeks, don't expect to be able to actually play any
games. Right now, you can pretty much just compile the binary and that's
it. It's quite possible that some nall changes didn't produce
compilation errors, but will produce runtime errors. So until the UI can
actually load games, we won't know if anything is broken. But we should
mostly be okay. It was mostly just trim<1> -> trim changes, moving to
Hash::SHA256 (much cleaner), and patching some reckless memory copy
functions enough to compile.
Progress isn't going to be like it was before: I'm now dividing my time
much thinner between studying and other hobbies.
My aim this time is not to produce a binary for everyone to play games
on. Rather, it's to keep the emulator alive. I want to be able to apply
critical patches again. And I would also like the base of the emulator
to live on, for use in other emulator frontends that utilize higan.
2015-02-26 10:10:46 +00:00
|
|
|
case WM_CTLCOLOREDIT:
|
2013-11-28 10:32:53 +00:00
|
|
|
case WM_CTLCOLORSTATIC: {
|
2015-06-12 13:14:38 +00:00
|
|
|
auto object = (mObject*)GetWindowLongPtr((HWND)lparam, GWLP_USERDATA);
|
|
|
|
if(!object) break;
|
|
|
|
|
Update to v094r09 release.
byuu says:
This will easily be the biggest diff in the history of higan. And not in
a good way.
* target-higan and target-loki have been blown away completely
* nall and ruby massively updated
* phoenix replaced with hiro (pretty near a total rewrite)
* target-higan restarted using hiro (just a window for now)
* all emulation cores updated to compile again
* installation changed to not require root privileges (installs locally)
For the foreseeable future (maybe even permanently?), the new higan UI
will only build under Linux/BSD with GTK+ 2.20+. Probably the most
likely route for Windows/OS X will be to try and figure out how to build
hiro/GTK on those platforms, as awful as that would be. The other
alternative would be to produce new UIs for those platforms ... which
would actually be a good opportunity to make something much more user
friendly.
Being that I just started on this a few hours ago, that means that for
at least a few weeks, don't expect to be able to actually play any
games. Right now, you can pretty much just compile the binary and that's
it. It's quite possible that some nall changes didn't produce
compilation errors, but will produce runtime errors. So until the UI can
actually load games, we won't know if anything is broken. But we should
mostly be okay. It was mostly just trim<1> -> trim changes, moving to
Hash::SHA256 (much cleaner), and patching some reckless memory copy
functions enough to compile.
Progress isn't going to be like it was before: I'm now dividing my time
much thinner between studying and other hobbies.
My aim this time is not to produce a binary for everyone to play games
on. Rather, it's to keep the emulator alive. I want to be able to apply
critical patches again. And I would also like the base of the emulator
to live on, for use in other emulator frontends that utilize higan.
2015-02-26 10:10:46 +00:00
|
|
|
//allow custom colors for various widgets
|
|
|
|
//note that this happens always: default colors are black text on a white background, unless overridden
|
|
|
|
//this intentionally overrides the default behavior of Windows to paint disabled controls with the window background color
|
2015-06-12 13:14:38 +00:00
|
|
|
|
|
|
|
#if defined(Hiro_Window) && defined(Hiro_TabFrame)
|
|
|
|
if(!object->parentTabFrame(true) && window->self()->hbrush) {
|
|
|
|
SetBkColor((HDC)wparam, window->self()->hbrushColor);
|
|
|
|
return (LRESULT)window->self()->hbrush;
|
2013-12-21 10:45:58 +00:00
|
|
|
}
|
2015-06-12 13:14:38 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined(Hiro_HexEdit)
|
|
|
|
if(auto hexEdit = dynamic_cast<mHexEdit*>(object)) {
|
|
|
|
if(auto background = hexEdit->backgroundColor()) SetBkColor((HDC)wparam, CreateRGB(background));
|
|
|
|
if(auto foreground = hexEdit->foregroundColor()) SetTextColor((HDC)wparam, CreateRGB(foreground));
|
|
|
|
return (LRESULT)hexEdit->self()->backgroundBrush;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined(Hiro_LineEdit)
|
|
|
|
if(auto lineEdit = dynamic_cast<mLineEdit*>(object)) {
|
|
|
|
if(auto background = lineEdit->backgroundColor()) SetBkColor((HDC)wparam, CreateRGB(background));
|
|
|
|
if(auto foreground = lineEdit->foregroundColor()) SetTextColor((HDC)wparam, CreateRGB(foreground));
|
|
|
|
return (LRESULT)lineEdit->self()->backgroundBrush;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined(Hiro_TextEdit)
|
|
|
|
if(auto textEdit = dynamic_cast<mTextEdit*>(object)) {
|
|
|
|
if(auto background = textEdit->backgroundColor()) SetBkColor((HDC)wparam, CreateRGB(background));
|
|
|
|
if(auto foreground = textEdit->foregroundColor()) SetTextColor((HDC)wparam, CreateRGB(foreground));
|
|
|
|
return (LRESULT)textEdit->self()->backgroundBrush;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2013-11-28 10:32:53 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2013-11-28 10:29:01 +00:00
|
|
|
case WM_DRAWITEM: {
|
2015-06-12 13:14:38 +00:00
|
|
|
auto drawItem = (LPDRAWITEMSTRUCT)lparam;
|
|
|
|
auto object = (mObject*)GetWindowLongPtr((HWND)drawItem->hwndItem, GWLP_USERDATA);
|
|
|
|
if(!object) break;
|
|
|
|
|
|
|
|
#if defined(Hiro_TabFrame)
|
|
|
|
if(auto tabFrame = dynamic_cast<mTabFrame*>(object)) {
|
|
|
|
return tabFrame->self()->onDrawItem(lparam), true;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2013-11-28 10:29:01 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2015-06-12 13:14:38 +00:00
|
|
|
case WM_MENUCOMMAND: {
|
|
|
|
return Menu_windowProc(hwnd, msg, wparam, lparam);
|
|
|
|
}
|
|
|
|
|
2013-11-28 10:29:01 +00:00
|
|
|
case WM_COMMAND: {
|
2015-06-12 13:14:38 +00:00
|
|
|
if(!lparam) break;
|
|
|
|
auto object = (mObject*)GetWindowLongPtr((HWND)lparam, GWLP_USERDATA);
|
|
|
|
if(!object) break;
|
|
|
|
|
|
|
|
#if defined(Hiro_Button)
|
|
|
|
if(auto button = dynamic_cast<mButton*>(object)) {
|
|
|
|
return button->self()->onActivate(), false;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined(Hiro_CheckButton)
|
|
|
|
if(auto checkButton = dynamic_cast<mCheckButton*>(object)) {
|
|
|
|
return checkButton->self()->onToggle(), false;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined(Hiro_CheckLabel)
|
|
|
|
if(auto checkLabel = dynamic_cast<mCheckLabel*>(object)) {
|
|
|
|
return checkLabel->self()->onToggle(), false;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined(Hiro_ComboButton)
|
|
|
|
if(auto comboButton = dynamic_cast<mComboButton*>(object)) {
|
|
|
|
if(HIWORD(wparam) == CBN_SELCHANGE) {
|
|
|
|
return comboButton->self()->onChange(), false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined(Hiro_LineEdit)
|
|
|
|
if(auto lineEdit = dynamic_cast<mLineEdit*>(object)) {
|
|
|
|
if(HIWORD(wparam) == EN_CHANGE) {
|
|
|
|
return lineEdit->self()->onChange(), false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined(Hiro_RadioButton)
|
|
|
|
if(auto radioButton = dynamic_cast<mRadioButton*>(object)) {
|
|
|
|
return radioButton->self()->onActivate(), false;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined(Hiro_RadioLabel)
|
|
|
|
if(auto radioLabel = dynamic_cast<mRadioLabel*>(object)) {
|
|
|
|
return radioLabel->self()->onActivate(), false;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined(Hiro_TextEdit)
|
|
|
|
if(auto textEdit = dynamic_cast<mTextEdit*>(object)) {
|
|
|
|
if(HIWORD(wparam) == EN_CHANGE) {
|
|
|
|
return textEdit->self()->onChange(), false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2013-11-28 10:29:01 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case WM_NOTIFY: {
|
2015-10-03 06:25:39 +00:00
|
|
|
//Widgets inside a TabFrame must be parented to it rather than the Window.
|
|
|
|
//This is critical for proper inheritance of styles and message passing.
|
|
|
|
//However, by doing this, some WM_NOTIFY messages end up being sent to both
|
|
|
|
//the TabFrame and the Window; while others are only sent to the TabFrame.
|
|
|
|
//To save code, hiro uses a shared callback for both of these cases.
|
|
|
|
//So when a message is sent to both, we ignore the TabFrame message.
|
2015-08-24 09:42:11 +00:00
|
|
|
bool isWindowCallback = (object == window);
|
|
|
|
|
2015-06-12 13:14:38 +00:00
|
|
|
auto header = (LPNMHDR)lparam;
|
|
|
|
auto object = (mObject*)GetWindowLongPtr((HWND)header->hwndFrom, GWLP_USERDATA);
|
|
|
|
if(!object) break;
|
|
|
|
|
|
|
|
#if defined(Hiro_ListView)
|
|
|
|
if(auto listView = dynamic_cast<mListView*>(object)) {
|
|
|
|
if(header->code == LVN_ITEMACTIVATE) {
|
|
|
|
listView->self()->onActivate(lparam);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if(header->code == LVN_ITEMCHANGED) {
|
|
|
|
listView->self()->onChange(lparam);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if(header->code == LVN_COLUMNCLICK) {
|
2015-10-03 06:25:39 +00:00
|
|
|
if(isWindowCallback) listView->self()->onSort(lparam);
|
2015-06-12 13:14:38 +00:00
|
|
|
break;
|
|
|
|
}
|
Update to v094r40 release.
byuu says:
Changelog:
- updated to newest hiro API
- SFC performance profile builds once again
- hiro: Qt port completed
Errata 1: the hiro/Qt target won't run tomoko just yet. Starts by
crashing inside InputSettings because hiro/Qt isn't forcefully selecting
the first item added to a ComboButton just yet. Even with a monkey patch
to get around that, the UI is incredibly unstable. Lots of geometry
calculation bugs, and a crash when you try and access certain folders in
the browser dialog. Lots of work left to be done there, sadly.
Errata 2: the hiro/Windows port has black backgrounds on all ListView
items. It's because I need to test for unassigned colors and grab the
default Windows brush colors in those cases.
Note: alternating row colors on multi-column ListView widgets is gone
now. Not a bug. May add it back later, but I'm not sure. It doesn't
interact nicely with per-cell background colors.
Things left to do:
First, I have to fix the Windows and Qt target bugs.
Next, I need to go through and revise the hiro API even more (nothing
too major.)
Next, I need to update icarus to use the new hiro API, and add support
for the SFC games database.
Next, I have to rewrite my TSV->BML cheat code tool.
Next, I need to post a final WIP of higan+icarus publicly and wait a few
days.
Next, I need to fix any bugs reported from the final WIP that I can.
Finally, I should be able to release v095.
2015-08-18 10:18:00 +00:00
|
|
|
if(header->code == NM_CLICK || header->code == NM_DBLCLK) {
|
2015-08-24 09:42:11 +00:00
|
|
|
//onToggle performs the test to ensure the ListViewItem clicked was checkable
|
2015-10-03 06:25:39 +00:00
|
|
|
if(isWindowCallback) listView->self()->onToggle(lparam);
|
Update to v094r40 release.
byuu says:
Changelog:
- updated to newest hiro API
- SFC performance profile builds once again
- hiro: Qt port completed
Errata 1: the hiro/Qt target won't run tomoko just yet. Starts by
crashing inside InputSettings because hiro/Qt isn't forcefully selecting
the first item added to a ComboButton just yet. Even with a monkey patch
to get around that, the UI is incredibly unstable. Lots of geometry
calculation bugs, and a crash when you try and access certain folders in
the browser dialog. Lots of work left to be done there, sadly.
Errata 2: the hiro/Windows port has black backgrounds on all ListView
items. It's because I need to test for unassigned colors and grab the
default Windows brush colors in those cases.
Note: alternating row colors on multi-column ListView widgets is gone
now. Not a bug. May add it back later, but I'm not sure. It doesn't
interact nicely with per-cell background colors.
Things left to do:
First, I have to fix the Windows and Qt target bugs.
Next, I need to go through and revise the hiro API even more (nothing
too major.)
Next, I need to update icarus to use the new hiro API, and add support
for the SFC games database.
Next, I have to rewrite my TSV->BML cheat code tool.
Next, I need to post a final WIP of higan+icarus publicly and wait a few
days.
Next, I need to fix any bugs reported from the final WIP that I can.
Finally, I should be able to release v095.
2015-08-18 10:18:00 +00:00
|
|
|
break;
|
|
|
|
}
|
2015-06-12 13:14:38 +00:00
|
|
|
if(header->code == NM_RCLICK) {
|
2015-10-03 06:25:39 +00:00
|
|
|
if(isWindowCallback) listView->self()->onContext(lparam);
|
2015-06-12 13:14:38 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
if(header->code == NM_CUSTOMDRAW) {
|
|
|
|
return listView->self()->onCustomDraw(lparam);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined(Hiro_TabFrame)
|
|
|
|
if(auto tabFrame = dynamic_cast<mTabFrame*>(object)) {
|
|
|
|
if(header->code == TCN_SELCHANGE) {
|
|
|
|
tabFrame->self()->onChange();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2013-11-28 10:29:01 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2015-06-12 13:14:38 +00:00
|
|
|
#if defined(Hiro_ListView)
|
2015-07-02 10:22:24 +00:00
|
|
|
case AppMessage::ListView_doPaint: {
|
|
|
|
if(auto listView = (mListView*)lparam) {
|
|
|
|
if(auto self = listView->self()) InvalidateRect(self->hwnd, nullptr, true);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2015-06-12 13:14:38 +00:00
|
|
|
case AppMessage::ListView_onActivate: {
|
|
|
|
if(auto listView = (mListView*)lparam) listView->doActivate();
|
Update to v094 release.
byuu says:
This release adds support for game libraries, and substantially improves
Game Boy and Game Boy Color emulation with cycle-based renderers. Many
other changes are also present.
It's very important to note that this release now defaults to optimal
drivers rather than safe drivers. This is particularly important if you
do not have strong OpenGL 3.2 drivers. If performance is bad, go to
Settings -> Configuration -> Advanced, change the video driver, and
restart higan. In the rare case that you have trouble opening higan, you
can edit settings.bml directly and change the setting there. The Windows
safe driver is Direct3D, and the Linux safe driver is XShm.
Also note that although display emulation shaders are now supported,
they have not been included in this release as they are not ready yet.
The support has been built-in anyway, so that they can be tested by
everyone. Once refined, future releases of higan will come with built-in
shaders for each emulated system that simulates the unique display
characteristics of each.
Changelog (since v093):
- sfc: added SA-1 MDR support (fixes SD Gundam G-Next bug)
- sfc: remove random/ and config/, merge to system/ with better
randomization
- gb: improved color emulation palette contrast
- gbc: do not sort sprites by X-priority
- gbc: allow transparency on BG priority pixels
- gbc: VRAM DMA timing and register fixes
- gbc: block invalid VRAM DMA transfer source and target addresses
- gba: added LCD color emulation (without it, colors are grossly
over-saturated)
- gba: removed internal frame blending (use shaders to simulate motion
blur if desired)
- gba: added Game Boy Player support (adds joypad rumble support to
supported games)
- gba: SOUND_CTL_H is readable
- gb/gbc: PPU renderer is now cycle-based (major accuracy improvement)
- gb/gbc: OAM DMA runs in parallel with the CPU
- gb/gbc: only HRAM can be accessed during OAM DMA
- gb/gbc: fixed serialization of games with SRAM
- gb/gbc: disallow up+down or left+right at the same time
- gb/gbc: added weak hipass filter to remove DC bias
- gb/gbc: STAT OAM+Hblank IRQs only trigger during active display
- gb/gbc: fixed underflow in window clamping
- gb/gbc/gba: audio mixes internally at 2MHz now instead of 4MHz (does
not affect accuracy)
- gb/gbc/gba: audio volume reduced for consistency with other systems
- fc/sfc/gb/gbc/gba: cheat codes are now stored in universal, decrypted
format
- ethos: replaced file loader with a proper game library
- ethos: added display emulation shader support
- ethos: added color emulation option to video settings
- ethos: program icon upgraded from 48x48 to 512x512
- ethos: settings and tools windows now use tab frames (less wasted
screen space)
- ethos: default to optimal (video, audio, input) drivers instead of
safest drivers
- ethos: input mapping system completely rewritten to support
hotplugging and unique device mappings
- ruby: added fixes for OpenGL 3.2 on AMD graphics cards
- ruby: quark shaders now support user settings inside of manifest
- ruby: quark shaders can use integral textures (allows display
emulation shaders to work with raw colors)
- ruby: add joypad rumble support
- ruby: XInput (Xbox 360) controllers now support hotplugging
- ruby: added Linux udev joypad driver with hotplug support
- phoenix: fixed a rare null pointer dereference issue on Windows
- port: target -std=c++11 instead of -std=gnu++11 (do not rely on GNU
C++ extensions)
- port: added out-of-the-box compilation support for BSD/Clang 3.3+
- port: applied a few Debian upstream patches
- cheats: updated to mightymo's 2014-01-02 release; decrypted all Game
Genie codes
2014-01-20 08:55:17 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2015-06-12 13:14:38 +00:00
|
|
|
case AppMessage::ListView_onChange: {
|
|
|
|
if(auto listView = (mListView*)lparam) listView->doChange();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2013-11-28 10:29:01 +00:00
|
|
|
case WM_HSCROLL:
|
|
|
|
case WM_VSCROLL: {
|
2015-06-12 13:14:38 +00:00
|
|
|
if(!lparam) break;
|
|
|
|
auto object = (mObject*)GetWindowLongPtr((HWND)lparam, GWLP_USERDATA);
|
|
|
|
if(!object) break;
|
|
|
|
|
2015-08-21 10:56:39 +00:00
|
|
|
#if defined(Hiro_HorizontalScrollBar)
|
|
|
|
if(auto horizontalScrollBar = dynamic_cast<mHorizontalScrollBar*>(object)) {
|
|
|
|
return horizontalScrollBar->self()->onChange(wparam), true;
|
2015-06-12 13:14:38 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined(Hiro_HorizontalSlider)
|
|
|
|
if(auto horizontalSlider = dynamic_cast<mHorizontalSlider*>(object)) {
|
|
|
|
return horizontalSlider->self()->onChange(), true;
|
2013-11-28 10:29:01 +00:00
|
|
|
}
|
2015-06-12 13:14:38 +00:00
|
|
|
#endif
|
|
|
|
|
2015-08-21 10:56:39 +00:00
|
|
|
#if defined(Hiro_VerticalScrollBar)
|
|
|
|
if(auto verticalScrollBar = dynamic_cast<mVerticalScrollBar*>(object)) {
|
|
|
|
return verticalScrollBar->self()->onChange(wparam), true;
|
2015-06-12 13:14:38 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined(Hiro_VerticalSlider)
|
|
|
|
if(auto verticalSlider = dynamic_cast<mVerticalSlider*>(object)) {
|
|
|
|
return verticalSlider->self()->onChange(), true;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2013-11-28 10:29:01 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return windowProc(hwnd, msg, wparam, lparam);
|
|
|
|
}
|
|
|
|
|
2013-03-15 13:11:33 +00:00
|
|
|
}
|