何か描いてみる(点・線・円描画)

ネットに流れているHelloWorldを解析しながら
最初は描画の仕方から話を続けていきます。

pgInit();
pgScreenFrame(2,0);

画面モードの設定のようですね。
  ゲーム機によくあるように画面モードは切りかえれるようですが
  今回は16ビットカラーが出るらしいこのままにしておきます。

pgFillvram関数が画面塗りつぶしなのでこれに注目しますと
pgGetVramAddr関数にて指定座標のポインタを受け取っていますね。
この関数内を見ればVRAMの先頭がわかります。
どうやらVRAMの先頭アドレスは0x04000000のようです。
やはり現状は直接メモリに書き込んで描画しているようで,
GBAの自作プログラムと雰囲気は似ていますねw

同じくpgGetVramAddrを見る事によりVRAMの横幅もわかります。
現在512で折り返しているので横512ドットですね。
アドレスでは16ビットカラーなので1024バイト単位で次の行への
描画になりますね。

これを踏まえて点描画命令

//━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
//点描画
//━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

void setPixel(int x, int y, int color)
{
  unsigned char *vptr0;
  vptr0=pgGetVramAddr(0,0);
  *(unsigned short *)(vptr0+(y*512+x)*2)=color;
}


色指定が16ビットなので指定が面倒ですねぇ...
専用に命令を作っちゃいましょう

//━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
//色指定
//━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

short setColor(int r,int g,int b){
  return ((((b)>>3)<<10)|(((g)>>3)<<5)|((r)>>3));
}


これでRGB0〜255で指定して自動的に16ビットカラーに落としてくれます。
移植物を作る時に便利ですね^^


ラインアートを作る時など用に線も引きたいですね。

//━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
//線描画
//━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

void drawLine(int sx, int sy, int ex, int ey, int color)
{
  int addX, addY;
  int dstX, dstY;
  int counter,lp;
  unsigned char *vptr0;
  vptr0=pgGetVramAddr(0,0);

  dstX=ex-sx;
  dstY=ey-sy;
  if(dstX<0){dstX*=-1; addX=-1;}else{ addX=1;}
  if(dstY<0){dstY*=-1; addY=-1;}else{ addY=1;}

  counter=0;  //カウンターをクリア
  if(dstX>dstY){
    //Xの距離の方がYの距離よりも大きい場合
    for(lp=0; lp<=dstX; lp++)
    {
      //vvram[ sy*VramW+sx ]=(unsigned char)color;
      *(unsigned short *)(vptr0+(sy*512+sx)*2)=color;
      sx+=addX;
      counter+=dstY;
      if( counter>=dstX ){
        sy+=addY;
        counter-=dstX;
      }
    }
  }
  else{
    //Yの距離の方がXの距離よりも大きい場合
    for(lp=0; lp<=dstY; lp++)
    {
      //vvram[ sy*VramW+sx ]=(unsigned char)color;
      *(unsigned short *)(vptr0+(sy*512+sx)*2)=color;
      sy+=addY;
      counter+=dstX;
      if( counter>=dstY ){
        sx+=addX;
        counter-=dstY;
      }
    }
  }
}

何かに使う時用に円描画も作っておきましょう。

//━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
//円描画
//━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

void  Circle( int x, int y, int r,int c)
{
  unsigned char *vptr0;
  vptr0=pgGetVramAddr(0,0);
  int dx=r;
  int dy=0;
  int s=r;
  while(dx>=dy)
  {
    setPixel(x+dx,y+dy,c);//右右下
    setPixel(x+dx,y-dy,c);//右右上
    setPixel(x-dx,y+dy,c);//左左下
    setPixel(x-dx,y-dy,c);//左左上
    setPixel(x+dy,y+dx,c);//右下下
    setPixel(x+dy,y-dx,c);//右上上
    setPixel(x-dy,y+dx,c);//左下下
    setPixel(x-dy,y-dx,c);//左上上
    s-=2*dy+1;if(s<0)s+=2*(dx-1),dx--;
    dy++;
  }
}

これで色々と基本描画は揃いましたね。^^
それでは次回からは用意した画像を表示する方法に入ります
<今回の解説を描画した例>

今回のサンプルの実機用バイナリ(ファームVer1.0専用)