1: 2004-12-15 (水) 18:03:19 |
現: 2024-01-08 (月) 12:58:56 k-tan |
- | * wiki版のintroシリーズ no.0002 | + | TITLE:x |
| + | * wiki版のintroシリーズ no.0002 [#k58fd08c] |
| -(by [[K]], 2004.12.15) | | -(by [[K]], 2004.12.15) |
| -これはC言語でもASKAでもnaskでもとにかくごちゃまぜでintroしてしまおうというこころみ。 | | -これはC言語でもASKAでもnaskでもとにかくごちゃまぜでintroしてしまおうというこころみ。 |
| --これは[[guide/wintro0001]]の続きなので、それを読んでない人はそれを読んでね。 | | --これは[[guide/wintro0001]]の続きなので、それを読んでない人はそれを読んでね。 |
- | ---最初から読みたい人は[[guide/ASKA]]や[[guide/nask]]からどうぞ。 | + | ---最初から読みたい人は[[guide/C]]や[[guide/ASKA]]や[[guide/nask]]からどうぞ。 |
| --C言語をやる人はintroaを読むといいでしょう。ここのプログラムは、introaと同一内容です。 | | --C言語をやる人はintroaを読むといいでしょう。ここのプログラムは、introaと同一内容です。 |
| -質問とか感想とかはこめんと欄にレッツゴー。 | | -質問とか感想とかはこめんと欄にレッツゴー。 |
| | | |
- | *** countdown | + | *** countdown [#v307e891] |
- | -C版:"cntdwnc1.c" [osa_dir2では バイト] | + | -C版:"cntdwnc1.c" [tolset08では 538バイト] |
| + | //-C版:"cntdwnc1.c" [osa_dir2では 617バイト] |
| /* "cntdwnc1.c":countdwnをC言語で記述した例 */ | | /* "cntdwnc1.c":countdwnをC言語で記述した例 */ |
- | /* stack:20k malloc:1k */ | + | /* stack:4k malloc:1k */ |
| + | |
| #include <guigui00.h> | | #include <guigui00.h> |
| + | |
| #define AUTO_MALLOC 0 | | #define AUTO_MALLOC 0 |
| + | |
| void setdec3(int i, char *s); | | void setdec3(int i, char *s); |
| + | |
| void OsaskMain() | | void OsaskMain() |
| { | | { |
| int count; | | int count; |
| static char msg[] = "000"; | | static char msg[] = "000"; |
| + | |
| /* ライブラリ初期化 */ | | /* ライブラリ初期化 */ |
| lib_init(AUTO_MALLOC); | | lib_init(AUTO_MALLOC); |
| + | |
| /* ウィンドウオープン */ | | /* ウィンドウオープン */ |
| window = lib_openwindow(AUTO_MALLOC, 0x0200, 18 * 8, 1 * 16); | | window = lib_openwindow(AUTO_MALLOC, 0x0200, 18 * 8, 1 * 16); |
| textbox = lib_opentextbox(0x0000, AUTO_MALLOC, 0, 3, 1, 56, 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"); | | lib_putstring_ASCII(0x0000, 0, 0, wintitle, 0, 0, "cntdwnc1"); |
| + | |
| /* メインループ */ | | /* メインループ */ |
| for (;;) { | | for (;;) { |
| } | | } |
| } | | } |
| + | |
| void setdec3(int i, char *s) | | void setdec3(int i, char *s) |
| /* 注意:このルーチンでは、0~999までしか扱えない */ | | /* 注意:このルーチンでは、0~999までしか扱えない */ |
| return; | | return; |
| } | | } |
| + | |
| | | |
- | | + | -ASKA版:"cntdwna1.ask" [tolset08では 219バイト] |
- | -''以下未完成'' | + | //-ASKA版:"cntdwna1.ask" [osa_dir2では 249バイト] |
- | | + | /* "cntdwna1.ask":countdwnをASKAで記述した例 */ |
- | | + | /* stack:4k malloc:0k */ |
- | -ASKA版:"colora1.ask" [osa_dir2では 240バイト] | + | segment CODE(USE32, PARA); default(code == CODE); asmout("[FILE 'cntdwna1.ask']"); |
- | /* "colora1.ask":colorをASKAで記述した例 */ | + | |
- | /* stack:20k malloc:0k */ | + | |
- | segment CODE(USE32, PARA); default(code == CODE); asmout("[FILE 'colora1.ask']"); | + | |
| asmout("GLOBAL _OsaskMain"); | | asmout("GLOBAL _OsaskMain"); |
- | | + | |
- | void setdec2(); /* ALをDS:ESIに書き込む */ | + | void setdec3(); /* EAXをDS:ESIに書き込む */ |
| + | |
| void _OsaskMain() | | void _OsaskMain() |
| { | | { |
| asmout("MOV EBX,data.init"); CALL(0xc7, 0); | | asmout("MOV EBX,data.init"); CALL(0xc7, 0); |
- | | + | |
- | unsigned char i == AL, x == CL, y == CH; | + | for (;;) { |
- | i = 0; | + | unsigned int count == EAX; |
- | do { | + | count = 100; |
- | asmout("MOV EBX,data.putstr"); | + | do { |
- | x = 10; | + | asmout("MOV EBX,data.putnum"); |
- | y = i; | + | LEA(ESI, [EBX + 36]); |
- | y /= 2; | + | setdec3(); |
- | if (CF == 0) | + | CALL(0xc7, 0); |
- | x = 0; /* yが割り切れたらxは0に */ | + | count--; |
- | [EBX + 8] = x; | + | } while (!= 0); |
- | [EBX + 12] = y; | + | asmout("MOV EBX,data.putgo"); |
- | [EBX + 20] = i; | + | |
- | LEA(ESI, [EBX + 42]); | + | |
- | setdec2(); | + | |
| CALL(0xc7, 0); | | CALL(0xc7, 0); |
- | i++; | + | } |
- | } while (i < 16); | + | |
- | | + | |
- | asmout("MOV EBX,data.sleep"); CALL(0xc7, 0); | + | |
| } | | } |
- | | + | |
- | void setdec2() | + | void setdec3() |
| { | | { |
| char *s == DS:ESI; | | char *s == DS:ESI; |
| + | PUSH(EDX); |
| PUSH(ECX); | | PUSH(ECX); |
| PUSH(EAX); | | PUSH(EAX); |
- | CL = 10; | + | EDX = 0; |
- | AH = 0; | + | ECX = 10; |
- | DIV(CL); /* AX / CL = AL ... AH */ | + | DIV(ECX); /* EDX:EAX / ECX = EAX ... EDX */ |
| + | DIV(CL); /* AX / CL = AL ... AH */ |
| EAX |= 0x3030; /* '00' */ | | EAX |= 0x3030; /* '00' */ |
- | if (AL == 0x30) | + | DL |= 0x30; |
| + | if (AL == 0x30) { |
| AL = 0x20; /* ' ' */ | | AL = 0x20; /* ' ' */ |
| + | if (AH == 0x30) |
| + | AH = 0x20; |
| + | } |
| s[0] = AL; | | s[0] = AL; |
| s[1] = AH; | | s[1] = AH; |
| + | s[2] = DL; |
| POP(EAX); | | POP(EAX); |
| POP(ECX); | | POP(ECX); |
| + | POP(EDX); |
| return; | | return; |
| } | | } |
| + | |
| asmout("[SECTION .data]"); | | asmout("[SECTION .data]"); |
| + | |
| void data() | | void data() |
| { | | { |
| init: | | init: |
| asmout("DD 0x0004, data.work"); /* lib_init */ | | asmout("DD 0x0004, data.work"); /* lib_init */ |
- | asmout("DD 0x0020, data.window, 0x0200, 20 * 8, 8 * 16"); /* lib_openwindow */ | + | asmout("DD 0x0020, data.window, 0x0200, 18 * 8, 1 * 16"); /* lib_openwindow */ |
- | asmout("DD 0x0028, 0x1000, data.wintitle, 0, 7, 1, 0, 0, data.window, 0x00c0, 0"); /* lib_opentextbox */ | + | asmout("DD 0x0028, 0x1000, data.wintitle, 0, 8, 1, 0, 0, data.window, 0x00c0, 0"); /* lib_opentextbox */ |
- | asmout("DD 0x0028, 0x0001, data.textbox, 0, 20, 8, 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, 7, 'colora1'"); /* lib_putstring1 */ | + | asmout("DD 0x0040, 0x1000, 0, 0, data.wintitle, 0, 0, 0, 8, 'cntdwna1'"); /* lib_putstring1 */ |
| DD(0x0000); /* end of functions */ | | DD(0x0000); /* end of functions */ |
- | putstr: | + | putnum: |
- | asmout("DD 0x0040, 0x1000, 0, 0, data.textbox, 0, 0, 0, 8, 'color '"); /* lib_putstring1 */ | + | 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 */ | | DD(0x0000); /* end of functions */ |
- | sleep: | + | putgo: |
- | DD(0x0018, 0x0001, 0, 0); /* lib_waitsignal */ | + | 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 */ | | DD(0x0000); /* end of functions */ |
| + | |
| ALIGNB(8); | | ALIGNB(8); |
| work: | | work: |
| wintitle: | | wintitle: |
| RESB(64); /* テキストボックス構造体 */ | | RESB(64); /* テキストボックス構造体 */ |
- | RESB(56); /* 7x1文字分 (7 * 1 * 8) */ | + | RESB(64); /* 8x1文字分 (8 * 1 * 8) */ |
| textbox: | | textbox: |
| RESB(64); /* テキストボックス構造体 */ | | RESB(64); /* テキストボックス構造体 */ |
- | RESB(1280); /* 20x8文字分 (20 * 8 * 8) */ | + | RESB(24); /* 3x1文字分 (3 * 1 * 8) */ |
| } | | } |
| + | |
| | | |
- | | + | -nask版:"cntdwnn1.nas" [tolset08では 219バイト] |
- | -nask版:"colorn1.nas" [osa_dir2では 238バイト] | + | //-nask版:"cntdwnn1.nas" [osa_dir2では 249バイト] |
- | ; "colorn1.nas":colorをnaskで記述した例 | + | ; "cntdwnn1.nas":countdwnをnaskで記述した例 |
- | ; stack:20k malloc:0k | + | ; stack:4k malloc:0k |
| + | |
| [FORMAT "WCOFF"] | | [FORMAT "WCOFF"] |
| [INSTRSET "i486p"] | | [INSTRSET "i486p"] |
| [OPTION 1] | | [OPTION 1] |
| [BITS 32] | | [BITS 32] |
- | [FILE "colorn1.nas"] | + | [FILE "cntdwnn1.nas"] |
| + | |
| [SECTION .text] | | [SECTION .text] |
| GLOBAL _OsaskMain | | GLOBAL _OsaskMain |
| + | |
| _OsaskMain: | | _OsaskMain: |
| MOV EBX,init | | MOV EBX,init |
| CALL 0xc7:0 | | CALL 0xc7:0 |
- | MOV AL,0 | |
| .mainloop: | | .mainloop: |
- | MOV EBX,putstr | + | MOV EAX,100 |
- | MOV CL,10 | + | .countloop: |
- | MOV CH,AL | + | MOV EBX,putnum |
- | SHR CH,1 | + | LEA ESI,[EBX+36] |
- | JC .skip | + | CALL setdec3 |
- | MOV CL,0 | + | |
- | .skip: | + | |
- | MOV [EBX+ 8],CL | + | |
- | MOV [EBX+12],CH | + | |
- | MOV [EBX+20],AL | + | |
- | LEA ESI,[EBX+42] | + | |
- | CALL setdec2 | + | |
| CALL 0xc7:0 | | CALL 0xc7:0 |
- | INC AL | + | DEC EAX |
- | CMP AL,16 | + | JNZ .countloop |
- | JB .mainloop | + | MOV EBX,putgo |
- | MOV EBX,sleep | + | |
| CALL 0xc7:0 | | CALL 0xc7:0 |
- | | + | JMP .mainloop |
- | setdec2: | + | |
| + | setdec3: |
| + | PUSH EDX |
| PUSH ECX | | PUSH ECX |
| PUSH EAX | | PUSH EAX |
- | MOV CL,10 | + | XOR EDX,EDX |
- | MOV AH,0 | + | MOV ECX,10 |
| + | DIV ECX |
| DIV CL | | DIV CL |
| OR EAX,'00' | | OR EAX,'00' |
| + | OR DL,'0' |
| CMP AL,'0' | | CMP AL,'0' |
| JNE .skip | | JNE .skip |
| MOV AL,' ' | | MOV AL,' ' |
| + | CMP AH,'0' |
| + | JNE .skip |
| + | MOV AH,' ' |
| .skip: | | .skip: |
| MOV [ESI+0],AL | | MOV [ESI+0],AL |
| MOV [ESI+1],AH | | MOV [ESI+1],AH |
| + | MOV [ESI+2],DL |
| POP EAX | | POP EAX |
| POP ECX | | POP ECX |
| + | POP EDX |
| RET | | RET |
- | | + | |
- | ; .で始まるラベルはローカルラベル。 | + | |
- | ; ローカルラベルは、次のグローバルラベル宣言までが有効範囲。 | + | |
| [SECTION .data] | | [SECTION .data] |
| ALIGNB 4 | | ALIGNB 4 |
| init: | | init: |
| DD 0x0004, work ; lib_init | | DD 0x0004, work ; lib_init |
- | DD 0x0020, window, 0x0200, 20 * 8, 8 * 16 ; lib_openwindow | + | DD 0x0020, window, 0x0200, 18 * 8, 1 * 16 ; lib_openwindow |
- | DD 0x0028, 0x1000, wintitle, 0, 7, 1, 0, 0, window, 0x00c0, 0 ; lib_opentextbox | + | DD 0x0028, 0x1000, wintitle, 0, 8, 1, 0, 0, window, 0x00c0, 0 ; lib_opentextbox |
- | DD 0x0028, 0x0001, textbox, 0, 20, 8, 0, 0, window, 0x00c0, 0 ; lib_opentextbox | + | DD 0x0028, 0x0000, textbox, 0, 3, 1, 56, 0, window, 0x00c0, 0 ; lib_opentextbox |
- | DD 0x0040, 0x1000, 0, 0, wintitle, 0, 0, 0, 7, 'colorn1' ; lib_putstring1 | + | DD 0x0040, 0x1000, 0, 0, wintitle, 0, 0, 0, 8, 'cntdwnn1' ; lib_putstring1 |
| DD 0x0000 ; end of functions | | DD 0x0000 ; end of functions |
- | putstr: | + | putnum: |
- | DD 0x0040, 0x1000, 0, 0, textbox, 0, 0, 0, 8, 'color ' ; lib_putstring1 | + | DD 0x0040, 0x1000, 0, 0, textbox, 0, 0, 0, 3, '000' ; lib_putstring1 |
| + | DD 0x0018, 0x0007, 0, 0, 0, 1, 0 ; lib_waitsignaltime |
| DD 0x0000 ; end of functions | | DD 0x0000 ; end of functions |
- | sleep: | + | putgo: |
- | DD 0x0018, 0x0001, 0, 0 ; lib_waitsignal | + | DD 0x0040, 0x1000, 0, 0, textbox, 0, 0, 0, 3, 'GO!' ; lib_putstring1 |
| + | DD 0x0018, 0x0007, 0, 0, 0, 10, 0 ; lib_waitsignaltime |
| DD 0x0000 ; end of functions | | DD 0x0000 ; end of functions |
| + | |
| ALIGNB 8 | | ALIGNB 8 |
| work: | | work: |
| RESB 128 ; ウィンドウ構造体 | | RESB 128 ; ウィンドウ構造体 |
| wintitle: | | wintitle: |
- | RESB 64 + 7 * 1 * 8; テキストボックス構造体(7x1文字分) | + | RESB 64 + 8 * 1 * 8; テキストボックス構造体(8x1文字分) |
| textbox: | | textbox: |
- | RESB 64 + 20 * 8 * 8; テキストボックス構造体(20x8文字分) | + | RESB 64 + 3 * 1 * 8; テキストボックス構造体(3x1文字分) |
| + | |
| | | |
- | | + | *** 説明 [#wd8c3e0c] |
- | *** 説明 | + | |
| -概要: | | -概要: |
- | --このプログラムは、ウィンドウを一つ開き、そのウィンドウに16色のメッセージを表示するだけのプログラムです。 | + | --このプログラムは、ウィンドウを一つ開き、そのウィンドウに1秒おきに数字を表示していくだけのプログラムです。 |
- | --このプログラムを通じて、テキストに色を付ける方法と、数字表示の方法について説明します。 | + | --このプログラムを通じて、一定時間タスクをスリープさせる方法を説明します。 |
- | --OSASKでは、printf()やitoa()などの便利な関数がまだ用意されていません。したがっ | + | --OSASKでは、アプリケーションが一定の時間を待つために、空のループをまわしたり、時刻を取得して比較を繰り返すようなことはしません。できないというわけではありませんが、CPUタイムの浪費につながりますから、もったいないです。したがって、所定の手続きを踏んで、時間が来るまでタスクをスリープさせます。 |
- | て、残念なことに数字を表示するのは少し面倒です。今回はitoaの代わりにsetdec2()という関数を作ってみました。 | + | |
- | --これくらいの規模の例になると、CとASKAとnaskの文法の違いが出てきますので、見比べてみるのも面白いかもしれません。どれでもいいのですので、好きな言語を活用してください。 | + | |
| | | |
| -APIの説明: | | -APIの説明: |
| + | --lib_waitsignaltime(opt, signaldw, nest, time0, time1, time2) : |
| + | ---タスクを一定時間スリープさせます。optには、0x7か0xfを指定できます。signaldwとnestは0にしてください。time0~time2の設定方法は、以下のようにしてください。まず、設定したい時間間隔を秒で表します。その整数部をtime1に書き込みます。もし、32bitで書ききれないのでしたら(そんなに長く待つことがあるのかどうかは分かりませんが)、time2に上位32bitを入れてください(time1だけで収まれば、time2はもちろん0です)。つまり、最大で5千万年くらいまでは指定できます(でも今のバージョンでは上位数ビットが生かされないかもしれないのでせいぜい数百万年くらいにしてください・・・笑)。また、秒単位では細かな制御には向かないでしょう。そこで、小数部に2^32を乗じた値をtime0に設定します。これで1ns(ナノ秒)よりも細かい単位で指定できることになります。実際はハードウェアの都合によりこの96bitの精度が完全に生かされるとは限りませんが、しかし限界まで生かす努力はします。 |
| + | ---optに0xfを指定した場合、この関数をコールした時刻から指定された時間だけ待った後にタスクは目覚めます。一方、optに0x7を指定した場合は、既に設定されている時間基点から指定された時間だけ待った後にタスクが目覚めます。時間基点というのは、タスクが起動した時刻のことですが、lib_waitsignaltime()でスリープすると目覚めた時刻が新しい時間基点にセットされます。今回のサンプルのようにできるだけ「秒」を意識するなら、optに0xfを指定するよりは0x7を指定する方がふさわしいでしょう。なぜなら、目覚めた直後にすぐにスリープするわけではなく、文字表示などをするからです。 |
| + | ---この処理を1ns以下に終えることは期待できませんから、0xfを指定すれば徐々にこの誤差が累積されることになります。0x7ならそういうことは原理的にありません。これで誤差が出る場合にはOSかハードウェアの問題であり、アプリケーションの問題ではありません。目的に応じて使い分けましょう。 |
| + | ---本来はこの関数は一定時間待つためのものではありません。時限付きシグナル待ちというもので、シグナルがくれば時刻に達していなくてもタスクはスリープから回復してしまいます。しかし今のところシグナルを一切扱っていないので、事実上、純粋な時間待ちの処理として利用できます。 |
| + | ---この時間間隔指定ですが、少なくとも10ミリ秒以上はあってほしいです。これは何も10ミリ秒単位であることを要請しているわけでありません。11.52ミリ秒などでもかまいません。また頻繁に繰り替えすことがないのなら、10ミリ秒を下回ってもかまいません。将来のOSASKでは、連続して何度も10ミリ秒以下の指定をした場合、OS側で強制的に10ミリ秒間間隔に補正される可能性があります。現在のOSASKでは、OSの動作が不安定になります。ですからやってはいけません。 |
| | | |
- | --lib_opentextbox(opt, textbox, backcolor, x_size, y_size, x_pos, y_pos, window, charset, init_char) : | + | *** まとめ [#o7f1dd60] |
- | ---ウィンドウにテキストボックスを貼ります。optの値は、0と0x1000しか紹介していませんでしたが、実は1も使えます。optに1を指定すると、テキストボックスに外枠が付きます。また、背景色が選べるようになり、それはbackcolorで指定します。それ以外はoptに0を指定した場合と全く同様です。なお、この枠がウィンドウをはみ出たり他の表示と重なったりしないようにしてください。 | + | -これで時間を細かく制御できるようになるはずです。時間とともに表示を操作すれば動きのある表示(アニメーション)ができるでしょう。ここまでのところではテキストしか扱えないので、テキストアニメーションしかできませんが。それでも、少しは遊べるはずです。もねさんがすぐに「msg00」や「msg01」を作ったのもうなずけます。 |
- | | + | -精密な時間制御が比較的簡単にできることはOSASKアプリの特徴の一つです。他のOSよりも簡単にマスターできることでしょう。 |
- | --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以外を指定できるようになります。 | + | |
| | | |
- | *** まとめ | + | *** おまけ [#tca81632] |
- | -これで、テキストボックスを使った表示は一通りできるようになったはずです。許される範囲であちこちを改造して、把握してください。この程度のことなら、決して難しくないと感じていただけるはずです。 | + | -次回(no.0003)はキー入力を少しやります。これで、キー入力を反映できるようになるでしょう。 |
- | -なお、C版でテキストボックスを広げる際には、malloc領域が不足する可能性があるので、malloc:オプションの値を大きくしてやってください。ASKA/naskでは、テキストボックス構造体のサイズを間違えなければ、mallocは0kのままでかまいません。 | + | -続編はこちら → [[guide/wintro0003]] |
| | | |
- | *** おまけ | + | * こめんと欄 [#z2bc8102] |
- | -次回(no.0002)は時間制御関係を少しやります。これで、変化のあるテキスト表示ができるようになるでしょう。 | + | -遅くなりましたが、リクエストします。このページのAPIの説明に"lib_waitsignaltime"が無いよぅ。 -- ''nika'' SIZE(10){2005-01-24 (月) 18:29:50} |
- | ~ | + | -リクエストありがとうございます。今月中にこのページを完成できるように、努力します。・・・ので気長にお持ちください。 -- [[K]] SIZE(10){2005-01-24 (月) 22:02:08} |
- | ~ | + | -とりあえずこのページはできました。次のページは2週間後くらいまでに書き上げるくらいのペースで準備します。 -- [[K]] SIZE(10){2005-01-25 (火) 23:31:17} |
- | -''実際の開発をするにあたって'' | + | -お疲れ様です。気長にお待ちしています。 -- ''nika'' SIZE(10){2005-01-25 (火) 23:52:43} |
- | --このwintroシリーズを読んでいる人は、introシリーズを読んでいない可能性もあるので、大事な注意を書いておきます。 | + | -tolset08対応&nask版のバグフィクス(17の次がGO!になっていた)。 -- [[K]] SIZE(10){2005-01-29 (土) 21:07:25} |
- | --初心者がよくやることの一つに、プログラムをゼロから作り始めようとして失敗する、というのがあります。これは、いきなりプロジェクトを作って、まっさらなテキストファイルからプログラムを書いていく、ということを意味します。これはたいていうまくいきません。これはOSASKアプリ開発に限らず、他のOSのアプリ開発を最初にやろうとしたときもでも同じことです。 | + | |
- | --うまい方法は、まず、適当なサンプルアプリを見つけてきて(helloでもいいです)、それをコピーしたところから出発することです。これを少し改造し(たとえばウィンドウサイズとウィンドウタイトルを望みの大きさに変えて)、改造したらすぐに make run してみます。それでうまく動いたらバンザイです。さらに少し改造を加えて、自分の目的のアプリに近づけていきます。・・・もし make run してうまく動かなければ、どこが悪いのかをウンウンうなったりするのではなく、まずは動いていた段階に帰ります。そして少しずつ改造を戻していくことによって、どの変更で動かなくなったのかを突き止めるのです。 | + | |
- | --プログラムに経験があると過信している人ほど、この作業をやりません。まっさらなところから書き始めてつまづいて、それでそのプログラムを必至に眺めて、「おかしいところはないはずなんだけどなあ」とかいいます。もしくは、まめに make run するのをいやがって、一度にたくさん改造して、それでやっぱりバグを抱えて、何も分からなくなります。 | + | |
- | --この「こまめに make run 」「おかしくなったらつべこべ言わずに動いていた段階に一度戻る」を忠実に守った人が、一番速く上達します。初心者を脱した後でさえ、この方法で救われることを僕は何度も経験しています。 | + | |
- | --そんなわけで、僕としてはこの手法に沿った人からの質問にはできるだけ答えますが、そうでない人は自己努力不足ということで、十分な回答をしない場合があります。ご了承ください(これは具体的にどういうことかというと、問題あるソースだけではなく、問題なく動いていた段階のソースの提示を求めることがある、ということです)。 | + | |
| | | |
- | * こめんと欄 | |
| #comment | | #comment |