ザビタン開発日記
2009 | 01
2008 | 01 | 02 | 06 | 12
2007 | 10 | 11 | 12
10月 15 (月曜日) 2007
23:17
背景でけたー!
 



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



さーーーて!!

いよいよウィンドゥへのカスタムと行きますか!!
 
30日を過ぎたBlogにはコメントできません。
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側からこんなふうに呼び出すことで、最初の計算式と
同じ効果を出せましたぁ!! (^^
 
30日を過ぎたBlogにはコメントできません。

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型変数を渡せないと思います。

30日を過ぎたBlogにはコメントできません。
(1) 

PopnupBlog V3 Denali created by Bluemoon inc.