このページは何?

「30日でできる! OS自作入門」を実行しながら読むも、性格上の問題からか、 それだけではイマイチやりがいと学んだ実感が湧かないため、自分で問題を作り進めることにした。 このページでは、そのログを掲載する。 コードを載せすぎると著作権にかかる気がするため、最低限にする。 OSという観点ではあまり意味の無い修正・問題ばかりだが、 それでも単にmake runで読み進めるよりは楽しい。

4-6「色番号設定」(pp.83)

縞模様をy方向に

例題では縞模様はx方向で変化するが、y方向で変化させてみる

  • HariMain?
    • iが色とVRAMアドレスを兼ねているので、色の変化をx方向の解像度で無視させる
      	for (i = 0; i <= 0xffff; i++) {
      		p[i] = (i/320) & 0x0f;
      	}
  • 実行結果

4-6.PNG

4-7「四角形を描く」(pp.93)

座標を指定して点を描く関数を作成

  • 四角形を描く関数があるので、その前提として1ピクセル描くものがあってよいだろう、 と応用するどころか基本に戻ってみた。
  • 関数定義
    void drawpoint(unsigned char *vram, int xsize, unsigned char c, int x0, int y0)
    {
    	int x, y;
    
    	vram[ y0 * xsize + x0] = c;
    
    	return;
    }
  • テスト呼び出し
    	 drawpoint(p, 320, COL8_FFFFFF, 10,   10);
    	 drawpoint(p, 320, COL8_FFFFFF, 100,  150);
  • テスト結果

4-7.PNG

2点の座標を指定して線を描く関数を作成

  • 少しレベルアップして線を描いてみることにした。まずは思いついたとおりに書いてみる。2点の間の任意の位置の座標を計算するため、傾きdを計算する。
  • 関数定義
    void drawline8(unsigned char *vram, int xsize, unsigned char c, int x0, int y0, int x1, int y1)
    {
    	int x, y;
    	
    	int d;
    	
    	d = (y1-y0)/(x1-x0);
    	y = y0;
    
    	for (x = x0; x <= x1; x++){
    		y += d;
    		vram[ y * xsize + x] = c;
    	}
    	return;
    }
  • テスト呼び出し
    	drawline8(p, 320, COL8_FF0000, 10,  10, 100,150);
  • テスト実行

4-7-2.PNG

失敗。傾きがintであるため、切り捨てられy座標が足りていない。 とりあえず傾きを毎回計算させて目標のy座標になるようにしてみた。

  • 関数定義
    void drawline28(unsigned char *vram, int xsize, unsigned char c, int x0, int y0, int x1, int y1)
    {
    	int x, y;
    	
    	int d;
    	
    	d = (y1-y0)/(x1-x0);
    	y = y0;
    
    	for (x = x0; x <= x1; x++){
    		y = y + d;
    		d = (y1-y)/(x1-x);
    		vram[ y * xsize + x] = c;
    	}
    
    	return;
    }
  • 実行結果
    • そもそも描画されず固まった。1日ほど悩んだ末、x1=xのとき0除算をしていることに気がついた。通常のプログラミングと違い、そういったエラーも放っておくと表示されないので難しい。
  • 関数定義
    • 傾き計算部分を変更
      		if(x<x1){
      			d = (y1-y)/(x1-x);
      		}
    • 実行結果

4-7-3.PNG

  • まぁ美しくはないが、目的は達成。もう少し、傾き小、大というのを細かく繰り返させたいが・。

5-1「とにかく文字をだしたい」(pp.100)

影つき文字にする

Aという文字を表示させる例題に対して、影つき文字にさせる。 配列を使ったほうのコードの方が変更が楽そうだが、 ポインタの追加で対処した。

  • 関数実装
    void putfont8(char *vram, int xsize, int x, int y, char c, char *font)
    {
    	int i;
    	char *p, d /* data */;
    	char *p_shadow;
    
    	for (i = 0; i < 16; i++) {
    		p = vram + (y + i) * xsize + x;
    		p_shadow = vram + (y + i + 1 ) * xsize + x + 1;
    		d = font[i];
    		if ((d & 0x80) != 0) { p[0] = c; p_shadow[0] = COL8_000000; }
    		if ((d & 0x40) != 0) { p[1] = c; p_shadow[1] = COL8_000000; }
    		if ((d & 0x20) != 0) { p[2] = c; p_shadow[2] = COL8_000000; }
    		if ((d & 0x10) != 0) { p[3] = c; p_shadow[3] = COL8_000000; }
    		if ((d & 0x08) != 0) { p[4] = c; p_shadow[4] = COL8_000000; }
    		if ((d & 0x04) != 0) { p[5] = c; p_shadow[5] = COL8_000000; }
    		if ((d & 0x02) != 0) { p[6] = c; p_shadow[6] = COL8_000000; }
    		if ((d & 0x01) != 0) { p[7] = c; p_shadow[7] = COL8_000000; }
    	}
    	return;
    }
  • 実行結果

5-4.PNG

5-6 文字列を書きたい(pp.105)

文字列を折り返す

文字列を画面右隅にすると、下記の図のようにはみでた文字列がyが1だけインクリメントされた座標で表示される。そこで、1文字分きれいに改行させてみる。

5-6-1.PNG

  • 関数定義
    • やってることといえば、x座標が解像度ぎりぎりのときに、x座標をリセットし、 y座標を1文字分増加させているくらい。
void putfonts8_asc(char *vram, int xsize, int x, int y, char c, unsigned char *s)
{
	extern char hankaku[4096];
	for (; *s != 0x00; s++) {
		if( (xsize - 8) < x ){
			x=0;
			y+= 16;
		}
		putfont8(vram, xsize, x, y, c, hankaku + *s * 16);
		x += 8;
	}
	return;
}
  • 実行結果

5-6-2.PNG

5-8「マウスカーソルも描いてみよう」(pp.109)

カーソルが重なってもOKにしてみる

  • オリジナルのままカーソルを文字列に重ねると以下のようになる(当然、著者様はこの時点ではわざとこうしている)

5-8-1.PNG

  • 関数定義 まずはバッファによる描画関数、putblock8_8をinit_mouse_cursor8と統合して、 ポインタ描画を直接VRAM上で描画する関数にしてみる(退化)。 また、簡単な対処で、背景を塗りつぶす処理をさせないようにしてる。 あとは、呼び出す順番を文字列→ポインタに。
void init_mouse_cursor8(char *vram, int vxsize, int px0, int py0,char bc)
/* マウスカーソルを準備(16x16) */
{
	static char cursor[16][16] = {
〜略〜
	};
	int x, y;

	for (y = 0; y < 16; y++) {
		for (x = 0; x < 16; x++) {
			if (cursor[y][x] == '*') {
				vram[(py0 + y) * vxsize + (px0 + x)] = COL8_000000;
			}
			if (cursor[y][x] == 'O') {
				vram[(py0 + y) * vxsize + (px0 + x)] = COL8_FFFFFF;
			}
			if (cursor[y][x] == '.') {
				//vram[(py0 + y) * vxsize + (px0 + x)] = bc;
			}
		}
	}
	return;
}
  • 実行結果
    • それっぽくなりました。とはいえあくまで学習用の修正。

5-8-2.PNG

参考


添付ファイル: file5-8-2.PNG 213件 [詳細] file5-6-2.PNG 202件 [詳細] file5-8-1.PNG 214件 [詳細] file5-6-1.PNG 203件 [詳細] file5-4.PNG 205件 [詳細] file4-7.PNG 222件 [詳細] file4-7-2.PNG 203件 [詳細] file4-7-3.PNG 203件 [詳細] file4-6.PNG 218件 [詳細]

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2010-11-28 (日) 21:47:46 (2546d)