7 在窗口中描绘字符和方块(harib19g)

虽然时间已经很晚了,大家也很困了,不过看到成功显示出窗口,我们的精神又振奋了起来,所以我们再来试一下在窗口上显示字符和方块吧。这两个功能都是现成的,只要加在API上面就可以了。

在窗口上显示字符的API如下:

EDX = 6

EBX = 窗口句柄

ESI = 显示位置的x坐标

EDI = 显示位置的y坐标

EAX = 色号

ECX = 字符串长度

EBP = 字符串

描绘方块的API如下:

EDX = 7

EBX = 窗口句柄

EAX = x0

ECX = y0

ESI = x1

EDI = y1

EBP = 色号

哎哟,真悬,如果再多一个参数寄存器就要不够用了。

■■■■■

接下来就是写程序了,这个简单。

本次的console.c节选

  1. int *hrb_api(int edi, int esi, int ebp, int esp, int ebx, int edx, int ecx, int eax)
  2. {
  3. (中略)
  4. if (edx == 1) {
  5. cons_putchar(cons, eax & 0xff, 1);
  6. } else if (edx == 2) {
  7. cons_putstr0(cons, (char *) ebx + ds_base);
  8. } else if (edx == 3) {
  9. cons_putstr1(cons, (char *) ebx + ds_base, ecx);
  10. } else if (edx == 4) {
  11. return &(task->tss.esp0);
  12. } else if (edx == 5) {
  13. (中略)
  14. } else if (edx == 6) { /*从此开始*/
  15. sht = (struct SHEET *) ebx;
  16. putfonts8_asc(sht->buf, sht->bxsize, esi, edi, eax, (char *) ebp + ds_base);
  17. sheet_refresh(sht, esi, edi, esi + ecx * 8, edi + 16);
  18. } else if (edx == 7) {
  19. sht = (struct SHEET *) ebx;
  20. boxfill8(sht->buf, sht->bxsize, ebp, eax, ecx, esi, edi);
  21. sheet_refresh(sht, eax, ecx, esi + 1, edi + 1); /*到此结束*/
  22. }
  23. return 0;
  24. }

操作系统的修改完成了,下面来修改应用程序。

本次的a_nask.nas节选

  1. _api_putstrwin: ; void api_putstrwin(int win, int x, int y, int col, int len, char *str);
  2. PUSH EDI
  3. PUSH ESI
  4. PUSH EBP
  5. PUSH EBX
  6. MOV EDX,6
  7. MOV EBX,[ESP+20] ; win
  8. MOV ESI,[ESP+24] ; x
  9. MOV EDI,[ESP+28] ; y
  10. MOV EAX,[ESP+32] ; col
  11. MOV ECX,[ESP+36] ; len
  12. MOV EBP,[ESP+40] ; str
  13. INT 0x40
  14. POP EBX
  15. POP EBP
  16. POP ESI
  17. POP EDI
  18. RET
  19. _api_boxfilwin: ; void api_boxfilwin(int win, int x0, int y0, int x1, int y1, int col);
  20. PUSH EDI
  21. PUSH ESI
  22. PUSH EBP
  23. PUSH EBX
  24. MOV EDX,7
  25. MOV EBX,[ESP+20] ; win
  26. MOV EAX,[ESP+24] ; x0
  27. MOV ECX,[ESP+28] ; y0
  28. MOV ESI,[ESP+32] ; x1
  29. MOV EDI,[ESP+36] ; y1
  30. MOV EBP,[ESP+40] ; col
  31. INT 0x40
  32. POP EBX
  33. POP EBP
  34. POP ESI
  35. POP EDI
  36. RET

本次的winhelo2.c节选

  1. int api_openwin(char *buf, int xsiz, int ysiz, int col_inv, char *title);
  2. void api_putstrwin(int win, int x, int y, int col, int len, char *str);
  3. void api_boxfilwin(int win, int x0, int y0, int x1, int y1, int col);
  4. void api_end(void);
  5. char buf[150 * 50];
  6. void HariMain(void)
  7. {
  8. int win;
  9. win = api_openwin(buf, 150, 50, -1, "hello");
  10. api_boxfilwin(win, 8, 36, 141, 43, 3 /*黄色*/);
  11. api_putstrwin(win, 28, 28, 0 /*黑色*/, 12, "hello, world");
  12. api_end();
  13. }

■■■■■

大功告成,“make run”之后结果如下。对了,刚刚忘记说了,bug1.hrb已经没有用了,所以把它删掉了哦。

7 在窗口中描绘字符和方块(harib19g) - 图1

完成了!

运行得很顺利,心里相当满意呀。那么今天就到这里吧,大家晚安,明天见哦。