サイトトップへ
OSASK.NET
  サイトトップへ       新掲示板(閉鎖済)   Wiki(凍結済)   旧掲示板(廃止済)   ニュース(廃止済)  
2: 2004-01-23 (金) 00:15:46 ソース 現: 2024-01-08 (月) 12:59:00 ゲスト ソース
Line 1: Line 1:
[[introx]] [[introx]]
 + 
           "mt_xor1.c"の解説            "mt_xor1.c"の解説
                                                                 2004/01/22                                                                  2004/01/22
-                                      ベイサイド(bayside_yokohama@yahoo.co.jp) +                                                                  ベイサイド 
 + 
   このドキュメントは、"mt_xor1.c"の説明だけをするものです。最初に読むべきドキュ    このドキュメントは、"mt_xor1.c"の説明だけをするものです。最初に読むべきドキュ
 メントではありません。最初に読むべきドキュメントは"document.txt"です。"mt_xor0  メントではありません。最初に読むべきドキュメントは"document.txt"です。"mt_xor0
 .c"との違いは32ビットグラフィックボックスを使うことです。  .c"との違いは32ビットグラフィックボックスを使うことです。
- +  
 + 
 1.アルゴリズム  1.アルゴリズム
 + 
   今まで説明してきた描画方法は点を打つとか線を引くというものでした。しかし実際    今まで説明してきた描画方法は点を打つとか線を引くというものでした。しかし実際
 のプログラムでは、もっと込み入ったことがやりたいというのはよくあることです。そ  のプログラムでは、もっと込み入ったことがやりたいというのはよくあることです。そ
 の場合、あたかもビデオメモリにアクセスするように自由に読み書きできれば、なにか  の場合、あたかもビデオメモリにアクセスするように自由に読み書きできれば、なにか
 と便利でしょう。・・・ここでは、そういうアクセス方法を説明します。  と便利でしょう。・・・ここでは、そういうアクセス方法を説明します。
 + 
   このアクセス方法は2つの手順で構成されます。まず、指定されたバッファ内に自由に    このアクセス方法は2つの手順で構成されます。まず、指定されたバッファ内に自由に
 読み書きします。このバッファはグラフィックボックスに対応しており、4バイトが1ド  読み書きします。このバッファはグラフィックボックスに対応しており、4バイトが1ド
Line 26: Line 26:
 できません。いじったら必ずflushしてください(リードアクセスしかしていないときは  できません。いじったら必ずflushしてください(リードアクセスしかしていないときは
 flushしなくてもよい)。  flushしなくてもよい)。
 + 
   グラフィックボックスのバッファ構造は、(int *) gbox + 16から後ろのxsize * ysi    グラフィックボックスのバッファ構造は、(int *) gbox + 16から後ろのxsize * ysi
 ze * 4がそっくりそのままバッファになっています。単純明快です。詳しいことはソー  ze * 4がそっくりそのままバッファになっています。単純明快です。詳しいことはソー
 スをご覧ください。  スをご覧ください。
 + 
   このプログラムはその方法でたくさんの点を描画して、ちょっとした「山」を描きま    このプログラムはその方法でたくさんの点を描画して、ちょっとした「山」を描きま
 す。  す。
- +  
 + 
 2.ライブラリ関数の説明  2.ライブラリ関数の説明
 + 
   引数の型については、guigui00.hを参照してください。    引数の型については、guigui00.hを参照してください。
 + 
   lib_flushgraphbox(opt, win, x, y, sx, sy, skip, p) :    lib_flushgraphbox(opt, win, x, y, sx, sy, skip, p) :
 + 
   グラフィックボックスをflushします。optは0x8024にしてください。winはグラフィッ    グラフィックボックスをflushします。optは0x8024にしてください。winはグラフィッ
 クボックスが所属するウィンドウです。残りのパラメーターが少々ややこしいです。ま  クボックスが所属するウィンドウです。残りのパラメーターが少々ややこしいです。ま
 ずグラフィックボックス全体をflushするなら、  ずグラフィックボックス全体をflushするなら、
 + 
     x, y  : グラフィックボックスオープン時に指定したx_pos, y_posの値      x, y  : グラフィックボックスオープン時に指定したx_pos, y_posの値
     sx, sy : グラフィックボックスオープン時に指定したx_size, y_sizeの値      sx, sy : グラフィックボックスオープン時に指定したx_size, y_sizeの値
     skip  : 必ず0      skip  : 必ず0
     p      : (int *) gbox + 16      p      : (int *) gbox + 16
 + 
 という風に指定します。しかしいじった範囲がグラフィックボックスのごく一部である  という風に指定します。しかしいじった範囲がグラフィックボックスのごく一部である
 という場合もよくあるでしょう。そんなときこのような全範囲flushをすると処理時間に  という場合もよくあるでしょう。そんなときこのような全範囲flushをすると処理時間に
 おいてかなりの無駄になります。そんな時は部分flushを使います。  おいてかなりの無駄になります。そんな時は部分flushを使います。
 + 
     x, y  : 部分flushしたい範囲の左上の座標(window内の座標系で指定・・・gboxの      x, y  : 部分flushしたい範囲の左上の座標(window内の座標系で指定・・・gboxの
             座標ではない)              座標ではない)
Line 59: Line 59:
     skip  : (グラフィックボックスオープン時に指定したx_size - この時のsx) * 4      skip  : (グラフィックボックスオープン時に指定したx_size - この時のsx) * 4
     p      : x, yで指定した座標に相当するドットを指し示すintポインタ      p      : x, yで指定した座標に相当するドットを指し示すintポインタ
 + 
 これをよくご覧になれば分かるように、結局は全範囲flushも部分flushも同じルールで  これをよくご覧になれば分かるように、結局は全範囲flushも部分flushも同じルールで
 す。  す。
 + 
   もしたとえば画面内でキャラクターが走っているとすれば、まずはバッファにアクセ    もしたとえば画面内でキャラクターが走っているとすれば、まずはバッファにアクセ
 スして、元いた場所を背景に戻して移動先にキャラクターを書き込むでしょう。そして  スして、元いた場所を背景に戻して移動先にキャラクターを書き込むでしょう。そして
Line 70: Line 70:
 。できるだけ狭い範囲に分解してやりましょう。・・・この時以下の2つの方法のどちら  。できるだけ狭い範囲に分解してやりましょう。・・・この時以下の2つの方法のどちら
 がいいかと迷われるかもしれません。  がいいかと迷われるかもしれません。
 + 
     1.移動元書き換え → 移動元flush → 移動先書き換え → 移動先flush      1.移動元書き換え → 移動元flush → 移動先書き換え → 移動先flush
     2.移動元書き換え → 移動先書き換え → 移動元flush → 移動先flush      2.移動元書き換え → 移動先書き換え → 移動元flush → 移動先flush
 + 
 もちろんどちらの手順でも問題なく実行できますが、どちらかといえば2.の方がおす  もちろんどちらの手順でも問題なく実行できますが、どちらかといえば2.の方がおす
 すめです。というのは、結局画面に反映されるのはflushの時なので、2.の方法の方が  すめです。というのは、結局画面に反映されるのはflushの時なので、2.の方法の方が
Line 79: Line 79:
 ターが介在しているのなら、まずはバッファ内の書き換えを集中させ、その後にflushを  ターが介在しているのなら、まずはバッファ内の書き換えを集中させ、その後にflushを
 集中的にやる方が良いでしょう。  集中的にやる方が良いでしょう。
 + 
 3.改造への指針  3.改造への指針
 + 
   このバッファへのアクセスとflushを使えば、かなり自由にグラフィック処理ができる    このバッファへのアクセスとflushを使えば、かなり自由にグラフィック処理ができる
 はずです。しかしflushの際にはVRAMへアクセスすることになり、これは結構重たい処理  はずです。しかしflushの際にはVRAMへアクセスすることになり、これは結構重たい処理
Line 92: Line 92:
 //  stack:4k malloc:6k  //  stack:4k malloc:6k
 //  copyright(C) 2004 ベイサイド  //  copyright(C) 2004 ベイサイド
 + 
 #include <guigui00.h>  #include <guigui00.h>
 + 
 #define  AUTO_MALLOC  0  #define  AUTO_MALLOC  0
 + 
 /* ちょっとしたマクロ */  /* ちょっとしたマクロ */
 #define  pixel(x, y)  *(p + (y) * 100 + (x))  #define  pixel(x, y)  *(p + (y) * 100 + (x))
 + 
 /* 基本的なアルゴリズム */  /* 基本的なアルゴリズム */
 /* 1.グラフィックボックスをオープンする */  /* 1.グラフィックボックスをオープンする */
Line 105: Line 105:
   そこを好きなようにいじる(リードしてもライトしてもいい) */    そこを好きなようにいじる(リードしてもライトしてもいい) */
 /* 3.いじり終ったら、バッファをflushしなければいけない。この時点で画面に反映される */  /* 3.いじり終ったら、バッファをflushしなければいけない。この時点で画面に反映される */
 + 
 void OsaskMain()  void OsaskMain()
 {  {
Line 113: Line 113:
   int i, j;    int i, j;
   int *p;    int *p;
 + 
   lib_init(AUTO_MALLOC);    lib_init(AUTO_MALLOC);
   window = lib_openwindow(AUTO_MALLOC, 0x0200, 136, 48);    window = lib_openwindow(AUTO_MALLOC, 0x0200, 136, 48);
   wintitle = lib_opentextbox(0x1000, AUTO_MALLOC, 0,  7, 1,  0,  0, window, 0x00c0, 0);    wintitle = lib_opentextbox(0x1000, AUTO_MALLOC, 0,  7, 1,  0,  0, window, 0x00c0, 0);
   lib_putstring_ASCII(0x0000, 0, 0, wintitle, 0, 0, "Mt.Xor0");    lib_putstring_ASCII(0x0000, 0, 0, wintitle, 0, 0, "Mt.Xor0");
 + 
   /* グラフィックボックスをウィンドウに用意する */    /* グラフィックボックスをウィンドウに用意する */
   graphicbox = lib_opengraphbox(1, AUTO_MALLOC, 4, 8, 100, 48, 18, 0, window);    graphicbox = lib_opengraphbox(1, AUTO_MALLOC, 4, 8, 100, 48, 18, 0, window);
Line 130: Line 130:
     y_pos    : グラフィックボックスの位置(ドット単位)      y_pos    : グラフィックボックスの位置(ドット単位)
   */    */
 + 
   p = (int *) graphicbox + 16;    p = (int *) graphicbox + 16;
 + 
   /* 頂点に一つ点を打つ */    /* 頂点に一つ点を打つ */
   pixel(49, 0) = 0; /* 黒い点 */    pixel(49, 0) = 0; /* 黒い点 */
 + 
   /* ちょっとした演算 */    /* ちょっとした演算 */
   for (j = 0; j < 47; j++) {    for (j = 0; j < 47; j++) {
Line 141: Line 141:
       pixel(i, j + 1) = ((pixel(i - 1, j) == 0) ^ (pixel(i + 1, j) == 0)) ? 0 : 0xC6C6C6;        pixel(i, j + 1) = ((pixel(i - 1, j) == 0) ^ (pixel(i + 1, j) == 0)) ? 0 : 0xC6C6C6;
   }    }
 + 
   j = 0;    j = 0;
   for (;;) {    for (;;) {
 + 
     /* バッファの内容を確実に画面に反映させる */      /* バッファの内容を確実に画面に反映させる */
     lib_flushgraphbox(0x8024, window, 18, 0, 100, 48, 0, p);      lib_flushgraphbox(0x8024, window, 18, 0, 100, 48, 0, p);
Line 156: Line 156:
       skip : 0(固定)        skip : 0(固定)
       p    : (int *) graphbox + 16        p    : (int *) graphbox + 16
 + 
       なお、上記の例はグラフィックボックス全体をflushしている        なお、上記の例はグラフィックボックス全体をflushしている
     */      */
 + 
     lib_waitsignaltime(0x0007, 0, 0, 0x80000000, 0, 0); /* 500msec.-wait */      lib_waitsignaltime(0x0007, 0, 0, 0x80000000, 0, 0); /* 500msec.-wait */
 + 
     /* 色変更 */      /* 色変更 */
     j = (j + 1) & 0x868686;      j = (j + 1) & 0x868686;
Line 168: Line 168:
         p[i] = j;          p[i] = j;
     }      }
 + 
   }    }
 }  }
Line 181: Line 181:
 #endif  #endif
-たぶん僕の言う「そのうち」はなかなかこないので、上記をコピーして自分のソースに貼り付けてもいいです。 -たぶん僕の言う「そのうち」はなかなかこないので、上記をコピーして自分のソースに貼り付けてもいいです。
 +
 +*** 修正した説明(案)
 +-説明がt_xor0と重複しすぎていて、読み手が飛ばし読みをする恐れがあったので、違いのみをピックアップして書き直しました。
 +
 + 
 +           "mt_xor1.c"の解説
 +                                                                 2004/01/24
 +                                                   川合秀実(kawai@osask.jp)
 + 
 +   このドキュメントは、"mt_xor1.c"の説明だけをするものです。最初に読むべきドキュ
 + メントではありません。最初に読むべきドキュメントは"document.txt"です。
 + 
 + 
 + 1.アルゴリズム
 + 
 +   このmt_xor1は、mt_xor0の改造版に相当します。違いは8ビットグラフィックボックス
 + ではなく32ビットグラフィックボックスを使うことです。mt_xor0を理解してから読んで
 + ください。
 + 
 +   グラフィックボックスのバッファ構造は、LIB_GBOX_BUF32(gbox)から後ろのxsize *
 + ysize * 4がそっくりそのままバッファになっています。詳しいことはソースをご覧く
 + ださい。1ドットが4バイトで構成され、
 +   bit 0- 7:青成分(0-255)
 +   bit 8-15:緑成分(0-255)
 +   bit16-23:赤成分(0-255)
 +   bit24-31:リザーブで必ず0
 + となっています。8bitグラフィックボックスと同様に、自由に読み書きして、必要に応
 + じてflushしてください。
 + 
 + 
 + 2.ライブラリ関数の説明
 + 
 +   引数の型については、guigui00.hを参照してください。
 + 
 +   lib_flushgraphbox(opt, win, x, y, sx, sy, skip, p) :
 + 
 +   グラフィックボックスをflushします。optは0x8004か0x8024にしてください。winは
 + グラフィックボックスが所属するウィンドウです。残りのパラメーターが少々ややこし
 + いです。まずグラフィックボックス全体をflushするなら、
 + 
 +     x, y  : グラフィックボックスオープン時に指定したx_pos, y_posの値
 +     sx, sy : グラフィックボックスオープン時に指定したx_size, y_sizeの値
 +     skip  : 必ず0
 +     p      : LIB_GBOX_BUF32(gox)
 + 
 + という風に指定します。
 + 
 +   32ビットグラフィックボックスで部分フラッシュをすることもできます。その場合は
 + 次のように引数を指定します。
 + 
 +     x, y  : 部分flushしたい範囲の左上の座標(window内の座標系で指定・・・gboxの
 +             座標ではない)
 +     sx, sy : 部分flushしたい範囲のサイズ
 +     skip  : (グラフィックボックスオープン時に指定したx_size - この時のsx) * 4
 +     p      : x, yで指定した座標に相当するドットを指し示すポインタ
 + 
 +   optの違いについてですが、通常は0x8004を使います。色表現力が犠牲になってもいい
 + から、速度を速くしてほしいという場合に限って(もしくはすべての画面モードで細い
 + 線がタイリングで点線に化けたりするのが不都合な場合)、0x8024を指定します。
 + 
 + 
 +  3.改造への指針
 + 
 +   これをつかえば8ビットグラフィックボックスでは得られなかった高い表現力が得られ
 + るでしょう。今のところ(完成度が低いせいで)32ビットグラフィックボックス内でラ
 + インを引くなどができませんが、それでもバッファに書いてflushすれば、一応どんな絵
 + でもかけます。ラインなどの基本描画機能のサポートはもうしばらくお待ちください。
 +
 +-[[K]]の視点で改良したソース。
 +
 + // "mt_xor1.c"
 + //  stack:4k malloc:20k
 + //  copyright(C) 2004 Hidemi KAWAI
 + 
 + #include <guigui00.h>
 + 
 + #define  AUTO_MALLOC  0
 + 
 + /* ちょっとしたマクロ */
 + #define  pixel(x, y)  *(p + (y) * 100 + (x))
 + #if (!defined(LIB_GBOX_BUF))
 +     #define LIB_GBOX_BUF(gbox)  ((void *) ((char *) (gbox) + 64))
 +     #define LIB_GBOX_BUF32(gbox)  ((unsigned int *) LIB_GBOX_BUF(gbox))
 + #endif
 + 
 + void OsaskMain()
 + {
 +     struct LIB_WINDOW *window;
 +     struct LIB_TEXTBOX *wintitle;
 +     struct LIB_GRAPHBOX *graphicbox;
 +     int i, j;
 +     int *p;
 +     static colortable[8] = {
 +         0x000000, 0x840000, 0x008400, 0x848400, 0x000084, 0x840084, 0x008484, 0x848484
 +     };
 + 
 +     lib_init(AUTO_MALLOC);
 +     window = lib_openwindow(AUTO_MALLOC, 0x0200, 136, 48);
 +     wintitle = lib_opentextbox(0x1000, AUTO_MALLOC, 0,  7, 1,  0,  0, window, 0x00c0, 0);
 +     lib_putstring_ASCII(0x0000, 0, 0, wintitle, 0, 0, "Mt.Xor1");
 + 
 +     /* グラフィックボックスをウィンドウに用意する */
 +     graphicbox = lib_opengraphbox(1, AUTO_MALLOC, 4, 0xc6c6c6, 100, 48, 18, 0, window);
 +     /* パラメーターの意味は以下の通り:
 +         opt      : 1(固定)
 +         mode    : 4(固定)
 +         mode_opt : 初期の背景色(バッファはこの値で初期化される)
 +         x_size  : グラフィックボックスの大きさ(ドット単位)
 +         y_size  : グラフィックボックスの大きさ(ドット単位)
 +         x_pos    : グラフィックボックスの位置(ドット単位)
 +         y_pos    : グラフィックボックスの位置(ドット単位)
 +     */
 + 
 +     p = LIB_GBOX_BUF32(graphicbox);
 + 
 +     /* 頂点に一つ点を打つ */
 +     pixel(49, 0) = 0x000000; /* 黒い点 */
 + 
 +     /* ちょっとした演算 */
 +     for (j = 0; j < 47; j++) {
 +         for (i = 1; i < 99; i++)
 +             pixel(i, j + 1) = pixel(i - 1, j) ^ pixel(i + 1, j) ^ 0xc6c6c6;
 +     }
 + 
 +     j = 0;
 +     for (;;) {
 +         /* バッファの内容を確実に画面に反映させる */
 +         lib_flushgraphbox(0x8004, window, 18, 0, 100, 48, 0, p);
 +         /* パラメーターの意味は以下の通り:
 +             opt  : 0x8004 or 0x8024(固定)
 +             win  : グラフィックボックスが所属するウィンドウ
 +             x    : グラフィックボックスのx_pos
 +             y    : グラフィックボックスのy_pos
 +             sx  : グラフィックボックスのx_size
 +             sy  : グラフィックボックスのy_size
 +             skip : 0(固定)
 +             p    : LIB_GBOX_BUF32(graphbox)
 +           なお、上記の例はグラフィックボックス全体をflushしている
 +         */
 + 
 +         lib_waitsignaltime(0x0007, 0, 0, 0x80000000, 0, 0); /* 500msec.-wait */
 + 
 +         /* 色変更 */
 +         j = (j + 1) & 7;
 +         for (i = 0; i < 48 * 100; i++) {
 +             if (p[i] != 0xc6c6c6)
 +                 p[i] = colortable[j];
 +         }
 +     }
 + }

トップ   差分 バックアップ 複製 名前変更 リロード印刷に適した表示   ページ新規作成 全ページ一覧 単語検索 最新ページの一覧   ヘルプ
新着

目次
メンバー一覧


最新の20件
2016-10-01 2016-09-08
  • @MenuBar.
2016-09-07 2016-09-04 2016-08-15 2015-09-23 2014-07-30 2014-07-04 2014-02-04 2013-10-26 2013-06-21 2013-06-17 2013-06-15 2013-04-02 2013-02-09 2013-02-04 2012-12-25 2012-12-01 2012-05-28 2012-03-31

トピック一覧
一般用コメント最新
新掲示板lina
2016/9/5 20:58
SandBoxゲスト
2016/9/4 12:01
RecentDeletedlina
2015/6/2 19:29
Old-OSASK-MLlina
2014/6/29 9:14
hideyosi/メールhideyosi
2014/1/6 20:17
hideyosi/募集中lina
2013/11/8 19:56

このサイトは川合秀実から委託を受けて、OSASKコミュニティによって管理・運営されています。