ザビタン開発日記
2009 | 01
2008 | 01 | 02 | 06 | 12
2007 | 10 | 11 | 12
10月 17 (水曜日) 2007
17:09
時計搭載に挑戦
 
さーて。あんまし見た目だけやっててもアレなんで(まだやりたいのや山々でつが・・・(汗 )



ダミーで置いてある時計。これを本当に動かすことってできないもんかなぁと・・・



ここいら辺に参考文献が!??



さっそくカンニング参考にしながらイジってみよう・・・



おぉ! ちゃんと現在時刻をゲットできたぞ!??(^^



・・・さてここで考察。



CMOSによって、とりあえず現在の時刻を得ることができた。あとは

タイマーを使って1秒ごとに割り込みをかけ、数値を

足して行けばいい・・・・。そんなんでいいのかな???



えーっと。タイマーはどうしよう? それ用に作るかな?それとも??



いろいろ考えてみたけど、マルチタスクの時、別の窓開いてカウントとかやってたよね。

ああいうのをやって実験してみよう!!



えーっと。今はウィンドゥを出すにはどうしてるんだっけ。



  1. ウィンドゥを出すAPIを呼び出す



・・・あ”これだけだったっけ・・・



・・・その後、かなりガチョーーンなことに気が付いた。

bootpac.cからはAPI使えないのね・・・

 
name: @Guest  Comment:
16:54
THE-BBL OS リリース!
 
そんなわけで、リリースの第一弾つーかね。

Ver.0.00ということでどうかひとつ・・・・(汗



(以前にも一回おんなじような感じでリリースしたんですが、あれは忘れてください・・・)



Makefileをちょこっと直して、ウチの子の画像を挟み込みました




リビジョン10相当っすね。
 
name: @Guest  Comment:
14:18
コンソールの各パラメータを定数化
 
console.c内の各関数。ここでは初期値(文字数30x8)が決め打ちされている。

これらをとりあえず全て定数化してみる。



#define CONS_CHAR_X 80;

#define CONS_CHAR_Y 24;



こんなのをconsole.cの先頭に追加。

各関数内の数値を変更してみる。





おっと??

なんかいけたっぽいぞ??

euc.txtに文字を沢山書き込んでテスト・・・



おぉ! いいじゃんいいじゃん!!!




リビジョン9


 
name: @Guest  Comment:
09:39
コンソールの位置と大きさ
 
ニセタスクバーを上にもっていっちゃったせいで、最初に表示される

コンソールとかぶってしまうようになりました。

また、当分は800x600でやっていきますが、それだとちょっとこの

コンソールでは狭すぎですよね?80x24くらいにしたいなぁ・・・



そんなわけでさっそく改造!

まずはコンソールの表示位置ね。

えーっと。これはどこでやってたっけかな・・・。



あったあった。bootpac.c内で key_win = open_console(shtctl, memtotal); として呼んでいる。これが最初のコンソール。



そのすぐ下のあたり。ここで、マウスや初期コンソールなどのシートの位置を

sheet_slideなどで調整しているね。



sheet_slide(key_win, 32, 4);



これを書き換えれば最初の位置が変更できる。



sheet_slide(key_win, 32, 32);



とりあえずこんなもんでいいかな。



次にコンソールの大きさ。これはどこでやってるのかな。

???あれれれ?

open_console関数内で決めうちしてるのかな?これ??



sheet_setbuf(sht, buf, 256, 165, -1); /* 透明色なし */



とりあえずこの辺の数字をいろいろといじってみる・・・



ふむ・・・・単にここいらへんの数字を変えただけではいろいろとズレが

生じちゃうよね?ここは一発、open_console関数の復習と逆説で考えてみよう。



まず、オイラの目的は80x24のコンソールがほしいわけ。

そうなると単にウィンドゥの大きさだけじゃない。その大きさの

テキストボックスが収まる窓が必要。これを逆に計算してみると・・・



標準状態:30x8文字で240x128(文字が8x16だからね)

欲しい状態:80x24文字だから640x384。



さらにウィンドゥの部品が覆うので高さが+37、幅が+16となるから

ウィンドゥの大きさは656x421とこうなるわけね。

open_console内の各数字をこれに合わせてみる・・・





             :

unsigned char *buf = (unsigned char *) memman_alloc_4k(memman, 656 * 421);

sheet_setbuf(sht, buf, 656, 421, -1); /* 透明色なし */

make_window8(buf, 656, 421, "console", 0);

make_textbox8(sht, 8, 28, 640, 384, COL8_000000);

sht->task = open_constask(sht, memtotal);

             :





・・・・おぉぉ! ひろーーいコンソールが!できたーーー!



ダメじゃん!!!!!!!





これ、わかります? 

ウィンドゥは広くなってるけど、コンソール部分は前と同じ大きさ

のままなんですよ〜?(T T)

これじゃまるで、旅館の大広間で3人だけ朝食喰ってる状態じゃないですか!!



えーーーっと、この辺の制御はどこだったかな・・・



むむむーーーーー!!!!



これはconsole.c内。でも、幅や高さをみな決め打ちで行ってますねぇ・・・



こりゃ大幅な改造・・・いや! むしろ引数、いやさ、せめて定数かなんかに改造しておかないと大変だぞおぉぉ!!!(汗



リビジョン8
 
name: @Guest  Comment:
Referer  (9)
00:11
パターン関数。怪我の功名!??
 
画面の四隅。oldMacではどこも角をまるくしている。

BBLも上の上下はそうしてる。例のパターン関数でね。

・・・でも、問題発生。下のほうだと、こうなっちゃう・・・



これはわかるよね?。背景パターンの上に白を新たに塗ってしまった上体なんだよなぁ。

今パターン関数は二色対応だけど、透明色か三色対応しなくてはならんかなぁ・・・



と思っていたら!!



現在のパターン関数は * しか判断していない。

ってことは、 . も判断させて、それ以外の文字(たとえばスペースとか)を放置するようにしたら・・・



おぉぉ! 透明色(と言えば聞こえはいいが、ようはなんもしない部分)ができた!

これで下の四隅もOKだぞ!??









●リージョン7
 
name: @Guest  Comment:
10月 16 (火曜日) 2007
04:06
微調整
 
大体ウィンドゥは出来上がったけど、ちょっと問題が。



ウィンドゥをアクティブ・非アクティブに切り替えた時。



えーっと。非アクティブの時タイトルバーを塗り潰してるところってどこだっけ・・・



あったあった。change_wtitle8。



さっそく改造・・・



でけたでけた〜♪



 
name: @Guest  Comment:
00:41
ウィンドゥの描画はどこ?
 
えとえと。ウィンドゥを作成している場所はというと・・・





  1. ウィンドゥを出すためのAPIがある。api_openwin。

  2. これが呼び出されると、a_nask.nas内の_api_openwinがコールされる。

  3. 内部で機能番号5としての割り込み(0x40)を発生させる。

  4. console.c内に実際の動作が書かれている。

  5. ・・・sheet_allocで下じきを一枚もらって・・・

  6. ・・・sheet_setbufで新しい下じきの大きさ等を設定。

  7. ・・・make_window8で実際のウィンドゥ画面を書く



こういう道筋だったよね。

えーっと。make_window8はと・・・あったあった! window.c内だ!!



おっと!?? この中ではboxfill8を呼び出してるね。ってことは、

例のオイラのptboxfill関数でいろいろいけるね〜♪。早速配置!



むむむむ!??

あ〜。タイトルバーは別関数かぁ。ええと・・・

すぐ下のmake_wtitle8だね。先にこっちを改造。
 
name: @Guest  Comment:
Referer  (2)
10月 15 (月曜日) 2007
23:17
背景でけたー!
 






パターン関数が思いのほか便利なので、こんなんなりました〜。







さーーーて!!



いよいよウィンドゥへのカスタムと行きますか!!
 
name: @Guest  Comment:
13:52
パターン埋め関数できたかな?
 
うーん。これでいいかな???





void ptboxfill8(char *vram, int vgax, int startX, int startY,int xsize,

int ysize, char *ptn, int ptnY, int ptnX,int forcolor,int backcolor){



/*引数一覧

   --*vram vramのアドレス

--vgax 現在の画面モードのx方向のサイズ

--startX 塗り潰し開始点のx座標

--startY 塗り潰し開始点のy座標

--xsize 塗り潰す範囲のx方向の大きさ

--ysize 塗り潰す範囲のy方向の大きさ

--*ptn 塗り潰しパターンの配列変数



--ptnY パターン配列のy方向(縦方向)の大きさ

--ptnX パターン配列のx方向(横方向)の大きさ

  ここが逆転しているのは配列宣言と同じ

          置き方になるようにするため



--forcolor パターンで*だった場合にこの色を置く

--backcolor パターンで*以外だった場合にこの色を置く

*/

int y2,x2;

int ptnX2,ptnY2;

ptnX2=0;ptnY2=0;



for(y2=startY; y2 <= ysize; y2++){

if (ptnY2 > ptnY-1){ptnY2=0;}



for(x2=startX; x2 < xsize-1; x2++){

if (ptnX2 > ptnX-1){ptnX2=0;}



if(ptn[ptnY2*ptnX+ptnX2] == '*'){

vram[y2*vgax+x2]=forcolor;

}

else {

vram[y2*vgax+x2]=backcolor;

}



ptnX2++;

}

ptnX2=0;

ptnY2++;

}



return;

}









で、呼び出しはこんなことしてみたり・・・



static char ptn[8][8] = {

"********",

"**.....*",

"*.*....*",

"*..*...*",

"*...*..*",

"*....*.*",

"*.....**",

"********"

};

char sas[40];

sprintf(sas,"ptn= %05x",ptn);

putfonts8_asc(vram,800,64,8,COL8_000000,sas);



ptboxfill8(vram,x,0,20,x,y-30,ptn,8,8,COL8_000000,COL8_FFFFFF);













おぉぉ! でけたーーーー!!!!



━━━━━━(゜∀゜)━━━━━━



そんなわけで!!!!





char ptn[6][9] = {

"*..*..*..",

".........",

".........",

"..*..*..*",

".........",

"........."

};

ptboxfill8(vram,x,0,0,x,y-29,ptn,6,9,COL8_000000,COL8_FFFFFF);







init_screen側からこんなふうに呼び出すことで、最初の計算式と

同じ効果を出せましたぁ!! (^^

 
name: @Guest  Comment:
Referer  (4)
09:34
多次元配列の受け渡し
 
うわー! わかった〜!!!

なまじポインタを理解したつもりになってたのでよけいややこしいく

考えちゃって迷宮めぐりになってしまった!! orz



えっと。まず、配列を関数で渡す定番の方法。



void testkansuu(int a, int b, char hairetu[]){

printf(hairetu[4]);

}



void main(){

char a[9];

a[4] = 'A';



testkansuu(1,2, a);

}



この例ではわかるよね?。配列としてaを丸ごと渡している。これで

受け手である関数testkansuuは配列aを受け取れる。

あとはtestkansuu内で普通に配列として取り出せるわけ。



で、これどういうことかって言うと、



実は hairetu[] は *hairetu と同じ意味になる。

つまり、ポインタによって、配列変数aが格納されているアドレスが

やり取りされているわけ。



そこで気をよくして、多次元配列を送ってみた。





void testkansuu(int a, int b, char hairetu[][]){

printf(hairetu[4][3]);

}



void main(){

char a[9][9];

a[4][3] = 'A';



testkansuu(1,2, a);

}





エラーになっちゃうんだよねぇ・・・

いろいろとこね回したり検索してみると、こういうことすればOKだということが解った。





void testkansuu(int a, int b, char hairetu[][9]){

printf(hairetu[4][3]);

}



void main(){

char a[9][9];

a[4][3] = 'A';



testkansuu(1,2, a);

}





わかる? testkansuuでの引数の定義のところで、配列の後ろのほうの値をあらかじめ設定しておけばコンパイルできるようになる。



・・・でもさぁ。これじゃ、呼び出すMain側からは、a[][]を自由に

設定できないよね。a[2][2]にしたい時もあるかもしれない。

そんな時、いちいち関数の定義を書き換えるってのは・・・。

面倒なだけじゃなくて、バグやミスのいい温床になっちゃうよね?



そこで考え方を変えてみることにした。



そもそも多次元配列なんて存在しないのだ!!



たとえば



  char a[10];

char b[2][5];

int i,j,s;

s=0;



for(i = 0; i <=12; i++){

a[i] = i;

}



for(i = 0; i <= 3; i++){

for(j = 0; j <= 4; j++){

s=s++;

b[i][j]=s;

}

}



こうしたとしよう。仮に変数aが0x100から格納され、変数bは0x200から格納されたと仮定すると・・・





変数a 変数b

┌───┬───┐   ┌───┬───┐

│番地 │ 値 │   │番地 │ 値 │   

├───┼───┤   ├───┼───┤

│0x100 │ 1  │   │0x200 │ 1  │ ← [0][0]  

├───┼───┤   ├───┼───┤

│0x101 │ 2  │   │0x201 │ 2  │ ← [0][1]    

├───┼───┤   ├───┼───┤  

│0x102 │ 3  │   │0x202 │ 3  │ ← [0][2]    

├───┼───┤   ├───┼───┤

│0x103 │ 4  │   │0x203 │ 4  │ ← [0][3]    

├───┼───┤   ├───┼───┤

│0x104 │ 5  │   │0x204 │ 5  │ ← [0][4]   

├───┼───┤   ├───┼───┤

│0x105 │ 6  │   │0x205 │ 6  │ ← [1][0]    

├───┼───┤   ├───┼───┤

│0x106 │ 7  │   │0x206 │ 7  │ ← [1][1]    

├───┼───┤   ├───┼───┤

│0x107 │ 8  │   │0x207 │ 8  │ ← [1][2]   

├───┼───┤   ├───┼───┤

│0x108 │ 9  │   │0x208 │ 9  │ ← [1][3]    

├───┼───┤   ├───┼───┤

│0x109 │ 10  │   │0x209 │ 10  │ ← [1][4]    

└───┴───┘   └───┴───┘



このように、メモリ内部への格納にはなんの差もないのだ!!



だったら、渡された先であるtestkansuu内部では単なる普通の配列

(多次元ではない)と考え、要素数を自前で計算させちゃったって

同じ値が取り出せるんじゃない?。要素の数を引数ででも渡しちゃえばいいんじゃない??



そんなわけで、呼び出し先であるtestkansuuの内部で、a[4][3]を

取り出したいとすると、これでOKとなるよね?



void testkansuu(int a, int b, char *hairetu){



  // a[4][3]を得たい場合は・・・

printf(hairetu[4*3]);



}



void main(){

char a[9][9];

a[4][3] = 'A';



testkansuu(9,9, a); ←要素の数を引数で渡してあげる

}





これで結果は同じことになり、当然コンパイラはエラーを吐かない。

わーーーい!!! ばんざーーい!



・・・あ”

スマソ要素数を渡してあげる必然性ないよねこの例では・・・(^^;

tesukansuu内で連続して取り出したいとかそういう場合の話ね。
 
●uchan@Guest -- 10/17 07:28
僕も引っかかった問題なので、面白いです。ところで、printf(hairetu[4]);ですが、printfはchar型変数を渡せないと思います。

name: @Guest  Comment:
1 2 3 4 5 (6) 7 » 

PopnupBlog V3 Denali created by Bluemoon inc.