#include "..\munga_l4\mungal4.h" #pragma hdrstop #include "rpl4fe.h" #include #include //######################################################################## // The Death Race catalog (from TeslaConsole's RedPlanet/RPConfig.xml; // 'headmf' is excluded for the race scenario there). //######################################################################## namespace { struct CatalogEntry { const char *key; const char *name; }; const CatalogEntry kMaps[] = { { "wise", "Wiseguy's Wake" }, { "lyzlane", "Lyz's Lane" }, { "yip", "Yip's Yahoorama" }, { "blade", "Blade's Edge" }, { "otto", "Berserker's Bahnzai" }, { "frstrm", "Firestorm's Fury" }, { "burnt", "Burnt Cookies" }, { "brewers", "Brewer's Bane" }, { "pain", "Paingod's Passage" }, { "headoff", "Freezemoon's Freeway" }, }; const CatalogEntry kVehicles[] = { { "quark", "Quark" }, { "lepton", "Lepton" }, { "proton", "Proton" }, { "bug", "Bug" }, { "speck", "Speck" }, { "blkspk", "Black Speck" }, { "chigger", "Chigger" }, { "flea", "Flea" }, { "roach", "Roach" }, { "skeeter", "Skeeter" }, { "wasp", "Wasp" }, { "barge", "Barge" }, { "broccoli", "Screaming Broccoli" }, { "burro", "Burro" }, { "mule", "Mule" }, { "bttlbrg", "Battle Barge" }, { "gator", "Gator" }, { "grunt", "Grunt" }, { "vole", "Vole" }, { "bull", "Bull" }, { "tarntula", "Tarantula" }, { "mantis", "Mantis" }, { "ripper", "Ripper" }, { "roadblk", "Road Block" }, { "spitter", "Spitter" }, { "puck", "Armadillo" }, { "dragon", "Dragon" }, }; const CatalogEntry kColors[] = { { "Red", "Red" }, { "Blue", "Blue" }, { "Green", "Green" }, { "White", "White" }, { "Pink", "Pink" }, { "Aqua", "Aqua" }, { "Yellow", "Yellow" }, { "Purple", "Purple" }, { "Black", "Black" }, }; const CatalogEntry kBadges[] = { { "None", "None" }, { "Celtic", "Celtic" }, { "Desert", "Desert" }, { "Flames", "Flames" }, { "Giraffe", "Giraffe" }, { "Hawaii", "Hawaii" }, { "Korean", "Korean Camo" }, { "Lightning", "Lightning" }, { "Razzle Dazzle", "Razzle Dazzle" }, { "Rising Sun", "Rising Sun" }, { "Tiger Stripe", "Tiger Stripes" }, }; const CatalogEntry kTimes[] = { { "day", "Day" }, { "night", "Night" }, }; const CatalogEntry kWeather[] = { { "clear", "Clear" }, { "fog", "Light Fog" }, { "soup", "Heavy Fog" }, }; struct LengthEntry { int seconds; // 0 = endless (length line omitted) const char *name; }; const LengthEntry kLengths[] = { { 0, "Endless" }, { 180, "3:00" }, { 300, "5:00" }, { 480, "8:00" }, { 600, "10:00" }, }; // Standalone pilot address, as used by TEST.EGG: single-user mode // adopts the first pilot entry without resolving it. const char kLocalPilotAddress[] = "200.0.0.255"; #define FE_COUNT(t) ((int)(sizeof(t)/sizeof((t)[0]))) //--------------------------------------------------------------- // Menu model //--------------------------------------------------------------- enum FEGroup { GroupMap = 0, GroupVehicle, GroupColor, GroupBadge, GroupTime, GroupWeather, GroupLength, GroupLaunch, GroupCount }; struct FEItem { int group; int index; RECT rect; }; struct FEState { int selection[GroupCount]; char pilotName[24]; FEItem items[128]; int itemCount; HWND menuWindow; HWND nameEdit; HFONT textFont; HFONT titleFont; HBRUSH editBrush; Logical launched; Logical closed; }; FEState *gFE = NULL; int gLastMissionSeconds = 0; const COLORREF kGreenBright = RGB(64, 255, 64); const COLORREF kGreenDim = RGB(24, 140, 24); const COLORREF kBlack = RGB(0, 0, 0); //--------------------------------------------------------------- // Layout: three columns of lists + the launch button //--------------------------------------------------------------- void AddGroupItems( FEState *fe, int group, int count, int x, int *y, int row_h, int width) { for (int i = 0; i < count; ++i) { FEItem *item = &fe->items[fe->itemCount++]; item->group = group; item->index = i; item->rect.left = x; item->rect.top = *y; item->rect.right = x + width; item->rect.bottom = *y + row_h; *y += row_h; } *y += row_h; // gap below the group } void LayoutMenu(FEState *fe, int client_w, int client_h) { fe->itemCount = 0; int row_h = client_h / 36; if (row_h < 18) row_h = 18; if (row_h > 30) row_h = 30; int col_w = client_w / 5; int col1 = client_w / 14; int col2 = col1 + col_w + client_w / 28; int col3 = col2 + col_w + client_w / 28; int top = client_h / 7; int y = top; AddGroupItems(fe, GroupMap, FE_COUNT(kMaps), col1, &y, row_h, col_w); int y_after_maps = y; AddGroupItems(fe, GroupTime, FE_COUNT(kTimes), col1, &y, row_h, col_w); AddGroupItems(fe, GroupWeather, FE_COUNT(kWeather), col1, &y, row_h, col_w); AddGroupItems(fe, GroupLength, FE_COUNT(kLengths), col1, &y, row_h, col_w); y = top; AddGroupItems(fe, GroupVehicle, FE_COUNT(kVehicles), col2, &y, row_h, col_w); y = top + 2 * row_h; // leave room for the name edit + header AddGroupItems(fe, GroupColor, FE_COUNT(kColors), col3, &y, row_h, col_w); AddGroupItems(fe, GroupBadge, FE_COUNT(kBadges), col3, &y, row_h, col_w); // launch button FEItem *launch = &fe->items[fe->itemCount++]; launch->group = GroupLaunch; launch->index = 0; launch->rect.left = col3; launch->rect.top = client_h - 3 * row_h; launch->rect.right = col3 + col_w; launch->rect.bottom = client_h - row_h; // pilot name edit sits at the top of column 3 if (fe->nameEdit != NULL) { MoveWindow(fe->nameEdit, col3, top - row_h / 4, col_w, row_h, TRUE); } } const char *GroupTitle(int group) { switch (group) { case GroupMap: return "TRACK"; case GroupVehicle: return "VEHICLE"; case GroupColor: return "COLOR"; case GroupBadge: return "BADGE"; case GroupTime: return "TIME OF DAY"; case GroupWeather: return "WEATHER"; case GroupLength: return "RACE LENGTH"; } return ""; } const char *ItemName(int group, int index) { switch (group) { case GroupMap: return kMaps[index].name; case GroupVehicle: return kVehicles[index].name; case GroupColor: return kColors[index].name; case GroupBadge: return kBadges[index].name; case GroupTime: return kTimes[index].name; case GroupWeather: return kWeather[index].name; case GroupLength: return kLengths[index].name; case GroupLaunch: return "L A U N C H R A C E"; } return ""; } //--------------------------------------------------------------- // Painting (double buffered, pod green on black) //--------------------------------------------------------------- void PaintMenu(FEState *fe) { PAINTSTRUCT ps; HDC hdc = BeginPaint(fe->menuWindow, &ps); RECT client; GetClientRect(fe->menuWindow, &client); HDC mem = CreateCompatibleDC(hdc); HBITMAP surface = CreateCompatibleBitmap(hdc, client.right, client.bottom); HBITMAP old_surface = (HBITMAP) SelectObject(mem, surface); FillRect(mem, &client, (HBRUSH) GetStockObject(BLACK_BRUSH)); SetBkMode(mem, TRANSPARENT); // title SelectObject(mem, fe->titleFont); SetTextColor(mem, kGreenBright); RECT title = client; title.top = client.bottom / 28; title.bottom = title.top + client.bottom / 10; DrawTextA(mem, "RED PLANET - MARTIAN DEATH RACE", -1, &title, DT_CENTER | DT_TOP | DT_SINGLELINE); SelectObject(mem, fe->textFont); // group headers (drawn above each group's first item) int previous_group = -1; for (int i = 0; i < fe->itemCount; ++i) { const FEItem *item = &fe->items[i]; if (item->group != previous_group && item->group != GroupLaunch) { previous_group = item->group; RECT header = item->rect; header.top -= (item->rect.bottom - item->rect.top); header.bottom = item->rect.top; SetTextColor(mem, kGreenBright); DrawTextA(mem, GroupTitle(item->group), -1, &header, DT_LEFT | DT_VCENTER | DT_SINGLELINE); } Logical selected = (item->group == GroupLaunch) || (fe->selection[item->group] == item->index); RECT row = item->rect; if (item->group == GroupLaunch) { HBRUSH launch_brush = CreateSolidBrush(kGreenBright); FrameRect(mem, &row, launch_brush); DeleteObject(launch_brush); SetTextColor(mem, kGreenBright); DrawTextA(mem, ItemName(item->group, item->index), -1, &row, DT_CENTER | DT_VCENTER | DT_SINGLELINE); continue; } if (selected) { HBRUSH sel_brush = CreateSolidBrush(kGreenDim); RECT fill = row; FillRect(mem, &fill, sel_brush); DeleteObject(sel_brush); SetTextColor(mem, kGreenBright); } else { SetTextColor(mem, kGreenDim); } RECT text = row; text.left += 6; DrawTextA(mem, ItemName(item->group, item->index), -1, &text, DT_LEFT | DT_VCENTER | DT_SINGLELINE); } // pilot-name header if (fe->nameEdit != NULL) { RECT edit_rect; GetWindowRect(fe->nameEdit, &edit_rect); POINT corner = { edit_rect.left, edit_rect.top }; ScreenToClient(fe->menuWindow, &corner); RECT header; header.left = corner.x; header.right = corner.x + 300; header.bottom = corner.y; header.top = corner.y - 26; SetTextColor(mem, kGreenBright); DrawTextA(mem, "PILOT NAME", -1, &header, DT_LEFT | DT_VCENTER | DT_SINGLELINE); } BitBlt(hdc, 0, 0, client.right, client.bottom, mem, 0, 0, SRCCOPY); SelectObject(mem, old_surface); DeleteObject(surface); DeleteDC(mem); EndPaint(fe->menuWindow, &ps); } void MenuClick(FEState *fe, int x, int y) { for (int i = 0; i < fe->itemCount; ++i) { const FEItem *item = &fe->items[i]; if (x >= item->rect.left && x < item->rect.right && y >= item->rect.top && y < item->rect.bottom) { if (item->group == GroupLaunch) { fe->launched = True; // wake the modal loop (a click delivered via // SendMessage never passes through the queue) PostMessageA(fe->menuWindow, WM_NULL, 0, 0); } else { fe->selection[item->group] = item->index; InvalidateRect(fe->menuWindow, NULL, FALSE); } return; } } } LRESULT CALLBACK FrontEndWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { FEState *fe = gFE; switch (message) { case WM_PAINT: if (fe != NULL) { PaintMenu(fe); return 0; } break; case WM_LBUTTONDOWN: if (fe != NULL) { MenuClick(fe, (int)(short) LOWORD(lParam), (int)(short) HIWORD(lParam)); return 0; } break; case WM_CTLCOLOREDIT: if (fe != NULL) { SetTextColor((HDC) wParam, kGreenBright); SetBkColor((HDC) wParam, kBlack); return (LRESULT) fe->editBrush; } break; case WM_ERASEBKGND: return 1; } return DefWindowProcA(hwnd, message, wParam, lParam); } //--------------------------------------------------------------- // Plasma name bitmaps: white text auto-fit into WxH, thresholded // to 1bpp hex rows - the C++ twin of the console's PlasmaBitmaps. //--------------------------------------------------------------- void AppendNameBitmap(std::string &egg, int width, int height, const char *name) { BITMAPINFO info; memset(&info, 0, sizeof(info)); info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); info.bmiHeader.biWidth = width; info.bmiHeader.biHeight = -height; // top-down info.bmiHeader.biPlanes = 1; info.bmiHeader.biBitCount = 32; info.bmiHeader.biCompression = BI_RGB; void *bits = NULL; HDC dc = CreateCompatibleDC(NULL); HBITMAP bitmap = CreateDIBSection(dc, &info, DIB_RGB_COLORS, &bits, NULL, 0); HBITMAP old_bitmap = (HBITMAP) SelectObject(dc, bitmap); memset(bits, 0, width * height * 4); SetBkMode(dc, TRANSPARENT); SetTextColor(dc, RGB(255, 255, 255)); // shrink the font until the name fits (console: 24pt downward) int point_size = 24; for (;;) { HFONT font = CreateFontA( -MulDiv(point_size, GetDeviceCaps(dc, LOGPIXELSY), 72), 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, NONANTIALIASED_QUALITY, DEFAULT_PITCH | FF_DONTCARE, "Microsoft Sans Serif"); HFONT old_font = (HFONT) SelectObject(dc, font); SIZE extent; GetTextExtentPoint32A(dc, name, (int) strlen(name), &extent); if ((extent.cx <= width && extent.cy <= height) || point_size <= 1) { RECT rect = { 0, 0, width, height }; DrawTextA(dc, name, -1, &rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE | DT_NOPREFIX); SelectObject(dc, old_font); DeleteObject(font); break; } SelectObject(dc, old_font); DeleteObject(font); point_size = (point_size <= 2) ? (point_size / 2) : (point_size - 2); } GdiFlush(); const unsigned long *pixels = (const unsigned long *) bits; char hex[8]; for (int row = 0; row < height; ++row) { egg += "bitmap="; for (int byte_index = 0; byte_index < width / 8; ++byte_index) { unsigned char packed = 0; for (int bit = 0; bit < 8; ++bit) { unsigned long pixel = pixels[row * width + byte_index * 8 + bit]; if ((pixel & 0xFF) >= 128) // white text on black { packed |= (unsigned char)(128 >> bit); } } sprintf(hex, "%02X", packed); egg += hex; } egg += "\n"; } sprintf(hex, "%d", width); egg += "x="; egg += hex; egg += "\n"; sprintf(hex, "%d", height); egg += "y="; egg += hex; egg += "\n"; SelectObject(dc, old_bitmap); DeleteObject(bitmap); DeleteDC(dc); } // The 1st-4th place plasma graphics, verbatim from the console // (RPMission.AppendOrdinals) / TEST.EGG. extern const char *kOrdinalsBlock; //--------------------------------------------------------------- // Egg assembly (console RPMission.ToEggString, race scenario, // one local pilot) //--------------------------------------------------------------- void BuildEggText(const FEState *fe, std::string &egg) { char line[256]; egg += "[mission]\n"; egg += "adventure=Red Planet\n"; sprintf(line, "map=%s\n", kMaps[fe->selection[GroupMap]].key); egg += line; egg += "scenario=race\n"; sprintf(line, "time=%s\n", kTimes[fe->selection[GroupTime]].key); egg += line; sprintf(line, "weather=%s\n", kWeather[fe->selection[GroupWeather]].key); egg += line; egg += "temperature=0\n"; egg += "compression=0\n"; int seconds = kLengths[fe->selection[GroupLength]].seconds; if (seconds > 0) { sprintf(line, "length=%d\n", seconds); egg += line; } egg += "[pilots]\n"; sprintf(line, "pilot=%s\n", kLocalPilotAddress); egg += line; sprintf(line, "[%s]\n", kLocalPilotAddress); egg += line; egg += "hostType=0\n"; egg += "dropzone=one\n"; sprintf(line, "name=%s\n", fe->pilotName); egg += line; egg += "bitmapindex=1\n"; egg += "loadzones=1\n"; sprintf(line, "vehicle=%s\n", kVehicles[fe->selection[GroupVehicle]].key); egg += line; sprintf(line, "color=%s\n", kColors[fe->selection[GroupColor]].key); egg += line; sprintf(line, "badge=%s\n", kBadges[fe->selection[GroupBadge]].key); egg += line; sprintf(line, "[largebitmap]\nbitmap=BitMap::Large::%s\n", fe->pilotName); egg += line; sprintf(line, "[smallbitmap]\nbitmap=BitMap::Small::%s\n", fe->pilotName); egg += line; sprintf(line, "[BitMap::Large::%s]\n", fe->pilotName); egg += line; AppendNameBitmap(egg, 128, 32, fe->pilotName); egg += "width=8\n"; sprintf(line, "[BitMap::Small::%s]\n", fe->pilotName); egg += line; AppendNameBitmap(egg, 64, 16, fe->pilotName); egg += "width=4\n"; egg += kOrdinalsBlock; } } //######################################################################## //############################ RPL4FrontEnd_Run ########################## //######################################################################## Logical RPL4FrontEnd_Run( HINSTANCE instance, HWND main_window, char *egg_path_out, int egg_path_size ) { FEState fe; memset(&fe, 0, sizeof(fe)); strcpy(fe.pilotName, "Pilot"); fe.selection[GroupLength] = 2; // 5:00 gFE = &fe; //--------------------------------------------------------------- // Window class + fonts //--------------------------------------------------------------- static Logical class_registered = False; if (!class_registered) { class_registered = True; WNDCLASSA window_class; memset(&window_class, 0, sizeof(window_class)); window_class.style = CS_HREDRAW | CS_VREDRAW; window_class.lpfnWndProc = FrontEndWndProc; window_class.hInstance = instance; window_class.hCursor = LoadCursor(NULL, IDC_ARROW); window_class.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH); window_class.lpszClassName = "RPFrontEnd"; RegisterClassA(&window_class); } RECT client; GetClientRect(main_window, &client); fe.menuWindow = CreateWindowExA( 0, "RPFrontEnd", "", WS_CHILD | WS_VISIBLE, 0, 0, client.right, client.bottom, main_window, NULL, instance, NULL); if (fe.menuWindow == NULL) { gFE = NULL; return False; } int text_h = client.bottom / 40; if (text_h < 16) text_h = 16; if (text_h > 24) text_h = 24; fe.textFont = CreateFontA(-text_h, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, CLEARTYPE_QUALITY, DEFAULT_PITCH | FF_MODERN, "Consolas"); fe.titleFont = CreateFontA(-(text_h * 2), 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, CLEARTYPE_QUALITY, DEFAULT_PITCH | FF_MODERN, "Consolas"); fe.editBrush = CreateSolidBrush(kBlack); fe.nameEdit = CreateWindowExA( 0, "EDIT", fe.pilotName, WS_CHILD | WS_VISIBLE | WS_BORDER | ES_AUTOHSCROLL, 0, 0, 10, 10, fe.menuWindow, NULL, instance, NULL); SendMessageA(fe.nameEdit, WM_SETFONT, (WPARAM) fe.textFont, TRUE); SendMessageA(fe.nameEdit, EM_SETLIMITTEXT, sizeof(fe.pilotName) - 2, 0); LayoutMenu(&fe, client.right, client.bottom); InvalidateRect(fe.menuWindow, NULL, TRUE); //--------------------------------------------------------------- // Modal loop until the player launches or closes the window //--------------------------------------------------------------- MSG msg; while (!fe.launched && !fe.closed) { BOOL result = GetMessageA(&msg, NULL, 0, 0); if (result <= 0) { fe.closed = True; break; } if (msg.message == WM_QUIT || (msg.message == WM_SYSCOMMAND && msg.wParam == SC_CLOSE)) { fe.closed = True; } // closing the main window ends the front end too if (msg.message == WM_CLOSE && msg.hwnd == main_window) { fe.closed = True; } TranslateMessage(&msg); DispatchMessageA(&msg); if (!IsWindow(main_window)) { fe.closed = True; } } Logical launched = fe.launched; if (launched) { gLastMissionSeconds = kLengths[fe.selection[GroupLength]].seconds; GetWindowTextA(fe.nameEdit, fe.pilotName, sizeof(fe.pilotName) - 1); if (fe.pilotName[0] == '\0') { strcpy(fe.pilotName, "Pilot"); } std::string egg; egg.reserve(16384); BuildEggText(&fe, egg); strncpy(egg_path_out, "frontend.egg", egg_path_size - 1); egg_path_out[egg_path_size - 1] = '\0'; FILE *file = fopen(egg_path_out, "wb"); if (file != NULL) { fwrite(egg.data(), 1, egg.size(), file); fclose(file); DEBUG_STREAM << "FrontEnd: wrote " << egg_path_out << " (" << (int) egg.size() << " bytes)\n" << std::flush; } else { DEBUG_STREAM << "FrontEnd: could not write " << egg_path_out << "\n" << std::flush; launched = False; } } DestroyWindow(fe.menuWindow); DeleteObject(fe.textFont); DeleteObject(fe.titleFont); DeleteObject(fe.editBrush); gFE = NULL; return launched; } int RPL4FrontEnd_LastMissionSeconds() { return gLastMissionSeconds; } //######################################################################## // Ordinal plasma graphics (verbatim from the console / TEST.EGG) //######################################################################## namespace { const char *kOrdinalsBlock = "[ordinals]\n" "bitmap=Ordinal::BitMap::1\n" "bitmap=Ordinal::BitMap::2\n" "bitmap=Ordinal::BitMap::3\n" "bitmap=Ordinal::BitMap::4\n" "[Ordinal::BitMap::1]\n" "bitmap=00000000000000000000000000000000\n" "bitmap=00000000000000000000000000000000\n" "bitmap=00000000000000000000000000000000\n" "bitmap=00000000000000000000000000000000\n" "bitmap=00000000000000000000000000000000\n" "bitmap=00000000000000000000000000000000\n" "bitmap=000038000003C000001FF00000000F00\n" "bitmap=0000F8000003C000003FF80000000F00\n" "bitmap=0001F8000003C00000707C0000000F00\n" "bitmap=0001F8000003C00000603C0000000F00\n" "bitmap=00007801FC0FF00000003C3DF807FF00\n" "bitmap=00007803FE0FF00000003C3FFC0FFF00\n" "bitmap=00007803C703C00000003C3E3C1F0F00\n" "bitmap=000078078303C0000000783C1E1E0F00\n" "bitmap=000078078003C0000000783C1E1E0F00\n" "bitmap=00007807C003C0000000F03C1E1E0F00\n" "bitmap=00007807F003C0000001E03C1E1E0F00\n" "bitmap=00007803FC03C0000003C03C1E1E0F00\n" "bitmap=00007801FE03C0000007803C1E1E0F00\n" "bitmap=000078007F03C000000F003C1E1E0F00\n" "bitmap=000078001F03C000001E003C1E1E0F00\n" "bitmap=000078000F03C000003C003C1E1E0F00\n" "bitmap=000078060F03C0000078003C1E1E0F00\n" "bitmap=000078071E03E0000078003C1E1F1F00\n" "bitmap=00007803FE01F000007FFC3C1E0FFF00\n" "bitmap=00007801FC00F000007FFC3C1E07EF00\n" "bitmap=00000000000000000000000000000000\n" "bitmap=00000000000000000000000000000000\n" "bitmap=00000000000000000000000000000000\n" "bitmap=00000000000000000000000000000000\n" "bitmap=00000000000000000000000000000000\n" "bitmap=00000000000000000000000000000000\n" "x=128\n" "y=32\n" "width=8\n" "[Ordinal::BitMap::2]\n" "bitmap=00000000000000000000000000000000\n" "bitmap=00000000000000000000000000000000\n" "bitmap=00000000000000000000000000000000\n" "bitmap=00000000000000000000000000000000\n" "bitmap=00000000000000000000000000000000\n" "bitmap=00000000000000000000000000000000\n" "bitmap=001FFF0000003C0000003C03C0780000\n" "bitmap=001FFF0000003C0000007C03C0780000\n" "bitmap=00000E0000003C000000FC03C0780000\n" "bitmap=00003C0000003C000001BC03C0780000\n" "bitmap=0000700F3E1FFC000003BC0FF07BF000\n" "bitmap=0001E00F7E3FFC0000073C0FF07FF800\n" "bitmap=0003800FFE7C3C0000063C03C07C7800\n" "bitmap=0007F80FFE783C00000C3C03C0783C00\n" "bitmap=0007FE0F80783C0000183C03C0783C00\n" "bitmap=00001E0F00783C0000383C03C0783C00\n" "bitmap=00000F0F00783C0000703C03C0783C00\n" "bitmap=00000F0F00783C00007FFF03C0783C00\n" "bitmap=00000F0F00783C00007FFF03C0783C00\n" "bitmap=00000F0F00783C0000003C03C0783C00\n" "bitmap=00000F0F00783C0000003C03C0783C00\n" "bitmap=00000F0F00783C0000003C03C0783C00\n" "bitmap=00180F0F00783C0000003C03C0783C00\n" "bitmap=001C1F0F007C7C0000003C03E0783C00\n" "bitmap=000FFE0F003FFC0000003C01F0783C00\n" "bitmap=0007FC0F001FBC0000003C00F0783C00\n" "bitmap=00000000000000000000000000000000\n" "bitmap=00000000000000000000000000000000\n" "bitmap=00000000000000000000000000000000\n" "bitmap=00000000000000000000000000000000\n" "bitmap=00000000000000000000000000000000\n" "bitmap=00000000000000000000000000000000\n" "x=128\n" "y=32\n" "width=8\n" "[Ordinal::BitMap::3]\n" "bitmap=00000000000000000000000000000000\n" "bitmap=00000000000000000000000000000000\n" "bitmap=00000000000000000000000000000000\n" "bitmap=00000000000000000000000000000000\n" "bitmap=00000000000000000000000000000000\n" "bitmap=00000000000000000000000000000000\n" "bitmap=001FFF03C07800000000FC03C0780000\n" "bitmap=001FFF03C07800000003FC03C0780000\n" "bitmap=001E0003C07800000007C003C0780000\n" "bitmap=001E0003C0780000000F0003C0780000\n" "bitmap=001E000FF07BF000000F000FF07BF000\n" "bitmap=001E000FF07FF800001E000FF07FF800\n" "bitmap=001E0003C07C7800001E0003C07C7800\n" "bitmap=001FFC03C0783C00001EFC03C0783C00\n" "bitmap=001FFE03C0783C00001FFE03C0783C00\n" "bitmap=00001F03C0783C00001F1F03C0783C00\n" "bitmap=00000F03C0783C00001E0F03C0783C00\n" "bitmap=00000F03C0783C00001E0F03C0783C00\n" "bitmap=00000F03C0783C00001E0F03C0783C00\n" "bitmap=00000F03C0783C00001E0F03C0783C00\n" "bitmap=00000F03C0783C00001E0F03C0783C00\n" "bitmap=00000F03C0783C00001E0F03C0783C00\n" "bitmap=00180F03C0783C00001E0F03C0783C00\n" "bitmap=001C1F03E0783C00001F1F03E0783C00\n" "bitmap=000FFE01F0783C00000FFE01F0783C00\n" "bitmap=0007FC00F0783C000007FC00F0783C00\n" "bitmap=00000000000000000000000000000000\n" "bitmap=00000000000000000000000000000000\n" "bitmap=00000000000000000000000000000000\n" "bitmap=00000000000000000000000000000000\n" "bitmap=00000000000000000000000000000000\n" "bitmap=00000000000000000000000000000000\n" "x=128\n" "y=32\n" "width=8\n" "[Ordinal::BitMap::4]\n" "bitmap=00000000000000000000000000000000\n" "bitmap=00000000000000000000000000000000\n" "bitmap=00000000000000000000000000000000\n" "bitmap=00000000000000000000000000000000\n" "bitmap=00000000000000000000000000000000\n" "bitmap=00000000000000000000000000000000\n" "bitmap=001FFF03C07800000007FC03C0780000\n" "bitmap=001FFF03C0780000000FFE03C0780000\n" "bitmap=00000F03C0780000001F1F03C0780000\n" "bitmap=00000F03C0780000001E0F03C0780000\n" "bitmap=00000F0FF07BF000001E0F0FF07BF000\n" "bitmap=00001F0FF07FF800001E0F0FF07FF800\n" "bitmap=00001E03C07C7800001E0F03C07C7800\n" "bitmap=00003E03C0783C00001E0F03C0783C00\n" "bitmap=00003C03C0783C00000F1E03C0783C00\n" "bitmap=00003C03C0783C000007FC03C0783C00\n" "bitmap=00007803C0783C000007FC03C0783C00\n" "bitmap=00007803C0783C00000F1E03C0783C00\n" "bitmap=00007803C0783C00001E0F03C0783C00\n" "bitmap=0000F003C0783C00001E0F03C0783C00\n" "bitmap=0000F003C0783C00001E0F03C0783C00\n" "bitmap=0000F003C0783C00001E0F03C0783C00\n" "bitmap=0000F003C0783C00001E0F03C0783C00\n" "bitmap=0000F003E0783C00000F1E03E0783C00\n" "bitmap=0000F001F0783C00000FFE01F0783C00\n" "bitmap=0000F000F0783C000007FC00F0783C00\n" "bitmap=00000000000000000000000000000000\n" "bitmap=00000000000000000000000000000000\n" "bitmap=00000000000000000000000000000000\n" "bitmap=00000000000000000000000000000000\n" "bitmap=00000000000000000000000000000000\n" "bitmap=00000000000000000000000000000000\n" "x=128\n" "y=32\n" "width=8\n"; }