|
|
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.2 ! root 12: #include "wxbmp.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: // コンストラクタ
135: WXLCDWindow::WXLCDWindow(wxWindow *parent, wxWindowID id)
136: : inherited(parent, id, _("Front LCD"))
137: {
138: panel = new WXLCDPanel(this);
139:
140: // 大きさをそれに固定
141: Fit();
142: }
143:
144: // デストラクタ
145: WXLCDWindow::~WXLCDWindow()
146: {
147: }
148:
149: //
150: // LCD キャラクタパネル
151: //
152:
1.1.1.2 ! root 153: #define CP_WIDTH (N * (1 + 6 * (16 + 1 + 16)))
! 154: #define CP_HEIGHT (N * (1 + 9 * 8))
1.1 root 155:
156: // イベントテーブル
157: wxBEGIN_EVENT_TABLE(WXLCDCharPanel, inherited)
158: EVT_PAINT(WXLCDCharPanel::OnPaint)
159: wxEND_EVENT_TABLE()
160:
161: // コンストラクタ
162: WXLCDCharPanel::WXLCDCharPanel(wxWindow *parent)
1.1.1.2 ! root 163: : inherited(parent, wxSize(CP_WIDTH, CP_HEIGHT))
1.1 root 164: {
1.1.1.2 ! root 165: bitmap.Create(CP_WIDTH, CP_HEIGHT);
1.1 root 166: }
167:
168: // デストラクタ
169: WXLCDCharPanel::~WXLCDCharPanel()
170: {
171: }
172:
173: // 描画イベント (UI スレッドから呼ばれる)
174: void
175: WXLCDCharPanel::OnPaint(wxPaintEvent& event)
176: {
177: // メモリ DC に描画
178: wxMemoryDC memDC;
1.1.1.2 ! root 179: memDC.SelectObject(bitmap);
1.1 root 180: Draw(memDC);
181:
182: // 実画面 DC にコピー
183: wxPaintDC dstDC(this);
184: dstDC.Blit(0, 0, CP_WIDTH, CP_HEIGHT, &memDC, 0, 0);
185: }
186:
187: // バックグラウンドバッファに描画
188: void
189: WXLCDCharPanel::Draw(wxDC& dc)
190: {
191: wxSize dotsize = wxSize(N, N);
192:
193: // 背景
1.1.1.2 ! root 194: dc.SetPen(BGPANEL);
! 195: dc.SetBrush(BGPANEL);
! 196: dc.DrawRectangle(wxPoint(0, 0), bitmap.GetSize());
1.1 root 197:
198: // フォントは 5x8 (最下行はカーソル用に空けてあるので実際は 5x7)。
199: // 実際には 0xe0 以降には 5x10 フォントが混在しているのだが、その
200: // モードはサポートしていないので今の所全部 5x8 としてある。
201:
1.1.1.2 ! root 202: // cx, cy はこの文字の左上座標 (スケール前)
! 203: int cx = 1;
! 204: int cy = 1;
! 205: for (int ch = 0; ch < 256; ch++) {
1.1 root 206: const uint8 *font = gLCD->GetFont(ch);
207: for (int py = 0; py < 8; py++) {
208: uint8 line = *font++;
209: line <<= 3;
210: for (int px = 0; px < 5; px++) {
211: wxColour color;
212: if ((int8)line < 0) {
213: color = *wxBLACK;
214: } else {
215: color = *wxWHITE;
216: }
217: dc.SetPen(color);
218: dc.SetBrush(color);
219: dc.DrawRectangle(
220: wxPoint((cx + px) * N, (cy + py) * N),
221: dotsize);
222:
223: line <<= 1;
224: }
225: }
1.1.1.2 ! root 226:
! 227: cx += 6;
! 228: if (ch % 16 == 15) {
! 229: // 行折り返し
! 230: cx -= 6 * 16;
! 231: cy += 9;
! 232: // 0x80 以降は右側に作る
! 233: if (ch == 127) {
! 234: cx += 6 * (16 + 1/*中央の余白*/);
! 235: cy = 1;
! 236: }
! 237: }
1.1 root 238: }
239: }
240:
241: //
242: // LCD モニタウィンドウ
243: //
244:
245: // コンストラクタ
246: WXLCDMonitor::WXLCDMonitor(wxWindow *parent, wxWindowID id)
247: : inherited(parent, id, _("LCD"))
248: {
1.1.1.2 ! root 249: // top
! 250: // | +--------------------------+
! 251: // v | 上余白 |
! 252: // +------+------------+------+
! 253: // |左余白| TextScreen |右余白|
! 254: // +------+-----------++------+
! 255: // |左余白| CharPanel | 右余白|
! 256: // +------+-----------+-------+
! 257: // | 下余白 |
! 258: // +--------------------------+
1.1 root 259: wxBoxSizer *topsizer = new wxBoxSizer(wxVERTICAL);
260:
1.1.1.2 ! root 261: // 上余白
! 262: topsizer->Add(new WXPaddingPanel(this), 0, wxEXPAND);
! 263:
! 264: // 2段目
! 265: wxBoxSizer *hbox1 = new wxBoxSizer(wxHORIZONTAL);
! 266: topsizer->Add(hbox1, 0, wxEXPAND);
! 267:
! 268: // 2段目の左余白
! 269: hbox1->Add(new WXPaddingPanel(this), 0, wxEXPAND);
! 270:
1.1 root 271: monpanel = new WXTextScreen(this, *gLCD);
1.1.1.2 ! root 272: hbox1->Add(monpanel, 0, wxEXPAND);
! 273:
! 274: // 2段目の右余白
! 275: hbox1->Add(new WXPaddingPanel(this), 0, wxEXPAND);
! 276:
! 277: // 3段目
! 278: wxBoxSizer *hbox2 = new wxBoxSizer(wxHORIZONTAL);
! 279: topsizer->Add(hbox2, 0, wxEXPAND);
! 280:
! 281: // 3段目の左余白
! 282: hbox2->Add(new WXPaddingPanel(this), 0, wxEXPAND);
1.1 root 283:
284: chrpanel = new WXLCDCharPanel(this);
1.1.1.2 ! root 285: hbox2->Add(chrpanel, 0, wxEXPAND);
! 286:
! 287: // 3段目の右余白
! 288: // ここの1でこの右余白が空き全部を使用するので空き地が埋まる
! 289: hbox2->Add(new WXPaddingPanel(this), 1, wxEXPAND);
! 290:
! 291: // 下余白
! 292: topsizer->Add(new WXPaddingPanel(this), 0, wxEXPAND);
1.1 root 293:
294: SetSizer(topsizer);
295:
296: // 大きさをそれに固定
297: Fit();
298: }
299:
300: // デストラクタ
301: WXLCDMonitor::~WXLCDMonitor()
302: {
303: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.