|
|
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"
1.1.1.3 root 12: #include "wxbitmapbuf.h"
1.1 root 13: #include "wxcolor.h"
14: #include "wxtextscreen.h"
1.1.1.4 ! root 15: #include "wxuimessage.h"
1.1 root 16: #include "lcd.h"
17:
18: // パネルの大きさ (定数)
19: // N はとりあえずの倍率。
20: #define N (2)
21: #define PANEL_WIDTH ((N) * (5 + 1) * 16 + 1)
22: #define PANEL_HEIGHT ((N) * (8 + 1) * 2 + 1)
23:
24: //
25: // LUNA LCD パネル
26: //
27:
28: // イベントテーブル
29: wxBEGIN_EVENT_TABLE(WXLCDPanel, inherited)
30: EVT_PAINT(WXLCDPanel::OnPaint)
31: wxEND_EVENT_TABLE()
32:
33: // コンストラクタ
34: WXLCDPanel::WXLCDPanel(wxWindow *parent)
35: : inherited(parent, wxID_ANY, wxDefaultPosition,
36: wxSize(PANEL_WIDTH, PANEL_HEIGHT))
37: {
1.1.1.2 root 38: bitmap.Create(PANEL_WIDTH, PANEL_HEIGHT);
1.1 root 39:
40: ddram = gLCD->GetDDRAM();
41:
1.1.1.4 ! root 42: // VM からの通知を受け取る
! 43: WXUIMessage::Connect(UIMessage::LCD, this,
! 44: wxCommandEventHandler(WXLCDPanel::OnLCDChanged));
1.1 root 45: }
46:
47: // デストラクタ
48: WXLCDPanel::~WXLCDPanel()
49: {
1.1.1.4 ! root 50: WXUIMessage::Disconnect(UIMessage::LCD,
! 51: wxCommandEventHandler(WXLCDPanel::OnLCDChanged));
1.1 root 52: }
53:
1.1.1.4 ! root 54: // LCD 状態変更イベント (UIMessage)
1.1 root 55: void
1.1.1.4 ! root 56: WXLCDPanel::OnLCDChanged(wxCommandEvent& event)
1.1 root 57: {
1.1.1.4 ! root 58: Refresh();
1.1 root 59: }
60:
61: // 描画イベント (UI スレッドから呼ばれる)
62: void
63: WXLCDPanel::OnPaint(wxPaintEvent& event)
64: {
65: // メモリ DC に描画
66: wxMemoryDC memDC;
1.1.1.2 root 67: memDC.SelectObject(bitmap);
1.1 root 68: Draw(memDC);
69:
70: // 実画面 DC にコピー
71: wxPaintDC dstDC(this);
72: dstDC.Blit(0, 0, PANEL_WIDTH, PANEL_HEIGHT, &memDC, 0, 0);
73: }
74:
75: // バックグラウンドバッファに描画
76: void
77: WXLCDPanel::Draw(wxDC& dc)
78: {
79: // 背景
80: dc.SetPen(UD_CREAM);
81: dc.SetBrush(UD_CREAM);
1.1.1.2 root 82: dc.DrawRectangle(wxPoint(0, 0), bitmap.GetSize());
1.1 root 83:
84: for (int y = 0; y < 2; y++) {
85: for (int x = 0; x < 16; x++) {
86: uint8 ch = ddram[0x40 * y + x];
87: DrawChar(dc, x, y, ch);
88: }
89: }
90: }
91:
92: // 1文字描画
93: void
94: WXLCDPanel::DrawChar(wxDC& dc, int x, int y, uint8 ch)
95: {
96: wxSize dotsize = wxSize(N, N);
97: const uint8 *font;
98:
99: font = gLCD->GetFont(ch);
100:
101: for (int py = 0; py < 8; py++) {
102: uint8 line = *font++;
103: line <<= 3;
104: for (int px = 0; px < 5; px++) {
105: wxColour color;
106: if ((int8)line < 0) {
107: color = UD_BROWN;
108: } else {
109: color = UD_YELLOW_GREEN;
110: }
111: dc.SetPen(color);
112: dc.SetBrush(color);
113: dc.DrawRectangle(
114: wxPoint((1 + x * 6 + px) * N, (1 + y * 9 + py) * N),
115: dotsize);
116:
117: line <<= 1;
118: }
119: }
120: }
121:
122: //
123: // LCD ウィンドウ
124: //
125:
126: // コンストラクタ
1.1.1.3 root 127: WXLCDWindow::WXLCDWindow(wxWindow *parent)
128: : inherited(parent, wxID_ANY, _("Front LCD"))
1.1 root 129: {
1.1.1.3 root 130: wxBoxSizer *topsizer = new wxBoxSizer(wxVERTICAL);
131:
1.1 root 132: panel = new WXLCDPanel(this);
1.1.1.3 root 133: topsizer->Add(panel, 0, wxEXPAND);
1.1 root 134:
1.1.1.3 root 135: SetSizer(topsizer);
1.1 root 136: // 大きさをそれに固定
137: Fit();
138: }
139:
140: // デストラクタ
141: WXLCDWindow::~WXLCDWindow()
142: {
143: }
144:
145: //
146: // LCD キャラクタパネル
147: //
148:
1.1.1.2 root 149: #define CP_WIDTH (N * (1 + 6 * (16 + 1 + 16)))
150: #define CP_HEIGHT (N * (1 + 9 * 8))
1.1 root 151:
152: // イベントテーブル
153: wxBEGIN_EVENT_TABLE(WXLCDCharPanel, inherited)
154: EVT_PAINT(WXLCDCharPanel::OnPaint)
155: wxEND_EVENT_TABLE()
156:
157: // コンストラクタ
158: WXLCDCharPanel::WXLCDCharPanel(wxWindow *parent)
1.1.1.2 root 159: : inherited(parent, wxSize(CP_WIDTH, CP_HEIGHT))
1.1 root 160: {
1.1.1.2 root 161: bitmap.Create(CP_WIDTH, CP_HEIGHT);
1.1 root 162: }
163:
164: // デストラクタ
165: WXLCDCharPanel::~WXLCDCharPanel()
166: {
167: }
168:
169: // 描画イベント (UI スレッドから呼ばれる)
170: void
171: WXLCDCharPanel::OnPaint(wxPaintEvent& event)
172: {
173: // メモリ DC に描画
174: wxMemoryDC memDC;
1.1.1.2 root 175: memDC.SelectObject(bitmap);
1.1 root 176: Draw(memDC);
177:
178: // 実画面 DC にコピー
179: wxPaintDC dstDC(this);
180: dstDC.Blit(0, 0, CP_WIDTH, CP_HEIGHT, &memDC, 0, 0);
181: }
182:
183: // バックグラウンドバッファに描画
184: void
185: WXLCDCharPanel::Draw(wxDC& dc)
186: {
187: wxSize dotsize = wxSize(N, N);
188:
189: // 背景
1.1.1.2 root 190: dc.SetPen(BGPANEL);
191: dc.SetBrush(BGPANEL);
192: dc.DrawRectangle(wxPoint(0, 0), bitmap.GetSize());
1.1 root 193:
194: // フォントは 5x8 (最下行はカーソル用に空けてあるので実際は 5x7)。
195: // 実際には 0xe0 以降には 5x10 フォントが混在しているのだが、その
196: // モードはサポートしていないので今の所全部 5x8 としてある。
197:
1.1.1.2 root 198: // cx, cy はこの文字の左上座標 (スケール前)
199: int cx = 1;
200: int cy = 1;
201: for (int ch = 0; ch < 256; ch++) {
1.1 root 202: const uint8 *font = gLCD->GetFont(ch);
203: for (int py = 0; py < 8; py++) {
204: uint8 line = *font++;
205: line <<= 3;
206: for (int px = 0; px < 5; px++) {
207: wxColour color;
208: if ((int8)line < 0) {
209: color = *wxBLACK;
210: } else {
211: color = *wxWHITE;
212: }
213: dc.SetPen(color);
214: dc.SetBrush(color);
215: dc.DrawRectangle(
216: wxPoint((cx + px) * N, (cy + py) * N),
217: dotsize);
218:
219: line <<= 1;
220: }
221: }
1.1.1.2 root 222:
223: cx += 6;
224: if (ch % 16 == 15) {
225: // 行折り返し
226: cx -= 6 * 16;
227: cy += 9;
228: // 0x80 以降は右側に作る
229: if (ch == 127) {
230: cx += 6 * (16 + 1/*中央の余白*/);
231: cy = 1;
232: }
233: }
1.1 root 234: }
235: }
236:
237: //
238: // LCD モニタウィンドウ
239: //
240:
241: // コンストラクタ
1.1.1.3 root 242: WXLCDMonitor::WXLCDMonitor(wxWindow *parent)
243: : inherited(parent, wxID_ANY, _("LCD"))
1.1 root 244: {
1.1.1.2 root 245: // top
246: // | +--------------------------+
247: // v | 上余白 |
248: // +------+------------+------+
249: // |左余白| TextScreen |右余白|
250: // +------+-----------++------+
251: // |左余白| CharPanel | 右余白|
252: // +------+-----------+-------+
253: // | 下余白 |
254: // +--------------------------+
1.1 root 255: wxBoxSizer *topsizer = new wxBoxSizer(wxVERTICAL);
256:
1.1.1.2 root 257: // 上余白
258: topsizer->Add(new WXPaddingPanel(this), 0, wxEXPAND);
259:
260: // 2段目
261: wxBoxSizer *hbox1 = new wxBoxSizer(wxHORIZONTAL);
262: topsizer->Add(hbox1, 0, wxEXPAND);
263:
264: // 2段目の左余白
265: hbox1->Add(new WXPaddingPanel(this), 0, wxEXPAND);
266:
1.1.1.3 root 267: monpanel = new WXTextScreen(this, gMonitorManager.Get(ID_MONITOR_LCD));
1.1.1.2 root 268: hbox1->Add(monpanel, 0, wxEXPAND);
269:
270: // 2段目の右余白
1.1.1.3 root 271: // ここの1でこの右余白が空き全部を使用するので空き地が埋まる
272: hbox1->Add(new WXPaddingPanel(this), 1, wxEXPAND);
1.1.1.2 root 273:
274: // 3段目
275: wxBoxSizer *hbox2 = new wxBoxSizer(wxHORIZONTAL);
276: topsizer->Add(hbox2, 0, wxEXPAND);
277:
278: // 3段目の左余白
279: hbox2->Add(new WXPaddingPanel(this), 0, wxEXPAND);
1.1 root 280:
281: chrpanel = new WXLCDCharPanel(this);
1.1.1.2 root 282: hbox2->Add(chrpanel, 0, wxEXPAND);
283:
284: // 3段目の右余白
285: // ここの1でこの右余白が空き全部を使用するので空き地が埋まる
286: hbox2->Add(new WXPaddingPanel(this), 1, wxEXPAND);
287:
288: // 下余白
289: topsizer->Add(new WXPaddingPanel(this), 0, wxEXPAND);
1.1 root 290:
291: SetSizer(topsizer);
292:
293: // 大きさをそれに固定
294: Fit();
295: }
296:
297: // デストラクタ
298: WXLCDMonitor::~WXLCDMonitor()
299: {
300: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.