* wiki版のintroシリーズ no.0002 -(by [[K]], 2004.12.15) -これはC言語でもASKAでもnaskでもとにかくごちゃまぜでintroしてしまおうというこころみ。 --これは[[guide/wintro0001]]の続きなので、それを読んでない人はそれを読んでね。 ---最初から読みたい人は[[guide/ASKA]]や[[guide/nask]]からどうぞ。 --C言語をやる人はintroaを読むといいでしょう。ここのプログラムは、introaと同一内容です。 -質問とか感想とかはこめんと欄にレッツゴー。 *** countdown -C版:"cntdwnc1.c" [osa_dir2では 617バイト] /* "cntdwnc1.c":countdwnをC言語で記述した例 */ /* stack:4k malloc:1k */ #include <guigui00.h> #define AUTO_MALLOC 0 void setdec3(int i, char *s); void OsaskMain() { struct LIB_WINDOW *window; struct LIB_TEXTBOX *wintitle, *textbox; int count; static char msg[] = "000"; /* ライブラリ初期化 */ lib_init(AUTO_MALLOC); /* ウィンドウオープン */ window = lib_openwindow(AUTO_MALLOC, 0x0200, 18 * 8, 1 * 16); wintitle = lib_opentextbox(0x1000, AUTO_MALLOC, 0, 8, 1, 0, 0, window, 0x00c0, 0); textbox = lib_opentextbox(0x0000, AUTO_MALLOC, 0, 3, 1, 56, 0, window, 0x00c0, 0); lib_putstring_ASCII(0x0000, 0, 0, wintitle, 0, 0, "cntdwnc1"); /* メインループ */ for (;;) { for (count = 100; count > 0; count--) { setdec3(count, msg); lib_putstring_ASCII(0x0000, 0, 0, textbox, 0, 0, msg); lib_waitsignaltime(0x0007, 0, 0, 0, 1, 0); /* 1秒待つ */ } lib_putstring_ASCII(0x0000, 0, 0, textbox, 0, 0, "GO!"); lib_waitsignaltime(0x0007, 0, 0, 0, 10, 0); /* 10秒待つ */ } } void setdec3(int i, char *s) /* 注意:このルーチンでは、0~999までしか扱えない */ { s[0] = '0' + i / 100; i %= 100; s[1] = '0' + i / 10; s[2] = '0' + i % 10; if (s[0] == '0') { s[0] = ' '; if (s[1] == '0') s[1] = ' '; } return; } -ASKA版:"cntdwna1.ask" [osa_dir2では 249バイト] /* "cntdwna1.ask":countdwnをASKAで記述した例 */ /* stack:4k malloc:0k */ segment CODE(USE32, PARA); default(code == CODE); asmout("[FILE 'cntdwna1.ask']"); asmout("GLOBAL _OsaskMain"); void setdec3(); /* EAXをDS:ESIに書き込む */ void _OsaskMain() { asmout("MOV EBX,data.init"); CALL(0xc7, 0); for (;;) { unsigned int count == EAX; count = 100; do { asmout("MOV EBX,data.putnum"); LEA(ESI, [EBX + 36]); setdec3(); CALL(0xc7, 0); count--; } while (!= 0); asmout("MOV EBX,data.putgo"); CALL(0xc7, 0); } } void setdec3() { char *s == DS:ESI; PUSH(EDX); PUSH(ECX); PUSH(EAX); EDX = 0; ECX = 10; DIV(ECX); /* EDX:EAX / ECX = EAX ... EDX */ DIV(CL); /* AX / CL = AL ... AH */ EAX |= 0x3030; /* '00' */ DL |= 0x30; if (AL == 0x30) { AL = 0x20; /* ' ' */ if (AH == 0x30) AH = 0x20; } s[0] = AL; s[1] = AH; s[2] = DL; POP(EAX); POP(ECX); POP(EDX); return; } asmout("[SECTION .data]"); void data() { ALIGNB(4); init: asmout("DD 0x0004, data.work"); /* lib_init */ asmout("DD 0x0020, data.window, 0x0200, 18 * 8, 1 * 16"); /* lib_openwindow */ asmout("DD 0x0028, 0x1000, data.wintitle, 0, 8, 1, 0, 0, data.window, 0x00c0, 0"); /* lib_opentextbox */ asmout("DD 0x0028, 0x0000, data.textbox, 0, 3, 1, 56, 0, data.window, 0x00c0, 0"); /* lib_opentextbox */ asmout("DD 0x0040, 0x1000, 0, 0, data.wintitle, 0, 0, 0, 8, 'cntdwna1'"); /* lib_putstring1 */ DD(0x0000); /* end of functions */ putnum: asmout("DD 0x0040, 0x1000, 0, 0, data.textbox, 0, 0, 0, 3, '000'"); /* lib_putstring1 */ DD(0x0018, 0x0007, 0, 0, 0, 1, 0); /* lib_waitsignaltime */ DD(0x0000); /* end of functions */ putgo: asmout("DD 0x0040, 0x1000, 0, 0, data.textbox, 0, 0, 0, 3, 'GO!'"); /* lib_putstring1 */ DD(0x0018, 0x0007, 0, 0, 0, 10, 0); /* lib_waitsignaltime */ DD(0x0000); /* end of functions */ ALIGNB(8); work: RESB(256); /* func_initに必要な256バイトのワークエリア */ window: RESB(128); /* ウィンドウ構造体 */ wintitle: RESB(64); /* テキストボックス構造体 */ RESB(64); /* 8x1文字分 (8 * 1 * 8) */ textbox: RESB(64); /* テキストボックス構造体 */ RESB(24); /* 3x1文字分 (3 * 1 * 8) */ } -''以下未完成'' -nask版:"cntdwnn1.nas" [osa_dir2では バイト] ; "cntdwnn1.nas":countdwnをnaskで記述した例 ; stack:4k malloc:0k [FORMAT "WCOFF"] [INSTRSET "i486p"] [OPTIMIZE 1] [OPTION 1] [BITS 32] [FILE "cntdwnn1.nas"] [SECTION .text] GLOBAL _OsaskMain _OsaskMain: MOV EBX,init CALL 0xc7:0 .mainloop: MOV EAX,100 .countloop: MOV EBX,putnum LEA ESI,[EBX+36] CALL setdec3 CALL 0xc7:0 DEC EAX CMP AL,16 JNZ .countloop MOV EBX,putgo CALL 0xc7:0 JMP .mainloop setdec2: PUSH EDX PUSH ECX PUSH EAX XOR EDX,EDX MOV ECX,10 DIV ECX DIV CL OR EAX,'00' OR DL,'0' CMP AL,'0' JNE .skip MOV AL,' ' CMP AH,'0' JNE .skip MOV AH,' ' .skip: MOV [ESI+0],AL MOV [ESI+1],AH MOV [ESI+2],DL POP EAX POP ECX POP EDX RET ;;; [SECTION .data] ALIGNB 4 init: DD 0x0004, work ; lib_init DD 0x0020, window, 0x0200, 20 * 8, 8 * 16 ; lib_openwindow DD 0x0028, 0x1000, wintitle, 0, 7, 1, 0, 0, window, 0x00c0, 0 ; lib_opentextbox DD 0x0028, 0x0001, textbox, 0, 20, 8, 0, 0, window, 0x00c0, 0 ; lib_opentextbox DD 0x0040, 0x1000, 0, 0, wintitle, 0, 0, 0, 7, 'colorn1' ; lib_putstring1 DD 0x0000 ; end of functions putstr: DD 0x0040, 0x1000, 0, 0, textbox, 0, 0, 0, 8, 'color ' ; lib_putstring1 DD 0x0000 ; end of functions sleep: DD 0x0018, 0x0001, 0, 0 ; lib_waitsignal DD 0x0000 ; end of functions ALIGNB 8 work: RESB 256 ; func_initに必要な256バイトのワークエリア window: RESB 128 ; ウィンドウ構造体 wintitle: RESB 64 + 7 * 1 * 8; テキストボックス構造体(7x1文字分) textbox: RESB 64 + 20 * 8 * 8; テキストボックス構造体(20x8文字分) *** 説明 -概要: --このプログラムは、ウィンドウを一つ開き、そのウィンドウに16色のメッセージを表示するだけのプログラムです。 --このプログラムを通じて、テキストに色を付ける方法と、数字表示の方法について説明します。 --OSASKでは、printf()やitoa()などの便利な関数がまだ用意されていません。したがっ て、残念なことに数字を表示するのは少し面倒です。今回はitoaの代わりにsetdec2()という関数を作ってみました。 --これくらいの規模の例になると、CとASKAとnaskの文法の違いが出てきますので、見比べてみるのも面白いかもしれません。どれでもいいのですので、好きな言語を活用してください。 -APIの説明: --lib_opentextbox(opt, textbox, backcolor, x_size, y_size, x_pos, y_pos, window, charset, init_char) : ---ウィンドウにテキストボックスを貼ります。optの値は、0と0x1000しか紹介していませんでしたが、実は1も使えます。optに1を指定すると、テキストボックスに外枠が付きます。また、背景色が選べるようになり、それはbackcolorで指定します。それ以外はoptに0を指定した場合と全く同様です。なお、この枠がウィンドウをはみ出たり他の表示と重なったりしないようにしてください。 --lib_putstring_ASCII(opt, x_pos, y_pos, textbox, color, backcolor, str) : ---colorc1.cでは使われていませんが、optに1を指定することにより、この関数でもbackcolorが有効になります。これは文字の背景色を文字単位で指定するものです。ちなみにスペースを表示した場合、backcolorで指定した色の四角形が表示されます。 ---ASKA/naskのlib_putstring1も全く同様で、optの最下位ビットを1にすると、backcolorに0以外を指定できるようになります。 *** まとめ -これで、テキストボックスを使った表示は一通りできるようになったはずです。許される範囲であちこちを改造して、把握してください。この程度のことなら、決して難しくないと感じていただけるはずです。 -なお、C版でテキストボックスを広げる際には、malloc領域が不足する可能性があるので、malloc:オプションの値を大きくしてやってください。ASKA/naskでは、テキストボックス構造体のサイズを間違えなければ、mallocは0kのままでかまいません。 -''以上未完成'' *** おまけ -次回(no.0003)はキー入力を少しやります。これで、キー入力を反映できるようになるでしょう。 -読んでいる人が追いつけないほど先に進んでもしょうがないので、こめんと欄でリクエストきたら次回を書き始めます。 * こめんと欄 #comment