|
|
1.1 ! root 1: // ! 2: // nono ! 3: // Copyright (C) 2020 nono project ! 4: // Licensed under nono-license.txt ! 5: // ! 6: ! 7: // ! 8: // LUNA LCD パネル ! 9: // ! 10: ! 11: #include "wxlcdwindow.h" ! 12: #include "wxcolor.h" ! 13: #include "wxtextscreen.h" ! 14: #include "lcd.h" ! 15: ! 16: // パネルの大きさ (定数) ! 17: // N はとりあえずの倍率。 ! 18: #define N (2) ! 19: #define PANEL_WIDTH ((N) * (5 + 1) * 16 + 1) ! 20: #define PANEL_HEIGHT ((N) * (8 + 1) * 2 + 1) ! 21: ! 22: // ! 23: // LUNA LCD パネル ! 24: // ! 25: ! 26: // イベントテーブル ! 27: wxBEGIN_EVENT_TABLE(WXLCDPanel, inherited) ! 28: EVT_TIMER(wxID_ANY, WXLCDPanel::OnTimer) ! 29: EVT_PAINT(WXLCDPanel::OnPaint) ! 30: wxEND_EVENT_TABLE() ! 31: ! 32: // コンストラクタ ! 33: WXLCDPanel::WXLCDPanel(wxWindow *parent) ! 34: : inherited(parent, wxID_ANY, wxDefaultPosition, ! 35: wxSize(PANEL_WIDTH, PANEL_HEIGHT)) ! 36: { ! 37: bmpbuf.reset(new uint8 [PANEL_WIDTH * PANEL_HEIGHT * 3]); ! 38: memset(&bmpbuf[0], 0x70, PANEL_WIDTH * PANEL_HEIGHT * 3); ! 39: image.reset(new wxImage(PANEL_WIDTH, PANEL_HEIGHT, bmpbuf.get(), true)); ! 40: bitmap.reset(new wxBitmap(*image)); ! 41: ! 42: count = (uint32)-1; ! 43: ddram = gLCD->GetDDRAM(); ! 44: ! 45: // 更新タイマー。そんなに応答速度速くなくていい ! 46: timer.SetOwner(this); ! 47: timer.Start(50); ! 48: } ! 49: ! 50: // デストラクタ ! 51: WXLCDPanel::~WXLCDPanel() ! 52: { ! 53: bitmap.reset(); ! 54: image.reset(); ! 55: bmpbuf.reset(); ! 56: } ! 57: ! 58: // タイマーイベント ! 59: void ! 60: WXLCDPanel::OnTimer(wxTimerEvent& event) ! 61: { ! 62: uint32 devcount; ! 63: ! 64: // 更新があれば.. ! 65: devcount = gLCD->GetCounter(); ! 66: if (count != devcount) { ! 67: count = devcount; ! 68: ! 69: // 再描画を起こす ! 70: Refresh(); ! 71: } ! 72: } ! 73: ! 74: // 描画イベント (UI スレッドから呼ばれる) ! 75: void ! 76: WXLCDPanel::OnPaint(wxPaintEvent& event) ! 77: { ! 78: // メモリ DC に描画 ! 79: wxMemoryDC memDC; ! 80: memDC.SelectObject(*bitmap); ! 81: Draw(memDC); ! 82: ! 83: // 実画面 DC にコピー ! 84: wxPaintDC dstDC(this); ! 85: dstDC.Blit(0, 0, PANEL_WIDTH, PANEL_HEIGHT, &memDC, 0, 0); ! 86: } ! 87: ! 88: // バックグラウンドバッファに描画 ! 89: void ! 90: WXLCDPanel::Draw(wxDC& dc) ! 91: { ! 92: // 背景 ! 93: dc.SetPen(UD_CREAM); ! 94: dc.SetBrush(UD_CREAM); ! 95: dc.DrawRectangle(wxPoint(0, 0), wxSize(PANEL_WIDTH, PANEL_HEIGHT)); ! 96: ! 97: for (int y = 0; y < 2; y++) { ! 98: for (int x = 0; x < 16; x++) { ! 99: uint8 ch = ddram[0x40 * y + x]; ! 100: DrawChar(dc, x, y, ch); ! 101: } ! 102: } ! 103: } ! 104: ! 105: // 1文字描画 ! 106: void ! 107: WXLCDPanel::DrawChar(wxDC& dc, int x, int y, uint8 ch) ! 108: { ! 109: wxSize dotsize = wxSize(N, N); ! 110: const uint8 *font; ! 111: ! 112: font = gLCD->GetFont(ch); ! 113: ! 114: for (int py = 0; py < 8; py++) { ! 115: uint8 line = *font++; ! 116: line <<= 3; ! 117: for (int px = 0; px < 5; px++) { ! 118: wxColour color; ! 119: if ((int8)line < 0) { ! 120: color = UD_BROWN; ! 121: } else { ! 122: color = UD_YELLOW_GREEN; ! 123: } ! 124: dc.SetPen(color); ! 125: dc.SetBrush(color); ! 126: dc.DrawRectangle( ! 127: wxPoint((1 + x * 6 + px) * N, (1 + y * 9 + py) * N), ! 128: dotsize); ! 129: ! 130: line <<= 1; ! 131: } ! 132: } ! 133: } ! 134: ! 135: // ! 136: // LCD ウィンドウ ! 137: // ! 138: ! 139: // コンストラクタ ! 140: WXLCDWindow::WXLCDWindow(wxWindow *parent, wxWindowID id) ! 141: : inherited(parent, id, _("Front LCD")) ! 142: { ! 143: panel = new WXLCDPanel(this); ! 144: ! 145: // 大きさをそれに固定 ! 146: Layout(); ! 147: Fit(); ! 148: } ! 149: ! 150: // デストラクタ ! 151: WXLCDWindow::~WXLCDWindow() ! 152: { ! 153: } ! 154: ! 155: // ! 156: // LCD キャラクタパネル ! 157: // ! 158: ! 159: #define CP_WIDTH (N * (1 + 6 * 16)) ! 160: #define CP_HEIGHT (N * (1 + 9 * 16)) ! 161: ! 162: // イベントテーブル ! 163: wxBEGIN_EVENT_TABLE(WXLCDCharPanel, inherited) ! 164: EVT_PAINT(WXLCDCharPanel::OnPaint) ! 165: wxEND_EVENT_TABLE() ! 166: ! 167: // コンストラクタ ! 168: WXLCDCharPanel::WXLCDCharPanel(wxWindow *parent) ! 169: : inherited(parent, wxID_ANY, wxDefaultPosition, ! 170: wxSize(CP_WIDTH, CP_HEIGHT)) ! 171: { ! 172: bmpbuf.reset(new uint8 [CP_WIDTH * CP_HEIGHT * 3]); ! 173: memset(&bmpbuf[0], 0x70, CP_WIDTH * CP_HEIGHT * 3); ! 174: image.reset(new wxImage(CP_WIDTH, CP_HEIGHT, bmpbuf.get(), true)); ! 175: bitmap.reset(new wxBitmap(*image)); ! 176: } ! 177: ! 178: // デストラクタ ! 179: WXLCDCharPanel::~WXLCDCharPanel() ! 180: { ! 181: bitmap.reset(); ! 182: image.reset(); ! 183: bmpbuf.reset(); ! 184: } ! 185: ! 186: // 描画イベント (UI スレッドから呼ばれる) ! 187: void ! 188: WXLCDCharPanel::OnPaint(wxPaintEvent& event) ! 189: { ! 190: // メモリ DC に描画 ! 191: wxMemoryDC memDC; ! 192: memDC.SelectObject(*bitmap); ! 193: Draw(memDC); ! 194: ! 195: // 実画面 DC にコピー ! 196: wxPaintDC dstDC(this); ! 197: dstDC.Blit(0, 0, CP_WIDTH, CP_HEIGHT, &memDC, 0, 0); ! 198: } ! 199: ! 200: // バックグラウンドバッファに描画 ! 201: void ! 202: WXLCDCharPanel::Draw(wxDC& dc) ! 203: { ! 204: wxSize dotsize = wxSize(N, N); ! 205: ! 206: // 背景 ! 207: // XXX LIGHT_GREY を textscreen と共用すること ! 208: dc.SetPen(*wxLIGHT_GREY); ! 209: dc.SetBrush(*wxLIGHT_GREY); ! 210: dc.DrawRectangle(wxPoint(0, 0), wxSize(CP_WIDTH, CP_HEIGHT)); ! 211: ! 212: // フォントは 5x8 (最下行はカーソル用に空けてあるので実際は 5x7)。 ! 213: // 実際には 0xe0 以降には 5x10 フォントが混在しているのだが、その ! 214: // モードはサポートしていないので今の所全部 5x8 としてある。 ! 215: for (int ch = 0; ch < 256; ch++) { ! 216: // この文字の左上座標 (スケール前) ! 217: int cx = 1 + (ch % 16) * 6; ! 218: int cy = 1 + (ch / 16) * 9; ! 219: ! 220: const uint8 *font = gLCD->GetFont(ch); ! 221: for (int py = 0; py < 8; py++) { ! 222: uint8 line = *font++; ! 223: line <<= 3; ! 224: for (int px = 0; px < 5; px++) { ! 225: wxColour color; ! 226: if ((int8)line < 0) { ! 227: color = *wxBLACK; ! 228: } else { ! 229: color = *wxWHITE; ! 230: } ! 231: dc.SetPen(color); ! 232: dc.SetBrush(color); ! 233: dc.DrawRectangle( ! 234: wxPoint((cx + px) * N, (cy + py) * N), ! 235: dotsize); ! 236: ! 237: line <<= 1; ! 238: } ! 239: } ! 240: } ! 241: } ! 242: ! 243: // ! 244: // LCD モニタウィンドウ ! 245: // ! 246: ! 247: // コンストラクタ ! 248: WXLCDMonitor::WXLCDMonitor(wxWindow *parent, wxWindowID id) ! 249: : inherited(parent, id, _("LCD")) ! 250: { ! 251: wxBoxSizer *topsizer = new wxBoxSizer(wxVERTICAL); ! 252: ! 253: monpanel = new WXTextScreen(this, *gLCD); ! 254: topsizer->Add(monpanel, 0, wxEXPAND | wxALL, DefaultPadding); ! 255: ! 256: chrpanel = new WXLCDCharPanel(this); ! 257: topsizer->Add(chrpanel, 0, wxEXPAND | wxRIGHT | wxLEFT | wxBOTTOM, ! 258: DefaultPadding); ! 259: ! 260: SetSizer(topsizer); ! 261: ! 262: // 大きさをそれに固定 ! 263: Layout(); ! 264: Fit(); ! 265: } ! 266: ! 267: // デストラクタ ! 268: WXLCDMonitor::~WXLCDMonitor() ! 269: { ! 270: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.