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