コンソールをスクロールしすぎるとだめになるバグを修正
そのためにバッファクラスを作成した
@@ -11,6 +11,7 @@ | ||
11 | 11 | #include <bitnos/window.h> |
12 | 12 | #include <string.h> |
13 | 13 | #include <stdio.h> |
14 | +#include <stdlib.h> | |
14 | 15 | #include <bitnos/memory.h> |
15 | 16 | #include <bitnos/timer.h> |
16 | 17 | #include <bitnos/specialtask.h> |
@@ -18,6 +19,94 @@ | ||
18 | 19 | namespace TaskConsole |
19 | 20 | { |
20 | 21 | |
22 | +/* class ScreenBuffer */ | |
23 | +void ScreenBuffer::Init(int width, int height) | |
24 | +{ | |
25 | + this->width = width; | |
26 | + this->height = height; | |
27 | + buf = new char[(this->width + 1) * this->height]; | |
28 | + | |
29 | + begin = 0; | |
30 | +} | |
31 | + | |
32 | +void ScreenBuffer::Dispose() | |
33 | +{ | |
34 | + delete[] buf; | |
35 | + buf = 0; | |
36 | +} | |
37 | + | |
38 | +void ScreenBuffer::Write(Point pos, char ch) | |
39 | +{ | |
40 | + if (IsAvailable(pos)) { | |
41 | + pos = Calculate(pos); | |
42 | + buf[pos.Y * (width + 1) + pos.X] = ch; | |
43 | + buf[pos.Y * (width + 1) + pos.X + 1] = '\0'; | |
44 | + } | |
45 | +} | |
46 | + | |
47 | +void ScreenBuffer::Write(Point pos, const char* str) | |
48 | +{ | |
49 | + if (IsAvailable(pos)) { | |
50 | + pos = Calculate(pos); | |
51 | + char* p = buf + pos.Y * (width + 1) + pos.X; | |
52 | + int x; | |
53 | + for (x = pos.X; x < width && *str != '\0'; x++) { | |
54 | + *p++ = *str++; | |
55 | + } | |
56 | + *p = '\0'; | |
57 | + } | |
58 | +} | |
59 | + | |
60 | +char ScreenBuffer::Read(Point pos) const | |
61 | +{ | |
62 | + if (IsAvailable(pos)) { | |
63 | + pos = Calculate(pos); | |
64 | + return buf[pos.Y * (width + 1) + pos.X]; | |
65 | + } | |
66 | + return 0; | |
67 | +} | |
68 | + | |
69 | +void ScreenBuffer::Scroll(int lines) | |
70 | +{ | |
71 | + begin += lines; | |
72 | + if (begin < 0) { | |
73 | + begin += height; | |
74 | + } else if (begin >= height) { | |
75 | + begin -= height; | |
76 | + } | |
77 | +} | |
78 | + | |
79 | +const char* ScreenBuffer::GetPointer(Point pos) const | |
80 | +{ | |
81 | + if (IsAvailable(pos)) { | |
82 | + pos = Calculate(pos); | |
83 | + return buf + pos.Y * (width + 1) + pos.X; | |
84 | + } | |
85 | + return 0; | |
86 | +} | |
87 | + | |
88 | +bool ScreenBuffer::IsAvailable(Point pos) const | |
89 | +{ | |
90 | + if (pos.X < 0 || width <= pos.X || | |
91 | + pos.Y < 0 || height <= pos.Y) { | |
92 | + return false; | |
93 | + } | |
94 | + return true; | |
95 | +} | |
96 | + | |
97 | +Point ScreenBuffer::Calculate(Point pos) const | |
98 | +{ | |
99 | + pos.Y += begin; | |
100 | + | |
101 | + if (pos.Y >= height) { | |
102 | + pos.Y -= height; | |
103 | + } | |
104 | + | |
105 | + return pos; | |
106 | +} | |
107 | +/* end of class ScreenBuffer */ | |
108 | + | |
109 | + | |
21 | 110 | struct Valiables |
22 | 111 | { |
23 | 112 | Console cons; |
@@ -30,6 +119,8 @@ | ||
30 | 119 | Timer* tim; |
31 | 120 | bool cursor; |
32 | 121 | bool active; |
122 | + | |
123 | + Timer* timBeep; | |
33 | 124 | }; |
34 | 125 | |
35 | 126 | // コマンド実行機能なし |
@@ -49,6 +140,9 @@ | ||
49 | 140 | void ShowCursor(Valiables* o); |
50 | 141 | void EraseCursor(Valiables* o); |
51 | 142 | |
143 | +void WriteBuffer(Valiables* o, int x, int y, char ch); | |
144 | +char ReadBuffer(Valiables* o, int x, int y); | |
145 | + | |
52 | 146 | void Init(void* obj) |
53 | 147 | { |
54 | 148 | Valiables* o = (Valiables*)obj; |
@@ -58,16 +152,16 @@ | ||
58 | 152 | Debug::WriteLine("Console Init"); |
59 | 153 | |
60 | 154 | //o->cons.height = 10; |
61 | - o->cons.height = 16; | |
155 | + o->cons.height = 10; | |
62 | 156 | // o->cons.width = 29; |
63 | - o->cons.width = 50; | |
64 | - //o->cons.bufHeight = 100; | |
65 | - o->cons.bufHeight = o->cons.height; | |
157 | + o->cons.width = 29; | |
158 | + o->cons.bufHeight = 20; | |
66 | 159 | //o->cons.bufWidth = 29; |
67 | 160 | o->cons.bufWidth = o->cons.width; |
68 | 161 | o->cons.buf = new char[o->cons.bufHeight * o->cons.bufWidth]; |
69 | 162 | o->cons.startLine = o->cons.endLine = 0; |
70 | 163 | o->cons.xPos = 0; |
164 | + o->cons.printYPos = 0; | |
71 | 165 | o->cons.backColor = ConvRGB16(0, 0, 0); |
72 | 166 | o->cons.textColor = ConvRGB16(255, 255, 255); |
73 | 167 | o->cmdlineBegin = 0; |
@@ -74,6 +168,10 @@ | ||
74 | 168 | o->cursor = false; |
75 | 169 | o->active = SpecialTask::Get(SpecialTask::Active) == task; |
76 | 170 | |
171 | + o->cons.sbuf.Init(29, 20); | |
172 | + o->cons.wPos = Point(0, 0); | |
173 | + o->cons.pPos = Point(0, 0); | |
174 | + | |
77 | 175 | o->img = new Image( |
78 | 176 | 8 + fontHankaku->GetWidth() * o->cons.width, |
79 | 177 | 25 + 8 + fontHankaku->GetHeight() * o->cons.height); |
@@ -88,7 +186,9 @@ | ||
88 | 186 | o->tim = timman->Alloc(task, 1); |
89 | 187 | o->tim->SetTime(80); |
90 | 188 | |
91 | - PutChar(o, '>'); | |
189 | + o->timBeep = timman->Alloc(task, 2); | |
190 | + | |
191 | + PutChar0(o, '>'); | |
92 | 192 | } |
93 | 193 | |
94 | 194 | void Proc(void* obj, Message* msg) |
@@ -97,9 +197,9 @@ | ||
97 | 197 | |
98 | 198 | if (msg->from == Message::From::Keyboard) { |
99 | 199 | if (msg->arg1 != 0) { |
100 | - if (o->cursor) { | |
200 | + //if (o->cursor) { | |
101 | 201 | EraseCursor(o); |
102 | - } | |
202 | + //} | |
103 | 203 | PutChar(o, msg->arg1); |
104 | 204 | if (o->cursor) { |
105 | 205 | ShowCursor(o); |
@@ -117,6 +217,12 @@ | ||
117 | 217 | o->cursor = true; |
118 | 218 | } |
119 | 219 | } |
220 | + } else if (msg->arg1 == 2) { | |
221 | + uint8_t reg = io_in8(0x0061); | |
222 | + //reg |= 0x03; | |
223 | + //reg &= 0x0f; | |
224 | + reg &= 0x0d; | |
225 | + io_out8(0x0061, reg); | |
120 | 226 | } |
121 | 227 | } else if (msg->from == Message::From::System) { |
122 | 228 | if (msg->arg1 == Message::System::WindowActivated) { |
@@ -130,11 +236,29 @@ | ||
130 | 236 | } |
131 | 237 | } |
132 | 238 | |
239 | +void NewLine(Valiables* o) | |
240 | +{ | |
241 | + if (o->cons.wPos.Y < o->cons.sbuf.GetHeight() - 1) { | |
242 | + o->cons.wPos.Y++; | |
243 | + } else { | |
244 | + o->cons.sbuf.Scroll(1); | |
245 | + o->cons.sbuf.Write(Point(0, o->cons.sbuf.GetHeight() - 1), '\0'); | |
246 | + o->cmdlineBegin--; | |
247 | + } | |
248 | + o->cons.wPos.X = 0; | |
249 | + o->cons.pPos.X = 0; | |
250 | + if (o->cons.pPos.Y < o->cons.height - 1) { | |
251 | + o->cons.pPos.Y++; | |
252 | + } | |
253 | +} | |
254 | + | |
133 | 255 | void PutChar0(Valiables* o, char ch) |
134 | 256 | { |
257 | +#if 0 | |
135 | 258 | // バッファに格納 |
136 | 259 | if (0x20 <= ch && ch < 0x80) { |
137 | - o->cons.buf[o->cons.bufWidth * o->cons.endLine + o->cons.xPos] = ch; | |
260 | + //o->cons.buf[o->cons.bufWidth * o->cons.endLine + o->cons.xPos] = ch; | |
261 | + WriteBuffer(o, o->cons.xPos, o->cons.endLine, ch); | |
138 | 262 | o->cons.xPos++; |
139 | 263 | } |
140 | 264 | if (ch == '\b') { |
@@ -143,43 +267,54 @@ | ||
143 | 267 | if (o->cons.xPos < 0) { |
144 | 268 | o->cons.xPos = o->cons.bufWidth - 1; |
145 | 269 | o->cons.endLine--; |
270 | + if (o->cons.endLine < 0) { | |
271 | + o->cons.endLine = o->cons.height - 1; | |
272 | + } | |
273 | + if (o->cons.printYPos > 0) { | |
274 | + o->cons.printYPos--; | |
275 | + } | |
146 | 276 | } |
147 | 277 | } else if (o->cons.endLine == o->cmdlineBegin && o->cons.xPos > 1) { |
148 | 278 | o->cons.xPos--; |
149 | 279 | } |
150 | - o->cons.buf[o->cons.bufWidth * o->cons.endLine + o->cons.xPos] = '\0'; | |
280 | + //o->cons.buf[o->cons.bufWidth * o->cons.endLine + o->cons.xPos] = '\0'; | |
281 | + WriteBuffer(o, o->cons.xPos, o->cons.endLine, '\0'); | |
151 | 282 | // 1文字だけ消去する |
152 | - int end = o->cons.endLine; | |
153 | - if (end >= o->cons.height) { | |
154 | - end = o->cons.height - 1; | |
155 | - } | |
156 | 283 | o->sht->DrawRectangleFill( |
157 | 284 | o->cons.backColor, |
158 | 285 | Point( |
159 | 286 | 4 + fontHankaku->GetWidth() * o->cons.xPos, |
160 | - 25 + 4 + fontHankaku->GetHeight() * end), | |
287 | + 25 + 4 + fontHankaku->GetHeight() * o->cons.printYPos), | |
161 | 288 | Point( |
162 | 289 | 4 + fontHankaku->GetWidth() * (o->cons.xPos + 1) - 1, |
163 | - 25 + 4 + fontHankaku->GetHeight() * (end + 1) - 1) | |
290 | + 25 + 4 + fontHankaku->GetHeight() * (o->cons.printYPos + 1) - 1) | |
164 | 291 | ); |
165 | 292 | } else if (o->cons.bufWidth <= o->cons.xPos || ch == '\n') { |
166 | 293 | // バッファの右端まで行った、またはエンターキーが押されたから改行 |
167 | 294 | if (o->cons.xPos < o->cons.bufWidth - 1) { |
168 | - o->cons.buf[o->cons.bufWidth * o->cons.endLine + o->cons.xPos] = '\0'; | |
295 | + //o->cons.buf[o->cons.bufWidth * o->cons.endLine + o->cons.xPos] = '\0';] | |
296 | + WriteBuffer(o, o->cons.xPos, o->cons.endLine, '\0'); | |
169 | 297 | } |
298 | + if (o->cons.printYPos < o->cons.height - 1) { | |
299 | + o->cons.printYPos++; | |
300 | + } | |
170 | 301 | o->cons.xPos = 0; |
171 | 302 | o->cons.endLine++; |
303 | + if (o->cons.endLine == o->cons.bufHeight) { | |
304 | + o->cons.endLine = 0; | |
305 | + } | |
172 | 306 | if (o->cons.endLine == o->cons.startLine) { |
307 | + memset(o->cons.buf + o->cons.endLine * o->cons.bufWidth, '\0', o->cons.bufWidth); | |
173 | 308 | o->cons.startLine++; |
309 | + if (o->cons.startLine == o->cons.bufHeight) { | |
310 | + o->cons.startLine = 0; | |
311 | + } | |
174 | 312 | } |
313 | + Debug::WriteLine("start=%d,end=%d", o->cons.startLine, o->cons.endLine); | |
175 | 314 | // 画面全体を描画しなおす |
176 | 315 | ConsoleRefreshScreen(o, o->cons.endLine - o->cons.height + 1); |
177 | 316 | } else { |
178 | 317 | // 改行しなかった |
179 | - int end = o->cons.endLine; | |
180 | - if (end >= o->cons.height) { | |
181 | - end = o->cons.height - 1; | |
182 | - } | |
183 | 318 | // 1文字だけ描画する |
184 | 319 | o->sht->DrawChar( |
185 | 320 | o->cons.textColor, |
@@ -186,9 +321,54 @@ | ||
186 | 321 | ch, |
187 | 322 | Point( |
188 | 323 | 4 + fontHankaku->GetWidth() * (o->cons.xPos - 1), |
189 | - 25 + 4 + fontHankaku->GetHeight() * end), | |
324 | + 25 + 4 + fontHankaku->GetHeight() * o->cons.printYPos), | |
190 | 325 | fontHankaku); |
191 | 326 | } |
327 | +#endif | |
328 | + if (0x20 <= ch && ch < 0x80) { | |
329 | + o->cons.sbuf.Write(o->cons.wPos, ch); | |
330 | + o->cons.wPos.X++; | |
331 | + if (o->cons.pPos.X < o->cons.width - 1) { | |
332 | + o->cons.pPos.X++; | |
333 | + } | |
334 | + } | |
335 | + if (ch == '\b') { | |
336 | + if ((o->cons.wPos.Y != o->cmdlineBegin && o->cons.wPos.X > 0) || | |
337 | + (o->cons.wPos.Y == o->cmdlineBegin && o->cons.wPos.X > 1)) { | |
338 | + o->cons.wPos.X--; | |
339 | + if (o->cons.pPos.X > 0) { | |
340 | + o->cons.pPos.X--; | |
341 | + } | |
342 | + } else if (o->cons.wPos.Y != o->cmdlineBegin && o->cons.wPos.X == 0) { | |
343 | + o->cons.wPos.X = o->cons.sbuf.GetWidth() - 1; | |
344 | + o->cons.wPos.Y--; | |
345 | + o->cons.pPos.X = o->cons.width - 1; | |
346 | + if (o->cons.pPos.Y > 0) { | |
347 | + o->cons.pPos.Y--; | |
348 | + } | |
349 | + } | |
350 | + o->cons.sbuf.Write(o->cons.wPos, '\0'); | |
351 | + o->sht->DrawRectangleFill( | |
352 | + o->cons.backColor, | |
353 | + Point( | |
354 | + 4 + fontHankaku->GetWidth() * o->cons.pPos.X, | |
355 | + 25 + 4 + fontHankaku->GetHeight() * o->cons.pPos.Y), | |
356 | + Point( | |
357 | + 4 + fontHankaku->GetWidth() * (o->cons.pPos.X + 1) - 1, | |
358 | + 25 + 4 + fontHankaku->GetHeight() * (o->cons.pPos.Y + 1) - 1) | |
359 | + ); | |
360 | + } else if (ch == '\n' || o->cons.wPos.X >= o->cons.sbuf.GetWidth()) { | |
361 | + NewLine(o); | |
362 | + ConsoleRefreshScreen(o, -1); | |
363 | + } else { | |
364 | + o->sht->DrawChar( | |
365 | + o->cons.textColor, | |
366 | + ch, | |
367 | + Point( | |
368 | + 4 + fontHankaku->GetWidth() * (o->cons.pPos.X - 1), | |
369 | + 25 + 4 + fontHankaku->GetHeight() * o->cons.pPos.Y), | |
370 | + fontHankaku); | |
371 | + } | |
192 | 372 | } |
193 | 373 | |
194 | 374 | void PutChar(Valiables* o, char ch) |
@@ -266,6 +446,7 @@ | ||
266 | 446 | } |
267 | 447 | #endif |
268 | 448 | PutChar0(o, ch); |
449 | +#if 0 | |
269 | 450 | if (ch == '\n') { |
270 | 451 | // コマンドラインを取得 |
271 | 452 | int i = 0; |
@@ -281,13 +462,29 @@ | ||
281 | 462 | } |
282 | 463 | o->cmdline[i] = '\0'; |
283 | 464 | |
284 | - Debug::WriteLine(o->cmdline); | |
465 | + //Debug::WriteLine(o->cmdline); | |
285 | 466 | RunCommand(o); |
286 | 467 | |
287 | 468 | o->cmdlineBegin = o->cons.endLine; |
288 | 469 | PutChar0(o, '>'); |
289 | 470 | } |
471 | +#endif | |
472 | + if (ch == '\n') { | |
473 | + int i = 0; | |
474 | + char c; | |
475 | + for (int line = o->cmdlineBegin, x = 1; line <= o->cons.wPos.Y; line++) { | |
476 | + for (; (c = o->cons.sbuf.Read(Point(x, line))) != '\0'; x++) { | |
477 | + o->cmdline[i++] = c; | |
478 | + } | |
479 | + x = 0; | |
480 | + } | |
481 | + o->cmdline[i] = '\0'; | |
290 | 482 | |
483 | + RunCommand(o); | |
484 | + | |
485 | + o->cmdlineBegin = o->cons.wPos.Y; | |
486 | + PutChar0(o, '>'); | |
487 | + } | |
291 | 488 | } |
292 | 489 | |
293 | 490 | void PutString0(Valiables* o, const char* str) |
@@ -307,6 +504,7 @@ | ||
307 | 504 | |
308 | 505 | void ConsoleRefreshScreen(Valiables* o, int begin) |
309 | 506 | { |
507 | +#if 0 | |
310 | 508 | int lines = o->cons.height; |
311 | 509 | if (begin < 0) { |
312 | 510 | // 自動計算モード |
@@ -327,7 +525,7 @@ | ||
327 | 525 | begin = o->cons.startLine; |
328 | 526 | } else { |
329 | 527 | lines = o->cons.height; |
330 | - begin = o->cons.endLine - o->cons.height; | |
528 | + begin = o->cons.endLine - o->cons.height + 1; | |
331 | 529 | if (begin < 0) { |
332 | 530 | begin += o->cons.bufHeight; |
333 | 531 | } |
@@ -336,9 +534,11 @@ | ||
336 | 534 | o->img->DrawRectangleFill( |
337 | 535 | o->cons.backColor, Point(0, 25), Point(o->img->width - 1, o->img->height - 1)); |
338 | 536 | int line = begin; |
537 | + Debug::WriteLine("refreshing l=%d,ls=%d", line, lines); | |
339 | 538 | for (int y = 0; y < lines; y++) { |
340 | 539 | for (int x = 0; x < o->cons.width; x++) { |
341 | - char ch = o->cons.buf[line * o->cons.bufWidth + x]; | |
540 | + //char ch = o->cons.buf[line * o->cons.bufWidth + x]; | |
541 | + char ch = ReadBuffer(o, x, line); | |
342 | 542 | if (ch == '\0') { |
343 | 543 | break; |
344 | 544 | } |
@@ -357,12 +557,43 @@ | ||
357 | 557 | } |
358 | 558 | } |
359 | 559 | o->sht->Refresh(); |
560 | +#endif | |
561 | + if (begin < 0) { | |
562 | + begin = o->cons.wPos.Y - o->cons.height + 1; | |
563 | + if (begin < 0) { | |
564 | + begin = 0; | |
565 | + } | |
566 | + } | |
567 | + o->img->DrawRectangleFill( | |
568 | + o->cons.backColor, Point(0, 25), Point(o->img->width - 1, o->img->height - 1)); | |
569 | + for (int lines = 0; begin + lines <= o->cons.sbuf.GetHeight() && lines < o->cons.height; lines++) { | |
570 | + o->img->DrawString( | |
571 | + o->cons.textColor, | |
572 | + o->cons.sbuf.GetPointer(Point(0, begin + lines)), | |
573 | + Point(4, 25 + 4 + lines * fontHankaku->GetHeight()), | |
574 | + fontHankaku); | |
575 | + } | |
576 | + o->sht->Refresh(); | |
360 | 577 | } |
361 | 578 | |
362 | 579 | void RunCommand(Valiables* o) |
363 | 580 | { |
364 | 581 | char s[256]; |
365 | - if (strncmp(o->cmdline, "mem", 4) == 0) { | |
582 | + char* command = o->cmdline; | |
583 | + char* args; | |
584 | + int i = 0; | |
585 | + while (command[i] != ' ' && command[i] != '\0') { | |
586 | + i++; | |
587 | + } | |
588 | + if (command[i] == ' ') { | |
589 | + command[i] = '\0'; | |
590 | + i++; | |
591 | + while (command[i] == ' ') { | |
592 | + i++; | |
593 | + } | |
594 | + } | |
595 | + args = command + i; | |
596 | + if (strncmp(command, "mem", 4) == 0) { | |
366 | 597 | PutString0(o, "mem : "); |
367 | 598 | sprintf(s, "%10d", physicalMemorySize); |
368 | 599 | if ((physicalMemorySize >> 30) != 0) { |
@@ -397,7 +628,7 @@ | ||
397 | 628 | } |
398 | 629 | PutString0(o, s + 7, 3); |
399 | 630 | PutString0(o, " B\n"); |
400 | - } else if (strncmp(o->cmdline, "opencons", 9) == 0) { | |
631 | + } else if (strncmp(command, "opencons", 9) == 0) { | |
401 | 632 | Task* consTask = taskman->Alloc(); |
402 | 633 | uintptr_t stackTop; |
403 | 634 | uint32_t stackSize; |
@@ -406,23 +637,39 @@ | ||
406 | 637 | TaskConsole::Init, DummyFunc, TaskConsole::Proc); |
407 | 638 | consTask->InitQueue(128); |
408 | 639 | taskman->Run(consTask, 1, 2); |
640 | + } else if (strncmp(command, "echo", 5) == 0) { | |
641 | + PutString0(o, args); | |
642 | + PutChar0(o, '\n'); | |
643 | + } else if (strncmp(command, "beep", 5) == 0) { | |
644 | + int cnt = 2712; | |
645 | + int freq = 1193180; | |
646 | + if (args[0] != '\0') { | |
647 | + cnt = ((freq << 10) / strtol(args, 0, 0) + 512) >> 10; | |
648 | + } | |
649 | + // freq = 1.19318MHz / cnt | |
650 | + io_out8(0x0043, 0xb6); | |
651 | + io_out8(0x0042, (cnt & 0x00ff)); | |
652 | + io_out8(0x0042, ((cnt >> 8) & 0x00ff)); | |
653 | + uint8_t reg = io_in8(0x0061); | |
654 | + reg |= 0x03; | |
655 | + reg &= 0x0f; | |
656 | + io_out8(0x0061, reg); | |
657 | + o->timBeep->SetTime(100); | |
658 | + } else if (strncmp(command, "eco", 4) == 0) { | |
659 | + PutString0(o, " tree \n"); | |
660 | + PutString0(o, " tree tree \n"); | |
661 | + PutString0(o, "tree tree tree\n"); | |
409 | 662 | } else { |
410 | - PutString0(o, "unknown command\n"); | |
663 | + if (strlen(command) > 0) { | |
664 | + PutString0(o, "unknown command\n"); | |
665 | + } | |
411 | 666 | } |
412 | 667 | } |
413 | 668 | |
414 | 669 | void ShowCursor(Valiables* o) |
415 | 670 | { |
416 | - int end = o->cons.endLine; | |
417 | - if (end >= o->cons.height) { | |
418 | - end = o->cons.height - 1; | |
419 | - } | |
420 | 671 | Point pos; |
421 | - if (o->cons.xPos > 0) { | |
422 | - pos = Point(4 + o->cons.xPos * fontHankaku->GetWidth(), 25 + 4 + end * fontHankaku->GetHeight()); | |
423 | - } else { | |
424 | - pos = Point(4 + o->cons.width * fontHankaku->GetWidth(), 25 + 4 + (end - 1) * fontHankaku->GetHeight()); | |
425 | - } | |
672 | + pos = Point(4 + o->cons.pPos.X * fontHankaku->GetWidth(), 25 + 4 + o->cons.pPos.Y * fontHankaku->GetHeight()); | |
426 | 673 | o->sht->DrawRectangleFill( |
427 | 674 | o->cons.textColor, |
428 | 675 | pos, |
@@ -431,21 +678,34 @@ | ||
431 | 678 | |
432 | 679 | void EraseCursor(Valiables* o) |
433 | 680 | { |
434 | - int end = o->cons.endLine; | |
435 | - if (end >= o->cons.height) { | |
436 | - end = o->cons.height - 1; | |
437 | - } | |
438 | 681 | Point pos; |
439 | - if (o->cons.xPos > 0) { | |
440 | - pos = Point(4 + o->cons.xPos * fontHankaku->GetWidth(), 25 + 4 + end * fontHankaku->GetHeight()); | |
441 | - } else { | |
442 | - pos = Point(4 + o->cons.width * fontHankaku->GetWidth(), 25 + 4 + (end - 1) * fontHankaku->GetHeight()); | |
443 | - } | |
682 | + pos = Point(4 + o->cons.pPos.X * fontHankaku->GetWidth(), 25 + 4 + o->cons.pPos.Y * fontHankaku->GetHeight()); | |
444 | 683 | o->sht->DrawRectangleFill( |
445 | 684 | o->cons.backColor, |
446 | 685 | pos, |
447 | - pos + Point(1, fontHankaku->GetHeight() - 1)); | |
686 | + pos + Point(0, fontHankaku->GetHeight() - 1)); | |
448 | 687 | } |
449 | 688 | |
689 | +void WriteBuffer(Valiables* o, int x, int y, char ch) | |
690 | +{ | |
691 | + if (x < 0 || o->cons.bufWidth <= x) { | |
692 | + Debug::WriteLine("write : x is wrong."); | |
693 | + } | |
694 | + if (y < 0 || o->cons.bufHeight <= y) { | |
695 | + Debug::WriteLine("write : y is wrong."); | |
696 | + } | |
697 | + o->cons.buf[y * o->cons.bufWidth + x] = ch; | |
698 | +} | |
699 | +char ReadBuffer(Valiables* o, int x, int y) | |
700 | +{ | |
701 | + if (x < 0 || o->cons.bufWidth <= x) { | |
702 | + Debug::WriteLine("read : x is wrong."); | |
703 | + } | |
704 | + if (y < 0 || o->cons.bufHeight <= y) { | |
705 | + Debug::WriteLine("read : y is wrong."); | |
706 | + } | |
707 | + return o->cons.buf[y * o->cons.bufWidth + x]; | |
708 | +} | |
450 | 709 | |
710 | + | |
451 | 711 | } |
@@ -9,7 +9,49 @@ | ||
9 | 9 | #define CONSOLE_H_ |
10 | 10 | |
11 | 11 | #include <stdint.h> |
12 | +#include <bitnos/point.h> | |
12 | 13 | |
14 | +namespace TaskConsole | |
15 | +{ | |
16 | +// charの2次元配列リングバッファ | |
17 | +class ScreenBuffer | |
18 | +{ | |
19 | + char* buf; | |
20 | + int width, height; | |
21 | + int begin; // データの先頭位置 | |
22 | + | |
23 | +public: | |
24 | + void Init(int width, int height); | |
25 | + | |
26 | + void Dispose(); | |
27 | + | |
28 | + void Write(Point pos, char ch); | |
29 | + | |
30 | + void Write(Point pos, const char* str); | |
31 | + | |
32 | + char Read(Point pos) const; | |
33 | + | |
34 | + const char* GetPointer(Point pos) const; | |
35 | + | |
36 | + void Scroll(int lines); | |
37 | + | |
38 | + int GetWidth() const | |
39 | + { | |
40 | + return width; | |
41 | + } | |
42 | + | |
43 | + int GetHeight() const | |
44 | + { | |
45 | + return height; | |
46 | + } | |
47 | + | |
48 | +private: | |
49 | + bool IsAvailable(Point pos) const; | |
50 | + | |
51 | + Point Calculate(Point pos) const; | |
52 | +}; | |
53 | + | |
54 | + | |
13 | 55 | struct Console |
14 | 56 | { |
15 | 57 | int width; // 横の文字数 |
@@ -21,10 +63,16 @@ | ||
21 | 63 | int startLine; // バッファの開始行 |
22 | 64 | int endLine; // バッファの終了行(書き込み行) |
23 | 65 | int xPos; // 書き込みの横位置 |
66 | + int printYPos; // 表示の縦位置 | |
24 | 67 | |
25 | 68 | uint16_t backColor; // 背景色 |
26 | 69 | uint16_t textColor; // 前景色 |
70 | + | |
71 | + ScreenBuffer sbuf; | |
72 | + Point wPos; // 書き込みの位置 | |
73 | + Point pPos; // 表示の位置 | |
27 | 74 | }; |
75 | +} | |
28 | 76 | |
29 | 77 | class Message; |
30 | 78 |