1: 2004-12-13 (月) 17:17:20 [5] | 現: 2024-01-08 (月) 12:58:56 k-tan[6] [7] | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | * wiki版のintroシリーズ no.0001 | + | TITLE:x |
+ | * wiki版のintroシリーズ no.0001 [#z51a3904] | ||
-(by [[K]], 2004.12.13) | -(by [[K]], 2004.12.13) | ||
-これはC言語でもASKAでもnaskでもとにかくごちゃまぜでintroしてしまおうというこころみ。 | -これはC言語でもASKAでもnaskでもとにかくごちゃまぜでintroしてしまおうというこころみ。 | ||
--これは[[guide/wintro0000]]の続きなので、それを読んでない人はそれを読んでね。 | --これは[[guide/wintro0000]]の続きなので、それを読んでない人はそれを読んでね。 | ||
- | ---最初から読みたい人は[[guide/ASKA]]や[[guide/nask]]からどうぞ。 | + | ---最初から読みたい人は[[guide/C]]や[[guide/ASKA]]や[[guide/nask]]からどうぞ。 |
--C言語をやる人はintroaを読むといいでしょう。ここのプログラムは、introaと同一内容です。 | --C言語をやる人はintroaを読むといいでしょう。ここのプログラムは、introaと同一内容です。 | ||
-質問とか感想とかはこめんと欄にレッツゴー。 | -質問とか感想とかはこめんと欄にレッツゴー。 | ||
- | *** color | + | *** color [#q99770b1] |
- | -C版:"colorc1.c" [osa_dir2では 616バイト] | + | -C版:"colorc1.c" [tolset08では 546バイト] |
+ | //-C版:"colorc1.c" [osa_dir2では 615バイト] | ||
/* "colorc1.c":colorをC言語で記述した例 */ | /* "colorc1.c":colorをC言語で記述した例 */ | ||
- | /* stack:20k malloc:2k */ | + | /* stack:4k malloc:2k */ |
+ | |||
#include <guigui00.h> | #include <guigui00.h> | ||
#define AUTO_MALLOC 0 | #define AUTO_MALLOC 0 | ||
+ | |||
void setdec2(const int i, char *s); | void setdec2(const int i, char *s); | ||
+ | |||
void OsaskMain() | void OsaskMain() | ||
{ | { | ||
Line 23: | Line 25: | ||
int i; | int i; | ||
static char msg[] = "color 0"; | static char msg[] = "color 0"; | ||
+ | |||
/* ライブラリ初期化 */ | /* ライブラリ初期化 */ | ||
lib_init(AUTO_MALLOC); | lib_init(AUTO_MALLOC); | ||
+ | |||
/* ウィンドウのオープン */ | /* ウィンドウのオープン */ | ||
window = lib_openwindow(AUTO_MALLOC, 0x0200, 20 * 8, 8 * 16); | window = lib_openwindow(AUTO_MALLOC, 0x0200, 20 * 8, 8 * 16); | ||
Line 32: | Line 34: | ||
textbox = lib_opentextbox(0x0001, AUTO_MALLOC, 0, 20, 8, 0, 0, window, 0x00c0, 0); | textbox = lib_opentextbox(0x0001, AUTO_MALLOC, 0, 20, 8, 0, 0, window, 0x00c0, 0); | ||
lib_putstring_ASCII(0x0000, 0, 0, wintitle, 0, 0, "colorc1"); | lib_putstring_ASCII(0x0000, 0, 0, wintitle, 0, 0, "colorc1"); | ||
+ | |||
/* メインルーチン */ | /* メインルーチン */ | ||
for (i = 0; i < 16; i += 2) { | for (i = 0; i < 16; i += 2) { | ||
Line 40: | Line 42: | ||
lib_putstring_ASCII(0x0000, 10, i / 2, textbox, i + 1, 0, msg); | lib_putstring_ASCII(0x0000, 10, i / 2, textbox, i + 1, 0, msg); | ||
} | } | ||
+ | |||
/* 終了 */ | /* 終了 */ | ||
lib_waitsignal(0x0001, 0, 0); | lib_waitsignal(0x0001, 0, 0); | ||
} | } | ||
+ | |||
void setdec2(const int i, char *s) | void setdec2(const int i, char *s) | ||
/* 注意:このルーチンでは、0~99までしか扱えない */ | /* 注意:このルーチンでは、0~99までしか扱えない */ | ||
Line 54: | Line 56: | ||
return; | return; | ||
} | } | ||
- | + | ||
- | -''以下未完成'' | + | -ASKA版:"colora1.ask" [tolset08では 210バイト] |
- | + | //-ASKA版:"colora1.ask" [osa_dir2では 239バイト] | |
- | -ASKA版:"helloa4.ask" [osa_dir2では 171バイト] | + | /* "colora1.ask":colorをASKAで記述した例 */ |
- | /* "helloa4.ask":helloをASKAで記述した例 */ | + | /* stack:4k malloc:0k */ |
- | /* stack:20k malloc:0k */ | + | segment CODE(USE32, PARA); default(code == CODE); asmout("[FILE 'colora1.ask']"); |
- | segment CODE(USE32, PARA); default(code == CODE); asmout("[FILE 'helloa.ask']"); | + | |
asmout("GLOBAL _OsaskMain"); | asmout("GLOBAL _OsaskMain"); | ||
+ | |||
+ | void setdec2(); /* ALをDS:ESIに書き込む */ | ||
+ | |||
void _OsaskMain() | void _OsaskMain() | ||
{ | { | ||
- | asmout("MOV EBX,data.funcs"); CALL(0xc7, 0); | + | asmout("MOV EBX,data.init"); CALL(0xc7, 0); |
+ | |||
+ | unsigned char i == AL, x == CL, y == CH; | ||
+ | i = 0; | ||
+ | do { | ||
+ | asmout("MOV EBX,data.putstr"); | ||
+ | x = 10; | ||
+ | y = i; | ||
+ | y /= 2; | ||
+ | if (CF == 0) | ||
+ | x = 0; /* yが割り切れたらxは0に */ | ||
+ | [EBX + 8] = x; | ||
+ | [EBX + 12] = y; | ||
+ | [EBX + 20] = i; | ||
+ | LEA(ESI, [EBX + 42]); | ||
+ | setdec2(); | ||
+ | CALL(0xc7, 0); | ||
+ | i++; | ||
+ | } while (i < 16); | ||
+ | |||
+ | asmout("MOV EBX,data.sleep"); CALL(0xc7, 0); | ||
} | } | ||
+ | |||
+ | void setdec2() | ||
+ | { | ||
+ | char *s == DS:ESI; | ||
+ | PUSH(ECX); | ||
+ | PUSH(EAX); | ||
+ | CL = 10; | ||
+ | AH = 0; | ||
+ | DIV(CL); /* AX / CL = AL ... AH */ | ||
+ | EAX |= 0x3030; /* '00' */ | ||
+ | if (AL == 0x30) | ||
+ | AL = 0x20; /* ' ' */ | ||
+ | s[0] = AL; | ||
+ | s[1] = AH; | ||
+ | POP(EAX); | ||
+ | POP(ECX); | ||
+ | return; | ||
+ | } | ||
+ | |||
asmout("[SECTION .data]"); | asmout("[SECTION .data]"); | ||
+ | |||
void data() | void data() | ||
{ | { | ||
ALIGNB(4); | ALIGNB(4); | ||
- | funcs: | + | init: |
asmout("DD 0x0004, data.work"); /* lib_init */ | asmout("DD 0x0004, data.work"); /* lib_init */ | ||
- | asmout("DD 0x0020, data.window, 0x0200, 136, 48"); /* lib_openwindow */ | + | asmout("DD 0x0020, data.window, 0x0200, 20 * 8, 8 * 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, 7, 1, 0, 0, data.window, 0x00c0, 0"); /* lib_opentextbox */ | ||
- | asmout("DD 0x0028, 0x0000, data.textbox, 0, 12, 1, 16, 16, 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 0x0040, 0x1000, 0, 0, data.wintitle, 0, 0, 0, 7, 'helloa4'"); /* lib_putstring1 */ | + | asmout("DD 0x0040, 0x1000, 0, 0, data.wintitle, 0, 0, 0, 7, 'colora1'"); /* lib_putstring1 */ |
- | asmout("DD 0x0040, 0x1000, 0, 0, data.textbox, 0, 0, 0, 12, 'hello, world'"); /* lib_putstring1 */ | + | DD(0x0000); /* end of functions */ |
+ | putstr: | ||
+ | asmout("DD 0x0040, 0x1000, 0, 0, data.textbox, 0, 0, 0, 8, 'color '"); /* lib_putstring1 */ | ||
+ | DD(0x0000); /* end of functions */ | ||
+ | sleep: | ||
DD(0x0018, 0x0001, 0, 0); /* lib_waitsignal */ | DD(0x0018, 0x0001, 0, 0); /* lib_waitsignal */ | ||
DD(0x0000); /* end of functions */ | DD(0x0000); /* end of functions */ | ||
+ | |||
ALIGNB(8); | ALIGNB(8); | ||
work: | work: | ||
Line 90: | Line 135: | ||
wintitle: | wintitle: | ||
RESB(64); /* テキストボックス構造体 */ | RESB(64); /* テキストボックス構造体 */ | ||
- | RESB(64); /* 8x1文字分 (8 * 1 * 8) */ | + | RESB(56); /* 7x1文字分 (7 * 1 * 8) */ |
textbox: | textbox: | ||
RESB(64); /* テキストボックス構造体 */ | RESB(64); /* テキストボックス構造体 */ | ||
- | RESB(96); /* 12x1文字分 (12 * 1 * 8) */ | + | RESB(1280); /* 20x8文字分 (20 * 8 * 8) */ |
} | } | ||
+ | |||
- | -nask版:"hellon4.nas" [osa_dir2では 170バイト] | + | -nask版:"colorn1.nas" [tolset08では 209バイト] |
- | ; "hellon4.nas":helloをnaskで記述した例 | + | //-nask版:"colorn1.nas" [osa_dir2では 237バイト] |
- | ; stack:20k malloc:0k | + | ; "colorn1.nas":colorをnaskで記述した例 |
+ | ; stack:4k malloc:0k | ||
+ | |||
[FORMAT "WCOFF"] | [FORMAT "WCOFF"] | ||
[INSTRSET "i486p"] | [INSTRSET "i486p"] | ||
Line 105: | Line 152: | ||
[OPTION 1] | [OPTION 1] | ||
[BITS 32] | [BITS 32] | ||
- | [FILE "hellon4.nas"] | + | [FILE "colorn1.nas"] |
- | ; 新出のOPTIONについて。定数計算をデフォルトでは符号付き整数でおこなえという意味。 | + | |
- | ; 指定しないとデフォルトは符号無し整数でおこなうことになっている。 | + | |
[SECTION .text] | [SECTION .text] | ||
GLOBAL _OsaskMain | GLOBAL _OsaskMain | ||
+ | |||
_OsaskMain: | _OsaskMain: | ||
- | MOV EBX,funcs | + | MOV EBX,init |
CALL 0xc7:0 | CALL 0xc7:0 | ||
+ | MOV AL,0 | ||
+ | .mainloop: | ||
+ | MOV EBX,putstr | ||
+ | MOV CL,10 | ||
+ | MOV CH,AL | ||
+ | SHR CH,1 | ||
+ | JC .skip | ||
+ | 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 | ||
+ | INC AL | ||
+ | CMP AL,16 | ||
+ | JB .mainloop | ||
+ | MOV EBX,sleep | ||
+ | CALL 0xc7:0 | ||
+ | |||
+ | setdec2: | ||
+ | PUSH ECX | ||
+ | PUSH EAX | ||
+ | MOV CL,10 | ||
+ | MOV AH,0 | ||
+ | DIV CL | ||
+ | OR EAX,'00' | ||
+ | CMP AL,'0' | ||
+ | JNE .skip | ||
+ | MOV AL,' ' | ||
+ | .skip: | ||
+ | MOV [ESI+0],AL | ||
+ | MOV [ESI+1],AH | ||
+ | POP EAX | ||
+ | POP ECX | ||
+ | RET | ||
+ | |||
+ | ; .で始まるラベルはローカルラベル。 | ||
+ | ; ローカルラベルは、次のグローバルラベル宣言までが有効範囲。 | ||
+ | |||
[SECTION .data] | [SECTION .data] | ||
ALIGNB 4 | ALIGNB 4 | ||
- | funcs: | + | init: |
DD 0x0004, work ; lib_init | DD 0x0004, work ; lib_init | ||
- | DD 0x0020, window, 0x0200, 18 * 8, 3 * 16 ; lib_openwindow | + | DD 0x0020, window, 0x0200, 20 * 8, 8 * 16 ; lib_openwindow |
- | DD 0x0028, 0x1000, wintitle, 0, 8, 1, 0, 0, window, 0x00c0, 0 ; lib_opentextbox | + | DD 0x0028, 0x1000, wintitle, 0, 7, 1, 0, 0, window, 0x00c0, 0 ; lib_opentextbox |
- | DD 0x0028, 0x0000, textbox, 0, 12, 1, 16, 16, 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, 'hellon4' ; lib_putstring1 | + | DD 0x0040, 0x1000, 0, 0, wintitle, 0, 0, 0, 7, 'colorn1' ; lib_putstring1 |
- | DD 0x0040, 0x1000, 0, 0, textbox, 0, 0, 0, 12, 'hello, world' ; 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 0x0018, 0x0001, 0, 0 ; lib_waitsignal | ||
DD 0x0000 ; end of functions | DD 0x0000 ; end of functions | ||
+ | |||
ALIGNB 8 | ALIGNB 8 | ||
work: | work: | ||
Line 132: | Line 223: | ||
RESB 128 ; ウィンドウ構造体 | RESB 128 ; ウィンドウ構造体 | ||
wintitle: | wintitle: | ||
- | RESB 64 + 8 * 1 * 8; テキストボックス構造体(8x1文字分) | + | RESB 64 + 7 * 1 * 8; テキストボックス構造体(7x1文字分) |
textbox: | textbox: | ||
- | RESB 64 + 12 * 1 * 8; テキストボックス構造体(12x1文字分) | + | RESB 64 + 20 * 8 * 8; テキストボックス構造体(20x8文字分) |
+ | |||
- | + | *** 説明 [#n1fba734] | |
- | *** 説明 | + | |
-概要: | -概要: | ||
- | --このプログラムは、ウィンドウを一つ開き、そのウィンドウに"hello, world"と表示 | + | --このプログラムは、ウィンドウを一つ開き、そのウィンドウに16色のメッセージを表示するだけのプログラムです。 |
- | するだけのプログラムです。 | + | --このプログラムを通じて、テキストに色を付ける方法と、数字表示の方法について説明します。 |
- | --このプログラムを通じて、OSASKアプリケーションの基本的な作法を説明します。 | + | --OSASKでは、printf()やitoa()などの便利な関数がまだ用意されていません。したがって、残念なことに数字を表示するのは少し面倒です。今回はitoaの代わりにsetdec2()という関数を作ってみました。 |
- | --OSASKアプリは基本的に、「ぐいぐい00ライブラリ」と呼ばれるライブラリを通じて、 | + | --これくらいの規模の例になると、CとASKAとnaskの文法の違いが出てきますので、見比べてみるのも面白いかもしれません。どれでもいいのですので、好きな言語を活用してください。 |
- | ほとんどすべての入出力処理を行います。ですから、このライブラリの使い方をマスタ | + | |
- | ーすることが、OSASKアプリの作り方をマスターすることになります。 | + | |
- | --OSASKでは、「ウィンドウ」に「テキストボックス」を貼付け、そのテキストボックス | + | |
- | に文字を書くという手順で文字を表示します。ウィンドウに直接文字を書く方法はあり | + | |
- | ません。 | + | |
- | --また文字を書くために、C言語では標準的なprintf()などを使うことはできません。特 | + | |
- | 別な関数を使います。 | + | |
- | --なおプログラムを見ればすぐに分かっていただけると思いますが、OSASKアプリの標準 | + | |
- | 的なメインルーチンは、int main();ではなく、void OsaskMain();です。またこの関数 | + | |
- | 内でreturn;してはいけません。アプリケーションを終了するのは、APIを呼び出すこと | + | |
- | で行います。 | + | |
- | --stackとmallocについて説明します。プロジェクトを作ってMakefileを書き換えるとき、''STACKSIZE''と''MALLOCSIZE''という記述がすぐに見つかると思います。この記述をソースでの記載にそろえてください。なお、デフォルトではこのソースの値より大きいですが、実は大きい分にはあまり問題はありません。ソースでの記載よりも小さいと、誤動作の原因になります。それでも、無駄に大きいのはなんだかもったいないので、できればソースの記載にそろえることをおすすめします。 | + | |
- | --C版とASKA版を見比べると、まあまあ似ていることが分かります。ASKA版とnask版を比べるとほとんど同じです。したがって、C用の資料をASKAやnaskで活用することができますし、逆にASKA用の資料やnask用の資料をCで活用することもできます。 | + | |
- | --なお、Cでの関数呼び出しはまさにスタック渡しですが、これらは[[guide/ASKA]]や[[guide/nask]]で紹介したテクニックによって EBX = ESP; などがなされて、CALLされているにすぎません。 | + | |
- | --C版では説明の簡便のためにAUTO_MALLOCを使っていますが、これをやめれば結構小さくなります(それでもPUSH等を多用する関係で、ASKA版やnask版にはサイズでは勝てません)。 | + | |
-APIの説明: | -APIの説明: | ||
- | |||
- | --lib_init(work) : | ||
- | ---APIを利用するために、かならず最初に行わなければならない初期化です。256バイトの領域をパラメータに指定します。この領域は4バイトアラインされている必要があります。機能番号は0x0004です。 | ||
- | ---C版でlib_init関数を使う場合workに0を指定することもでき、その場合はmalloc(256)された値が自動で割り当てられます。 | ||
- | ---この初期化作業やワークエリアは何だと思うかもしれませんが、OSASKのAPIの実態は実はDLL(ダイナミックリンクライブラリ)であり、これはそのDLLの初期化とワークエリア指定のためのものです。 | ||
- | ---APIでは、指定されたワークエリアやファンクション列はすべてDSで参照できるところにあると仮定され、さらに DS == ES == SS というのを仮定しています。.text内にコマンドを置いた場合、 DS = CS にしなければならず、そうするとワークエリアがCS内にあることになり、利用できないことになります。結局コマンド列は.data内かスタックにしか置けないでしょう。 | ||
- | |||
- | --lib_openwindow(window, slot, x_size, y_size) : | ||
- | ---ウィンドウをオープンします。最初の引数windowは128バイトの領域を指定します。C版ではwindowに0を指定することもでき、その場合はmalloc(128)された値が自動で割り当てられ、関数値として返されます。機能番号は0x0020です。 | ||
- | ---x_sizeとy_sizeはウィンドウの大きさをドット単位で指定します。ここで指定されたサイズにはウィンドウタイトルのためのドット数は含まれません。slotは、0x200にしておいてください。 | ||
- | ---一つのタスクが複数のウィンドウを持つことが許されています。その場合、2つめの | ||
- | ウィンドウのslotは0x210、3つめは0x220という風に数を増やしてやってください。また、デフォルトではこれらのウィンドウのうち一つが閉じられると、残りのウィンドウ | ||
- | も全て自動的に閉じられてタスクは終了させられます。このデフォルトを変更することはもちろんできますが、それは入門では難しすぎるのでここでは触れません。 | ||
--lib_opentextbox(opt, textbox, backcolor, x_size, y_size, x_pos, y_pos, window, charset, init_char) : | --lib_opentextbox(opt, textbox, backcolor, x_size, y_size, x_pos, y_pos, window, charset, init_char) : | ||
- | ---ウィンドウにテキストボックスを貼ります。機能番号は0x0028です。optにどんな値を指定するかでこの関数の意味は変わります。引数textboxは64バイト以上の領域で、必要ないサイズは、(64 + x_size * y_size * 8)バイトです。C版ではこれを0にできてその場合は自動でmallocされるなどは、lib_openwindowとおなじです。 | + | ---ウィンドウにテキストボックスを貼ります。optの値は、0と0x1000しか紹介していませんでしたが、実は1も使えます。optに1を指定すると、テキストボックスに外枠が付きます。また、背景色が選べるようになり、それはbackcolorで指定します。それ以外はoptに0を指定した場合と全く同様です。なお、この枠がウィンドウをはみ出たり他の表示と重なったりしないようにしてください。 |
- | ---opt == 0x1000 のとき | + | |
- | ---ウィンドウタイトル専用のテキストボックスを作ります(''ウィンドウタイトルはウィンドウ一つに対して一つ必要''で、省略することは許されません)。backcolorとx_posとy_posとinit_charは必ず0にしてください。windowはどのウインドウのタイトルであるかを指定するためのもので、lib_openwindow()で指定した値を使います。y_sizeは必ず1です。それで、x_sizeにはこのテキストボックスの文字数を入れます。 | + | |
- | ---ここで一つルールがあり、x_sizeは(ウィンドウのx_size / 8 - 10)以下の値にしなければいけません。長いウィンドウタイトルを付けたければ、この条件が満たされるようにウィンドウサイズを大きくしておく必要があります。 | + | |
- | ---この関係式はもっと分かりやすくかけます。以下の不等式が成立するようにサイズを | + | |
- | 決定してください。 | + | |
- | タイトルのx_size * 8 + 80 <= ウィンドウのx_size | + | |
- | ---opt == 0 のとき | + | |
- | ---一般のテキストボックスを作ります。とりあえずbackcolorとinit_charは0で、charsetは0xc0です(この値の意味や変更方法などはもっと先で紹介します)。x_sizeとy_sizeはテキストボックスの大きさです。単位はキャラクター単位で、1キャラクターは、横8ドット、縦16ドットです。x_posとy_posはウィンドウのどこにテキストボックスを貼り付けるかという指示です。テキストボックスの左上の座標をウィンドウ内座標で示します。単位はドット単位です。ただしx_posは8の倍数を指定しなければいけません(これは将来のOSA | + | |
- | SKでは解消される制限です)。y_posにはそういう制限はありません。windowでどのウィンドウにそのテキストボックスを貼り付けるかを指定します。やはり、lib_openwindow()で指定した値を使います。当然ですが、テキストボックスがウィンドウからはみ出さないようにしてください。テキストボックスは1つのウィンドウにいくつでも付けられますが、テキストボックスが重なることは許されません。座標やサイズに注意してください。 | + | |
--lib_putstring_ASCII(opt, x_pos, y_pos, textbox, color, backcolor, str) : | --lib_putstring_ASCII(opt, x_pos, y_pos, textbox, color, backcolor, str) : | ||
- | ---テキストボックスに文字を出力します。optとbackcolorは0にしてください。x_posとy_posはテキストボックス内での文字の表示位置を指定します。キャラクター単位です。左上が(0, 0)です。colorで表示色を制御できます(0~15)。textboxで対象となるテキストボックスを指定しますが、これはlib_opentextbox()で指定したものです。 | + | ---colorc1.cでは使われていませんが、optに1を指定することにより、この関数でもbackcolorが有効になります。これは文字の背景色を文字単位で指定するものです。ちなみにスペースを表示した場合、backcolorで指定した色の四角形が表示されます。 |
- | ---strは表示したい文字列です。この関数は'\n'や'\t'を認識しません。したがって、複数行に渡って出力したい場合は、lib_putstring_ASCII()をその行数分だけ呼び出すことになります。また、textboxをはみ出すような長いstrを指定したりしてはいけません。 | + | ---ASKA/naskのlib_putstring1も全く同様で、optの最下位ビットを1にすると、backcolorに0以外を指定できるようになります。 |
- | ---なお、textboxがウィンドウタイトル専用のテキストボックスの場合、x_posとy_posとcolorは必ず0にしてください。テキストボックスの同じ位置に何度も文字を重ね書きするのは許されます。その場合、文字が重なっていくのではなく最後に書かれた文字だけが表示されることになります(たとえば、既に表示されているところへスペースを表示すれば、文字は消える)。 | + | |
- | ---Cのlib_putstring_ASCIIは直接APIを呼ばずに、バンドルのライブラリ関数を呼んでいます。これは自動で文字数などを数えさせるためです。ASKAやnaskではこれを使わずに、lib_putstring1というファンクションを直接呼んでいます(機能番号0x0040)。パラメータは次のとおりです。 | + | |
- | ---lib_putstring1(opt, x_pos, y_pos, textbox, color, backcolor, 0, len, str) | + | |
- | ---optは0x1000を指定します。これは即値モード、8bitキャラクタ、という意味です。即値モードではたとえ8bitキャラクタモードであってもstrは4バイト単位で書かれる必要があるので、DBではなくDDで書いてください(つまり末尾を4バイトアラインさせる必要がある、という意味)。 | + | |
- | --lib_waitsignal(opt, signaldw, nest) : | + | *** まとめ [#qffc9ebe] |
- | ---optを1にすれば、タスクはスリープし、事実上終了します。残り2つの引数は0にして | + | -これで、テキストボックスを使った表示は一通りできるようになったはずです。許される範囲であちこちを改造して、把握してください。この程度のことなら、決して難しくないと感じていただけるはずです。 |
- | ください。機能番号は0x0018です。 | + | -なお、C版でテキストボックスを広げる際には、malloc領域が不足する可能性があるので、malloc:オプションの値を大きくしてやってください。ASKA/naskでは、テキストボックス構造体のサイズを間違えなければ、mallocは0kのままでかまいません。 |
- | *** まとめ | + | *** おまけ [#w6e221c1] |
- | -これで好きな大きさのウィンドウを開き、ウィンドウにテキストボックスを貼り付けて、好きな色で文字をかけるようになったはずです。まだキー入力もタイマー制御もできないので、凝ったことはできませんが。 | + | -次回(no.0002)は時間制御関係を少しやります。これで、変化のあるテキスト表示ができるようになるでしょう。 |
- | -プログラムの終了のさせ方も分かったはずです。「面倒だから無限ループ」なんてしないで、ちゃんとlib_waitsignalしてください(見た目は同じようなものですが、負荷が大きく違いますから)。 | + | -続編はこちら → [[guide/wintro0002]] |
+ | ~ | ||
+ | ~ | ||
+ | -''実際の開発をするにあたって'' | ||
+ | --このwintroシリーズを読んでいる人は、introシリーズを読んでいない可能性もあるので、大事な注意を書いておきます。 | ||
+ | --初心者がよくやることの一つに、プログラムをゼロから作り始めようとして失敗する、というのがあります。これは、いきなりプロジェクトを作って、まっさらなテキストファイルからプログラムを書いていく、ということを意味します。これはたいていうまくいきません。これはOSASKアプリ開発に限らず、他のOSのアプリ開発を最初にやろうとしたときもでも同じことです。 | ||
+ | --うまい方法は、まず、適当なサンプルアプリを見つけてきて(helloでもいいです)、それをコピーしたところから出発することです。これを少し改造し(たとえばウィンドウサイズとウィンドウタイトルを望みの大きさに変えて)、改造したらすぐに make run してみます。それでうまく動いたらバンザイです。さらに少し改造を加えて、自分の目的のアプリに近づけていきます。・・・もし make run してうまく動かなければ、どこが悪いのかをウンウンうなったりするのではなく、まずは動いていた段階に帰ります。そして少しずつ改造を戻していくことによって、どの変更で動かなくなったのかを突き止めるのです。 | ||
+ | --プログラムに経験があると過信している人ほど、この作業をやりません。まっさらなところから書き始めてつまづいて、それでそのプログラムを必至に眺めて、「おかしいところはないはずなんだけどなあ」とかいいます。もしくは、まめに make run するのをいやがって、一度にたくさん改造して、それでやっぱりバグを抱えて、何も分からなくなります。 | ||
+ | --この「こまめに make run 」「おかしくなったらつべこべ言わずに動いていた段階に一度戻る」を忠実に守った人が、一番速く上達します。初心者を脱した後でさえ、この方法で救われることを僕は何度も経験しています。 | ||
+ | --そんなわけで、僕としてはこの手法に沿った人からの質問にはできるだけ答えますが、そうでない人は自己努力不足ということで、十分な回答をしない場合があります。ご了承ください(これは具体的にどういうことかというと、問題あるソースだけではなく、問題なく動いていた段階のソースの提示を求めることがある、ということです)。 | ||
- | *** おまけ | + | * こめんと欄 [#s8db1e95] |
- | -ここまではどれもただ芸もなく固定的なパラメータでAPIを呼び出しているだけですが、次(no.0001)からはパラメータに変数を使ったり、サブルーチンを作ったりします。 | + | -tolset08にあわせて修正。 -- [[K]] SIZE(10){2005-01-29 (土) 15:34:36} |
- | * こめんと欄 | + | //#comment |
- | #comment | + |
(This host) = http://osask.net