|
|
1.1 ! root 1: // ! 2: // nono ! 3: // Copyright (C) 2024 nono project ! 4: // Licensed under nono-license.txt ! 5: // ! 6: ! 7: // ! 8: // アクセス状況 (グラフィカル) ウィンドウ ! 9: // ! 10: ! 11: // パネルには WXTextScreen 同様に四辺に DefaultPadding を手動で入れてある。 ! 12: ! 13: #include "wxaccstatmonitor.h" ! 14: #include "wxcolor.h" ! 15: #include "wxtextscreen.h" ! 16: #include "bankram.h" ! 17: #include "mainbus.h" ! 18: ! 19: // ! 20: // アクセス状況 (グラフィカル) パネル ! 21: // ! 22: ! 23: // コンストラクタ ! 24: WXAccStatPanel::WXAccStatPanel(wxWindow *parent, Monitor& monitor_) ! 25: : inherited(parent, monitor_) ! 26: { ! 27: // デバイスを取得 ! 28: mainbus = GetMainbusDevice(); ! 29: ! 30: // バンクメモリ描画のため ! 31: is_x68030 = gMainApp.IsX68030(); ! 32: if (is_x68030) { ! 33: for (int n = 0; n < 2; n++) { ! 34: auto bankdev = gMainApp.FindObject<BankRAMDevice>(OBJ_BANKRAM(n)); ! 35: bankram[n] = (bankdev != NULL); ! 36: } ! 37: } ! 38: ! 39: FontChanged(); ! 40: } ! 41: ! 42: // デストラクタ ! 43: WXAccStatPanel::~WXAccStatPanel() ! 44: { ! 45: } ! 46: ! 47: void ! 48: WXAccStatPanel::FontChanged() ! 49: { ! 50: inherited::FontChanged(); ! 51: ! 52: auto monsz = mainbus->monitor_accstat.GetSize(); ! 53: wxSize size( ! 54: WXTextScreen::DefaultPadding * 2 + monsz.width * font_width, ! 55: WXTextScreen::DefaultPadding * 2 + monsz.height * font_height); ! 56: ! 57: SetClientSize(size); ! 58: SetMinClientSize(size); ! 59: ! 60: redraw_header = true; ! 61: } ! 62: ! 63: void ! 64: WXAccStatPanel::Draw() ! 65: { ! 66: const int padding = WXTextScreen::DefaultPadding; ! 67: const auto& accstat_rw = mainbus->accstat_rw; ! 68: const auto& accstat_avail = mainbus->accstat_avail; ! 69: int rows = accstat_rw.size() / 64; ! 70: uint fw = font_width; ! 71: uint fh = font_height; ! 72: ! 73: // 8文字分(16MB) ごとに 0.5 文字分ずつ空ける ! 74: int width8 = fw * 8 + (fw / 2); ! 75: ! 76: if (redraw_header) { ! 77: redraw_header = false; ! 78: ! 79: char buf[80]; ! 80: static_assert(AccStat::SHIFT >= 20, ""); ! 81: snprintf(buf, sizeof(buf), ! 82: "Show %ubit space. %uMB/piece. ' ':Read, ' ':Write(+Read)", ! 83: mainbus->accstat_bitlen, 1U << (AccStat::SHIFT - 20)); ! 84: DrawStringSJIS(padding, padding, buf); ! 85: ! 86: bitmap.FillRect(UD_GREEN, padding + fw * 30, padding, fw - 1, fh - 1); ! 87: bitmap.FillRect(UD_RED, padding + fw * 40, padding, fw - 1, fh - 1); ! 88: ! 89: for (uint i = 0; i < 8; i++) { ! 90: snprintf(buf, sizeof(buf), "+$0%x", i); ! 91: DrawStringSJIS(padding + fw * 12 + width8 * i, ! 92: padding + fh * 1, buf); ! 93: } ! 94: ! 95: uint baseaddr; ! 96: if (accstat_rw.size() == mainbus->accstat_read.size()) { ! 97: baseaddr = 0; ! 98: } else { ! 99: baseaddr = 0xc0; ! 100: } ! 101: ! 102: for (int y = 0; y < rows; y++) { ! 103: snprintf(buf, sizeof(buf), "$%02x00'0000:", ! 104: (uint8)(baseaddr + y * 0x08)); ! 105: DrawStringSJIS(padding, padding + fh * (y + 2), buf); ! 106: } ! 107: ! 108: if (is_x68030) { ! 109: for (int n = 0; n < 2; n++) { ! 110: snprintf(buf, sizeof(buf), "BankMem #%u:", n); ! 111: DrawStringSJIS(padding, padding + fh * (35 + n), buf); ! 112: } ! 113: } ! 114: } ! 115: ! 116: // UD_{RED,GREEN} から UD_LIGHT_GREY まで HSV の S,V を線形補間。 ! 117: static const Color cols[8] = { ! 118: UD_RED, // HSV(18, 100, 100) ! 119: UD_GREEN, // HSV(162, 98, 69) ! 120: Color(242, 115, 60), // HSV(18, 75, 95) ! 121: Color(47, 183, 142), // HSV(162, 74, 72) ! 122: Color(229, 149, 114), // HSV(18, 50, 90) ! 123: Color(97, 191, 163), // HSV(162, 49, 75) ! 124: Color(216, 178, 162), // HSV(18, 25, 85) ! 125: Color(149, 196, 182), // HSV(162, 24, 77) ! 126: }; ! 127: // UD_LIGHT_GREY // HSV(240, 1, 80) ! 128: ! 129: uint py = padding + fh * 2; ! 130: for (int y = 0; y < rows; y++) { ! 131: const uint8 *a = &mainbus->accstat_rw[y * 64]; ! 132: uint8 avail = accstat_avail[y]; ! 133: uint px = padding + fw * 12; ! 134: ! 135: for (int i = 0; i < 8; i++) { ! 136: if ((int8)avail < 0) { ! 137: // 何かしらデバイスがある 16MB (8文字相当) 分。 ! 138: for (int j = 0; j < 8; j++, a++, px += fw) { ! 139: uint8 op = *a; ! 140: Color c; ! 141: if (__predict_true(op == 0)) { ! 142: c = UD_LIGHT_GREY; ! 143: } else { ! 144: c = cols[__builtin_ctz(op)]; ! 145: } ! 146: bitmap.DrawLineH(c, px, py, px + fw - 1); ! 147: } ! 148: } else { ! 149: // この 16MB には何のデバイスもない。 ! 150: a += 8; ! 151: // 事故がなければこれなくても動くはず ! 152: //bitmap.DrawLineH(BGPANEL, px, py, px + fw * 8 - 1); ! 153: px += fw * 8; ! 154: } ! 155: avail <<= 1; ! 156: px += fw / 2; ! 157: } ! 158: ! 159: // 1ラスターを縦1文字分に展開 ! 160: CopyLine(12, py, 68); ! 161: py += fh; ! 162: } ! 163: ! 164: // バンクメモリ ! 165: if (is_x68030) { ! 166: for (int n = 0; n < 2; n++) { ! 167: if (bankram[n]) { ! 168: py = padding + fh * (35 + n); ! 169: const uint8 *a = &mainbus->accbank[n * AccStat::BANKLEN]; ! 170: uint px = padding + fw * 12; ! 171: ! 172: for (int j = 0; j < 8; j++, a++, px += fw) { ! 173: uint8 op = *a; ! 174: Color c; ! 175: if (__predict_true(op == 0)) { ! 176: c = UD_LIGHT_GREY; ! 177: } else { ! 178: c = cols[__builtin_ctz(op)]; ! 179: } ! 180: bitmap.DrawLineH(c, px, py, px + fw - 1); ! 181: } ! 182: ! 183: // 1ラスターを縦1文字分に展開 ! 184: CopyLine(12, py, 8); ! 185: } ! 186: } ! 187: } ! 188: } ! 189: ! 190: // 1ラスターを縦1文字分に展開する。 ! 191: // ただの共通下請けなので引数に汎用性はない。 ! 192: // cx は文字単位の X 座標 (左端の1文字目が 0、次の文字が 1)。 ! 193: // py はピクセル単位の Y 座標。 ! 194: // clen はコピーする文字数。 ! 195: // (cxをピクセルにした座標, py) から clen 文字分の長さを次ラスターから ! 196: // (font_height - 1) ラスターまでにコピーする。 ! 197: void ! 198: WXAccStatPanel::CopyLine(int cx, int py, int clen) ! 199: { ! 200: const int padding = WXTextScreen::DefaultPadding; ! 201: int px = padding + font_width * cx; ! 202: Rect rect(px, py, clen * font_width, font_height - 1); ! 203: ! 204: bitmap.CopyFromTop(rect); ! 205: } ! 206: ! 207: ! 208: // ! 209: // アクセス状況 (グラフィカル) ウィンドウ ! 210: // ! 211: ! 212: // コンストラクタ ! 213: WXAccStatWindow::WXAccStatWindow(wxWindow *parent, Monitor& monitor_) ! 214: : inherited(parent, wxID_ANY, _("Access Status")) ! 215: { ! 216: new WXAccStatPanel(this, monitor_); ! 217: DoSize(); ! 218: } ! 219: ! 220: // デストラクタ ! 221: WXAccStatWindow::~WXAccStatWindow() ! 222: { ! 223: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.