ページへ戻る

+ Links

 印刷 

gg00man​/lib_getsig :: OSASK計画

osaskwiki:gg00man編集/lib_getsig

lib_getsigのページ

  • (2004.05.05 by K)
  • みんなのソースを見ていると、誰もがgetsignal()やgetsignalw()を作って使っています。しかし中身は僕が作ったときのままで、手を加えたものはめったにありません。
  • これを見て僕は反省しています。確かにgetsignalにはほとんど創意工夫の余地がありません。そんなものを毎回書かせていたことは、ソースをむやみに長くして読みにくくしていただけでしょう。
  • ということで、lib_getsig系の関数を作りました。良かったらこれを使ってください。introでの説明も順次こちらの説明に切り替えようと思っています。また、たいていの場合、今までのgetsignalを使うよりもlib_getsig系を使うほうがコンパクトで速くなります(わずかな差ですが)。
Page Top

ダウンロード

Page Top

関数一覧

  • lib_initsignalbox系
    • lib_initとlib_opensignalboxをくっつけたもの。
    • だからこれ一つでlib_initもlib_opensignalboxも不要。
    • これはmallocしないので、malloc領域の計算で数えなくてよい。
    • lib_getsig系を使うにはこの関数でシグナルボックスを初期化するか、もしくは特定の書式でシグナルボックス構造体を構成する必要がある(下記の「lib_initsignalbox0_256の中身」の記述を参考)。
    • 従来どおりユーザが自作したgetsignal等を使うのなら、この関数を使う必要もシグナルボックス構造体を作る必要もない。
    • シグナルボックスのサイズに応じて関数名にバリエーションがある。どれか一つを選ぶ(将来的には1k版と16k版も作る予定)。
    • lib_initsignalbox0_256(int rewind);
    • lib_initsignalbox0_4k(int rewind);
    • lib_initsignalbox0_64k(int rewind);
  • lib_getsig系
    • 末尾にwが付いているのは、シグナルがくるまで待ってくれる関数である。相当の動作は以下を参照。w版では、関数値が0になることはない。
    • lib_getsig0(int *sigbox);
    • lib_getsig0w(int *sigbox);
    • lib_getsig1(int *sigbox);
    • lib_getsig1w(int *sigbox);
    • 0版と1版の違いは、次の通り。
      • ノーマル版とw版のどちらかしか使わないのなら、0版を使うほうが高速かつコンパクト(ほとんどのプログラムはこちらに該当)。
      • ノーマル版とw版の両方を使うなら、1版を使うほうが高速かつコンパクト。
  • w版の動作説明用ソース
    int getsignalw()
    {
        int sig;
    retry:
        sig = getsignal();
        if (sig == 0) {
            lib_waitsignal(0x0001, 0, 0); /* シグナルがくるまでsleep */
            goto retry;
        }
        return sig;
    }
Page Top

使用例

/* "movec2.c" */
/*  stack:4k malloc:2k */

#include <guigui00.h>
#define AUTO_MALLOC      0

/* シグナルボックス関係 */
#define REWIND_CODE      1
#define initsignalbox()  lib_initsignalbox0_256(REWIND_CODE)
#define getsignalw()     lib_getsig0w(lib_sigbox_256)

void OsaskMain()
{
    struct LIB_WINDOW *window;
    struct LIB_TEXTBOX *wintitle, *textbox;
    int x, y, c;

    /* ライブラリ初期化&シグナルボックス初期化 */
    initsignalbox();

    /* ウィンドウオープン */
    window = lib_openwindow(AUTO_MALLOC, 0x0200, 20 * 8, 8 * 16);
    wintitle = lib_opentextbox(0x1000, AUTO_MALLOC, 0,  6, 1, 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, "movec2");

    /* シグナル定義 */
    lib_definesignal1p0(3, 0x0100, 0x00ac, window, 4); /* カーソルキー(計4つ) */
    lib_definesignal1p0(0, 0x0100, ' ',    window, 8); /* スペースバー */
    lib_definesignal0p0(0, 0, 0, 0);

    /* まず表示 */
    x = 9; y = 3; c = 11;
    lib_putstring_ASCII(0x0000, x, y, textbox, c, 0, "O");

    /* メインループ */
    for (;;) {
        int ox = x, oy = y, oc = c, sig;
        sig = getsignalw();
        if (sig == 4) { /* left */
            if (x > 0)
                x--;
        }
        if (sig == 5) { /* right */
            if (x < 19)
                x++;
        }
        if (sig == 6) { /* up */
            if (y > 0)
                y--;
        }
        if (sig == 7) { /* down */
            if (y < 7)
                y++;
        }
        if (sig == 8) { /* chagne */
            c = (c + 1) & 0x0f;
        }
        /* 何らかの変化があれば表示し直す */
        if (x != ox || y != oy || c != oc) {
            lib_putstring_ASCII(0x0000, ox, oy, textbox, 0, 0, " ");
            lib_putstring_ASCII(0x0000, x,  y,  textbox, c, 0, "O");
        }
    }
}
Page Top

マウスシグナルとかを扱いたい場合は?

  • マウスシグナルとかを扱いたい場合、getparam系の関数が必要になります。そういう人は、
    /* シグナルボックス関係 */
    #define REWIND_CODE      1
    #define initsignalbox()  lib_initsignalbox0_4k(REWIND_CODE)
    #define getsignalw()     lib_getsig0w(lib_sigbox_4k)
    #define sig_ptr          lib_sigptr_4k
  • として、sig_ptrを使えるようにしてください(256でも64kでも同様にできます)。これがあればgetparamを作るのは簡単です。以下に例を示します。
    int getparam()
    {
        int param = *sig_ptr++;
        lib_waitsignal(0x0000, 1, 0);
        return param;
    }
  • もちろんgetparam系の関数など作らずに、たとえば、
        x = sig_ptr[0];
        y = sig_ptr[1];
        sig_ptr += 2;
        lib_waitsignal(0x0000, 2, 0);
  • とやるほうがより高速です。
Page Top

lib_initsignalbox0_256の中身

  • execcmd化の参考などに
    void lib_initsignalbox0_256(int rewind)
    {
        static struct {
            int rewind, dummy;
            int *ptr;
            int box[256 / 4]; /* ここが4kだったり64kだったりする */
        } sigstr = {
            0, 0, sigstr.box, { 0 }
        };
        static struct LIB_WORK lib_work256;
        sigstr.rewind = rewind; /* lib_getsigが参照するので保存しておく */
        lib_init_nm(&lib_work256);
        lib_opensignalbox_nm(256, sigstr.box, 0, rewind);
    }
    
    /* sigstr.ptrがlib_sigptr_256, sigstr.boxがlib_sigbox_256 */
Page Top

こめんと欄

  • lib_initとlib_opensignalboxをくっつけるのはなんかビミョーな気がします。。いや、便利だけどね。。 -- あっきぃ 2004-05-05 (水) 23:21:09
  • いい意見!lib_initの直後にlib_opensignalboxをやりなさいっていうルールがありますが、たまに忘れそうになるので、ひとつにまとめちゃいました。 -- K 2004-05-05 (水) 23:32:05
  • いつものoptスイッチ仕様じゃなくて、サイズ別関数名にしたのには意味があるのかな?可読性はよさそうだけど。 -- 名無しさん 2004-05-05 (水) 23:52:53
  • それは実は情けない理由があって、上記の例のように関数内にstatic配列を確保する関係上、変数で値を指定されると厄介だったのです。・・・が、まあ、とりあえずちょっとだけ読みやすい気がしますし、256じゃなくて200じゃないと困るとかそういうことは多分ないので、大目に見てください。 -- K 2004-05-06 (木) 00:07:52
  • ちなみに従来のgetsignalwの直接記述よりも常に優れているというわけではなく、状況によっては、ソースサイズは小さくなるけど実行ファイルはでかくなる、こともあるそうです。われながらイマイチですね。512キャンペーンに使えるかどうかは、試してみないと分からないようです。とりあえず初心者向けではあるかな。 -- K 2004-05-06 (木) 00:11:28
  • getsignalがあるならばput(send?)signalとかありそうだなどと言ってみるテスト。・・・自分自身に送るってのあるけど、これは別アプリには届かないのかな? -- 名無しさん 2004-05-06 (木) 00:54:10
  • 微妙にページ違いな気がするのでimpressionsに移動してもいいでしょうか? -- K 2004-05-06 (木) 03:58:51
  • test062版なら実行ファイルもそれほどは大きくならないはずです。もしかしたら同じか小さくなるかも?(そうであってほしいなあ)。 -- K 2004-05-06 (木) 04:32:55
  • test063+go_0023の最強の組み合わせでもサイズが大きくなっちゃう場合があるそうです。ということでlib_getsigが常に良いとは限らないようです。 -- K 2004-05-07 (金) 14:25:17

Last-modified: 2009-11-17 (火) 00:00:00 (JST) (319d) by ゲスト