|
|
1.1 root 1: //
2: // nono
1.1.1.2 root 3: // Copyright (C) 2020 nono project
4: // Licensed under nono-license.txt
1.1 root 5: //
6:
7: #include "wxvideomonitor.h"
1.1.1.4 ! root 8: #include "wxbmp.h"
1.1 root 9: #include "bitmap.h"
10:
11: //
12: // LUNA ビットマップパネル
13: //
14:
15: // イベントテーブル
16: wxBEGIN_EVENT_TABLE(WXLunaBitmapPanel, inherited)
17: EVT_PAINT(WXLunaBitmapPanel::OnPaint)
18: EVT_SIZE(WXLunaBitmapPanel::OnSize)
19: EVT_SCROLLWIN(WXLunaBitmapPanel::OnScrollWin)
20: wxEND_EVENT_TABLE()
21:
22: // コンストラクタ
23: WXLunaBitmapPanel::WXLunaBitmapPanel(wxWindow *parent)
24: : inherited(parent, wxID_ANY, wxDefaultPosition,
25: wxSize(512, 384)) // 初期値は適当
26: {
27: src = gBitmap->GetBuf();
28:
29: // 仮想キャンバスサイズを設定
30: SetVirtualSize(virtual_width, virtual_height);
31: // スクロールバーを設定
32: SetScrollRate(width_per_unit, height_per_unit);
33: SetScrollbars(width_per_unit, height_per_unit,
34: virtual_width / width_per_unit,
35: virtual_height / height_per_unit);
36: }
37:
38: // デストラクタ
39: WXLunaBitmapPanel::~WXLunaBitmapPanel()
40: {
41: }
42:
43: // サイズ変更イベント
44: void
45: WXLunaBitmapPanel::OnSize(wxSizeEvent& event)
46: {
47: // Mac ではウィンドウ作成時に 0 以下の値が来ることがある
48: // GTK では 1 で来ることがある
1.1.1.3 root 49: const wxSize& size = event.GetSize();
1.1 root 50: if (size.x <= 1 || size.y <= 1) {
51: return;
52: }
53:
54: view_width = size.x;
55: view_height = size.y;
56:
57: // BMP バッファ作成
1.1.1.4 ! root 58: bmpbuf.resize(view_width * view_height * 3);
! 59: // 正しく描かれなかった時に分かりやすいよう初期値は濃いグレーにしておく。
! 60: // としたいところだが、このバッファはわりと大きくて更にリサイズする時は
! 61: // 連続して頻繁にリサイズが起きることになるので、この無駄な塗りつぶしは
! 62: // デバッグ目的以外では止めておく。
! 63: //std::fill(bmpbuf.begin(), bmpbuf.end(), 0x70);
1.1 root 64: }
65:
66: // スクロールイベント
67: void
68: WXLunaBitmapPanel::OnScrollWin(wxScrollWinEvent& event)
69: {
70: int orient = event.GetOrientation();
71: int pos = event.GetPosition();
72:
73: if (orient == wxHORIZONTAL) {
74: view_x = pos * width_per_unit;
75: } else {
76: view_y = pos * height_per_unit;
77: }
78: }
79:
80: // XXX 実際にはこの辺かどこかで更新チェックをしないといけない。
81: // 今は毎回全描画しているので画面サイズが大きくなると重くなる。
82:
83: // 描画イベント (UI スレッドから呼ばれる)
84: void
85: WXLunaBitmapPanel::OnPaint(wxPaintEvent& event)
86: {
87: // 更新があれば、ここで裏バッファに描画
88: Draw();
89: // バッファから wxBitmap を作成
1.1.1.4 ! root 90: wxImage image(view_width, view_height, &bmpbuf[0], true);
1.1 root 91: wxBitmap bitmap(image);
92:
93: // 実画面 DC にコピー
94: wxPaintDC dstDC(this);
95: dstDC.DrawBitmap(bitmap, 0, 0);
96: }
97:
98: // ビットマッププレーンの内容をパネルのバックグラウンドバッファに描画する
99: void
100: WXLunaBitmapPanel::Draw()
101: {
102: int width = std::min(2048, view_width);
103: int height = std::min(1024, view_height);
104: // X 方向は32bit(ロングワード)単位で処理
105: int x_offset = view_x / width_per_unit;
106:
107: for (int y = 0; y < height; y++) {
1.1.1.2 root 108: const uint32 *s = (const uint32 *)&src[(view_y + y) * 256];
1.1 root 109: uint8 *d = &bmpbuf[y * (width * 3)];
110:
111: // dst を1ラインクリアしてから..
112: memset(d, 0, width * 3);
113: // ON になってるドットだけ打っていく
114: for (int x = 0; x < width / 32; x++) {
115: uint32 srcdata = s[x_offset + x];
116: for (int i = 0; srcdata != 0; srcdata <<= 1, i++) {
117: uint8 dst;
118: if ((int32)srcdata < 0) {
119: dst = 0xff;
120: } else {
121: dst = 0;
122: }
123: d[(x * 32 + i) * 3 + 0] = dst;
124: d[(x * 32 + i) * 3 + 1] = dst;
125: d[(x * 32 + i) * 3 + 2] = dst;
126: }
127: }
128: }
129: }
130:
131: //
132: // LUNA ビットマップウィンドウ
133: //
134:
135: // イベントテーブル
136: wxBEGIN_EVENT_TABLE(WXLunaBitmapWindow, inherited)
137: EVT_TIMER(wxID_ANY, WXLunaBitmapWindow::OnTimer)
138: wxEND_EVENT_TABLE()
139:
140: // コンストラクタ
141: WXLunaBitmapWindow::WXLunaBitmapWindow(wxWindow *parent, wxWindowID id,
142: const wxString& name)
143: : inherited(parent, id, name,
144: inherited::DEFAULT_STYLE | wxRESIZE_BORDER)
145: {
146: panel = new WXLunaBitmapPanel(this);
147:
148: // 大きさをそれに固定
149: Fit();
150:
1.1.1.3 root 151: // 更新タイマーはモニターパネル同様の 30Hz にしておく。
1.1 root 152: timer.SetOwner(this);
1.1.1.3 root 153: timer.Start(33);
1.1 root 154: }
155:
156: // デストラクタ
157: WXLunaBitmapWindow::~WXLunaBitmapWindow()
158: {
159: }
160:
161: // タイマーイベント
162: void
163: WXLunaBitmapWindow::OnTimer(wxTimerEvent& event)
164: {
165: // モニタースクリーンを更新して、更新があれば画面を再描画
166: panel->Refresh();
167: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.