Displays: on-screen cockpit buttons + desktop plasma + the glass preset (steps 2d/2e)
NEW gated TUs: L4PADPANEL (GDI top-level window, all-W APIs: the pod button banks -- upper/lower aux, 12 secondary, specials/hat/handle, 63 buttons -- clickable via PadRIO::SetScreenButton with lamp-lit faces from GetLampState, 10 Hz repaint; created by the PadRIO ctor on BT_PAD_PANEL=1) and L4PLASMAWIN (PlasmaWindow : Video8BitBuffered -- the gauge renderer draws the 128x32 plasma into its pixelBuffer through the SAME code path as the serial device; Update() blits orange-on-black at L4PLASMASCALE, default x4). Gated seams: L4GREND.cpp L4PLASMA=SCREEN branch; btl4main.cpp -platform glass preset (PAD,KEYBOARD + BT_DEV_GAUGES + SCREEN plasma + panel; env always overrides; non-glass builds log+fall back to DEV); run.cmd glass token. MFD surfaces need NO new code: the existing dock-bottom / BT_DEV_GAUGES_WINDOW=1 / BT_DEV_GAUGES_DOCK=1 modes are the display story. Verified live: -platform glass boots GLASS profile, panel + plasma windows up, pad detected, dev gauges awake, mission loop clean. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,167 @@
|
||||
#include "mungal4.h"
|
||||
#pragma hdrstop
|
||||
|
||||
//###########################################################################
|
||||
// L4PLASMAWIN -- the desktop plasma display (BT_GLASS only; this TU is only
|
||||
// in the build when the gate is on -- see CMakeLists.txt).
|
||||
// Design: L4PLASMAWIN.h.
|
||||
//###########################################################################
|
||||
|
||||
#include "l4plasmawin.h"
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static LRESULT CALLBACK
|
||||
PlasmaWndProc(HWND window, UINT message, WPARAM wparam, LPARAM lparam)
|
||||
{
|
||||
switch (message)
|
||||
{
|
||||
case WM_CLOSE:
|
||||
ShowWindow(window, SW_HIDE); // hide only; the renderer owns it
|
||||
return 0;
|
||||
}
|
||||
return DefWindowProcW(window, message, wparam, lparam);
|
||||
}
|
||||
|
||||
//###########################################################################
|
||||
|
||||
PlasmaWindow::PlasmaWindow():
|
||||
Video8BitBuffered(plasmaWidth, plasmaHeight),
|
||||
window(NULL),
|
||||
blitBuffer(NULL)
|
||||
{
|
||||
scale = 4;
|
||||
const char *scale_string = getenv("L4PLASMASCALE");
|
||||
if (scale_string != NULL)
|
||||
{
|
||||
int v = atoi(scale_string);
|
||||
if (v >= 1 && v <= 16)
|
||||
{
|
||||
scale = v;
|
||||
}
|
||||
}
|
||||
blitBuffer = new unsigned long[plasmaWidth * plasmaHeight];
|
||||
memset(blitBuffer, 0, plasmaWidth * plasmaHeight * sizeof(unsigned long));
|
||||
DEBUG_STREAM << "[plasmawin] desktop plasma display up (scale x"
|
||||
<< scale << ")\n" << std::flush;
|
||||
}
|
||||
|
||||
PlasmaWindow::~PlasmaWindow()
|
||||
{
|
||||
if (window != NULL)
|
||||
{
|
||||
DestroyWindow((HWND)window);
|
||||
window = NULL;
|
||||
}
|
||||
delete[] blitBuffer;
|
||||
blitBuffer = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
PlasmaWindow::EnsureWindow()
|
||||
{
|
||||
if (window != NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
WNDCLASSW window_class;
|
||||
memset(&window_class, 0, sizeof(window_class));
|
||||
window_class.lpfnWndProc = PlasmaWndProc;
|
||||
window_class.hInstance = GetModuleHandleW(NULL);
|
||||
window_class.hCursor = LoadCursorW(NULL, (LPCWSTR)IDC_ARROW);
|
||||
window_class.lpszClassName = L"BTPlasmaWnd";
|
||||
RegisterClassW(&window_class);
|
||||
|
||||
RECT frame = { 0, 0, plasmaWidth * scale, plasmaHeight * scale };
|
||||
DWORD style = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX;
|
||||
AdjustWindowRect(&frame, style, FALSE);
|
||||
|
||||
window = CreateWindowW(
|
||||
L"BTPlasmaWnd", L"BattleTech - Plasma",
|
||||
style,
|
||||
40, 480,
|
||||
frame.right - frame.left, frame.bottom - frame.top,
|
||||
NULL, NULL, GetModuleHandleW(NULL), NULL);
|
||||
if (window == NULL)
|
||||
{
|
||||
DEBUG_STREAM << "[plasmawin] CreateWindow failed\n" << std::flush;
|
||||
return;
|
||||
}
|
||||
ShowWindow((HWND)window, SW_SHOWNOACTIVATE);
|
||||
}
|
||||
|
||||
//
|
||||
// The per-frame external-display flush (the gauge renderer calls this
|
||||
// where the serial path streams changed lines out the COM port). Blits
|
||||
// the whole 8-bit buffer as orange-on-black. Returns False = done (no
|
||||
// multi-call transfer in progress, unlike the serial path).
|
||||
//
|
||||
Logical
|
||||
PlasmaWindow::Update(Logical force_all)
|
||||
{
|
||||
(void)force_all;
|
||||
EnsureWindow();
|
||||
if (window == NULL || pixelBuffer == NULL ||
|
||||
pixelBuffer->Data.MapPointer == NULL)
|
||||
{
|
||||
return False;
|
||||
}
|
||||
|
||||
//
|
||||
// 8-bit index -> BGRA: any lit index renders plasma orange, intensity
|
||||
// stepped a little by index so shaded glyphs keep their shape. The
|
||||
// engine's graphics coordinate system puts (0,0) bottom-left; the
|
||||
// window is top-down, so flip Y in the copy.
|
||||
//
|
||||
const Byte *source = pixelBuffer->Data.MapPointer;
|
||||
for (int y = 0; y < plasmaHeight; ++y)
|
||||
{
|
||||
const Byte *line = source + (plasmaHeight - 1 - y) * plasmaWidth;
|
||||
unsigned long *destination = blitBuffer + y * plasmaWidth;
|
||||
for (int x = 0; x < plasmaWidth; ++x)
|
||||
{
|
||||
Byte index = line[x];
|
||||
if (index == 0)
|
||||
{
|
||||
destination[x] = 0x00180800; // near-black
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned long intensity = 160 + (index % 6) * 19; // 160..255
|
||||
destination[x] =
|
||||
(intensity << 16) | // R
|
||||
((intensity * 140 / 255) << 8); // G (amber)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BITMAPINFO info;
|
||||
memset(&info, 0, sizeof(info));
|
||||
info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||||
info.bmiHeader.biWidth = plasmaWidth;
|
||||
info.bmiHeader.biHeight = -plasmaHeight; // top-down
|
||||
info.bmiHeader.biPlanes = 1;
|
||||
info.bmiHeader.biBitCount = 32;
|
||||
info.bmiHeader.biCompression = BI_RGB;
|
||||
|
||||
HDC dc = GetDC((HWND)window);
|
||||
if (dc != NULL)
|
||||
{
|
||||
RECT client;
|
||||
GetClientRect((HWND)window, &client);
|
||||
StretchDIBits(dc,
|
||||
0, 0, client.right, client.bottom,
|
||||
0, 0, plasmaWidth, plasmaHeight,
|
||||
blitBuffer, &info, DIB_RGB_COLORS, SRCCOPY);
|
||||
ReleaseDC((HWND)window, dc);
|
||||
}
|
||||
return False;
|
||||
}
|
||||
|
||||
void
|
||||
PlasmaWindow::WaitForUpdate()
|
||||
{
|
||||
}
|
||||
Reference in New Issue
Block a user