diff --git a/src/interface.cc b/src/interface.cc index 9d4b416..a1b1115 100644 --- a/src/interface.cc +++ b/src/interface.cc @@ -127,6 +127,12 @@ static bool indicatorBarAdd(int indicator); static void customInterfaceBarInit(); static void customInterfaceBarExit(); +static void sidePanelsInit(); +static void sidePanelsExit(); +static void sidePanelsHide(); +static void sidePanelsShow(); +static void sidePanelsDraw(const char* path, int win, bool isLeading); + // 0x518F08 static bool gInterfaceBarInitialized = false; @@ -288,6 +294,11 @@ int gInterfaceBarWidth = -1; bool gInterfaceBarIsCustom = false; static Art* gCustomInterfaceBarBackground = nullptr; +int gInterfaceSidePanelsImageId = 2; +bool gInterfaceSidePanelsExtendFromScreenEdge = false; +static int gInterfaceSidePanelsLeadingWindow = -1; +static int gInterfaceSidePanelsTrailingWindow = -1; + // intface_init // 0x45D880 int interfaceInit() @@ -566,6 +577,9 @@ int interfaceInit() displayMonitorInit(); + // SFALL + sidePanelsInit(); + gInterfaceBarEnabled = true; gInterfaceBarInitialized = false; _intfaceHidden = 1; @@ -594,6 +608,9 @@ void interfaceReset() void interfaceFree() { if (gInterfaceBarWindow != -1) { + // SFALL + sidePanelsExit(); + displayMonitorExit(); _redLightFrmImage.unlock(); @@ -765,6 +782,10 @@ void intface_hide() _intfaceHidden = 1; } } + + // SFALL + sidePanelsHide(); + indicatorBarRefresh(); } @@ -777,9 +798,14 @@ void _intface_show() interfaceRenderHitPoints(false); interfaceRenderArmorClass(false); windowUnhide(gInterfaceBarWindow); + sidePanelsShow(); _intfaceHidden = false; } } + + // SFALL + sidePanelsShow(); + indicatorBarRefresh(); } @@ -2496,4 +2522,114 @@ unsigned char* customInterfaceBarGetBackgroundImageData() return artGetFrameData(gCustomInterfaceBarBackground, 0, 0); } +static void sidePanelsInit() +{ + if (gInterfaceBarMode) { + return; + } + + if (gInterfaceSidePanelsImageId == 0) { + return; + } + + if (gInterfaceBarWidth >= screenGetWidth()) { + return; + } + + Rect windowRect; + windowGetRect(gInterfaceBarWindow, &windowRect); + + gInterfaceSidePanelsLeadingWindow = windowCreate(0, windowRect.top, windowRect.left, windowRect.bottom - windowRect.top + 1, 0, WINDOW_HIDDEN | WINDOW_FLAG_0x02); + gInterfaceSidePanelsTrailingWindow = windowCreate(windowRect.right + 1, windowRect.top, screenGetWidth() - windowRect.right - 1, windowRect.bottom - windowRect.top + 1, 0, WINDOW_HIDDEN | WINDOW_FLAG_0x02); + + char path[COMPAT_MAX_PATH]; + sprintf(path, "art\\intrface\\HR_IFACELFT%d.frm", gInterfaceSidePanelsImageId); + sidePanelsDraw(path, gInterfaceSidePanelsLeadingWindow, true); + + sprintf(path, "art\\intrface\\HR_IFACERHT%d.frm", gInterfaceSidePanelsImageId); + sidePanelsDraw(path, gInterfaceSidePanelsTrailingWindow, false); +} + +static void sidePanelsExit() +{ + if (gInterfaceSidePanelsTrailingWindow != -1) { + windowDestroy(gInterfaceSidePanelsTrailingWindow); + gInterfaceSidePanelsTrailingWindow = -1; + } + + if (gInterfaceSidePanelsLeadingWindow != -1) { + windowDestroy(gInterfaceSidePanelsLeadingWindow); + gInterfaceSidePanelsLeadingWindow = -1; + } +} + +static void sidePanelsHide() +{ + if (gInterfaceSidePanelsLeadingWindow != -1) { + windowHide(gInterfaceSidePanelsLeadingWindow); + } + + if (gInterfaceSidePanelsTrailingWindow != -1) { + windowHide(gInterfaceSidePanelsTrailingWindow); + } +} + +static void sidePanelsShow() +{ + if (gInterfaceSidePanelsLeadingWindow != -1) { + windowUnhide(gInterfaceSidePanelsLeadingWindow); + } + + if (gInterfaceSidePanelsTrailingWindow != -1) { + windowUnhide(gInterfaceSidePanelsTrailingWindow); + } +} + +static void sidePanelsDraw(const char* path, int win, bool isLeading) +{ + int size; + if (dbGetFileSize(path, &size) != 0) { + return; + } + + Art* image = reinterpret_cast(internal_malloc(size)); + if (image == nullptr) { + return; + } + + if (artRead(path, reinterpret_cast(image)) != 0) { + internal_free(image); + return; + } + + unsigned char* imageData = artGetFrameData(image, 0, 0); + + int imageWidth = artGetWidth(image, 0, 0); + int imageHeight = artGetHeight(image, 0, 0); + + int windowWidth = windowGetWidth(win); + int windowHeight = windowGetHeight(win); + + int width = std::min(imageWidth, windowWidth); + + if (!gInterfaceSidePanelsExtendFromScreenEdge && isLeading) { + imageData += imageWidth - width; + } + + if (gInterfaceSidePanelsExtendFromScreenEdge && !isLeading) { + imageData += imageWidth - width; + } + + blitBufferToBufferStretch(imageData, + width, + imageHeight, + imageWidth, + windowGetBuffer(win), + windowWidth, + windowHeight, + windowWidth); + + internal_free(image); +} + } // namespace fallout diff --git a/src/interface.h b/src/interface.h index fee94e9..3dcb66a 100644 --- a/src/interface.h +++ b/src/interface.h @@ -36,6 +36,8 @@ extern bool gInterfaceBarMode; extern int gInterfaceBarWidth; extern bool gInterfaceBarIsCustom; extern int gInterfaceBarContentOffset; +extern int gInterfaceSidePanelsImageId; +extern bool gInterfaceSidePanelsExtendFromScreenEdge; int interfaceInit(); void interfaceReset(); diff --git a/src/svga.cc b/src/svga.cc index 117ee59..da0237f 100644 --- a/src/svga.cc +++ b/src/svga.cc @@ -187,6 +187,8 @@ int _GNW95_init_mode_ex(int width, int height, int bpp) configGetBool(&resolutionConfig, "IFACE", "IFACE_BAR_MODE", &gInterfaceBarMode); configGetInt(&resolutionConfig, "IFACE", "IFACE_BAR_WIDTH", &gInterfaceBarWidth); + configGetInt(&resolutionConfig, "IFACE", "IFACE_BAR_SIDE_ART", &gInterfaceSidePanelsImageId); + configGetBool(&resolutionConfig, "IFACE", "IFACE_BAR_SIDES_ORI", &gInterfaceSidePanelsExtendFromScreenEdge); } configFree(&resolutionConfig); }