#norelated

#contents

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

#html{{
<SCRIPT charset="utf-8" type="text/javascript" src="http://ws.amazon.co.jp/widgets/q?ServiceVersion=20070822&MarketPlace=JP&ID=V20070822/JP/p0ded-22/8001/dbf3828d-0a3a-456e-84a0-a47e4695ddd8"> </SCRIPT> <NOSCRIPT><A HREF="http://ws.amazon.co.jp/widgets/q?ServiceVersion=20070822&MarketPlace=JP&ID=V20070822%2FJP%2Fp0ded-22%2F8001%2Fdbf3828d-0a3a-456e-84a0-a47e4695ddd8&Operation=NoScript">Amazon.co.jp ウィジェット</A></NOSCRIPT>
}}


*4-6「色番号設定」(pp.83) [#a88bd30b]
** 縞模様をy方向に [#vdd40b7b]
例題では縞模様はx方向で変化するが、y方向で変化させてみる
-HariMain内
--iが色とVRAMアドレスを兼ねているので、色の変化をx方向の解像度で無視させる
 	for (i = 0; i <= 0xffff; i++) {
 		p[i] = (i/320) & 0x0f;
 	}
-実行結果

&ref(4-6.PNG);


*4-7「四角形を描く」(pp.93) [#g30547b7]
** 座標を指定して点を描く関数を作成  [#a8afd3d8]
- 四角形を描く関数があるので、その前提として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);
--テスト結果

&ref(4-7.PNG);

** 2点の座標を指定して線を描く関数を作成  [#qa76cb49]
--少しレベルアップして線を描いてみることにした。まずは思いついたとおりに書いてみる。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);
--テスト実行

&ref(4-7-2.PNG);

失敗。傾きがintであるため、傾きが切り捨てられy座標が足りていない。
失敗。傾きが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);
 		}
---実行結果

&ref(4-7-3.PNG);

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

*5-1「とにかく文字をだしたい」(pp.100) [#r9794ef6]
** 影つき文字にする [#y68dd8a8]
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;
 }
-- 実行結果

&ref(5-4.PNG);

*5-6 文字列を書きたい(pp.105) [#yeba6b09]
** 文字列を折り返す [#v284d14b]
文字列を画面右隅にすると、下記の図のようにはみでた文字列がyが1だけインクリメントされた座標で表示される。そこで、1文字分きれいに改行させてみる。

&ref(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;
 }

--実行結果

&ref(5-6-2.PNG);

* 5-8「マウスカーソルも描いてみよう」(pp.109) [#e07187bf]
** カーソルが重なってもOKにしてみる [#bfabccf4]
-オリジナルのままカーソルを文字列に重ねると以下のようになる(当然、著者様はこの時点ではわざとこうしている)

&ref(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;
 }

--実行結果
---それっぽくなりました。とはいえあくまで学習用の修正。

&ref(5-8-2.PNG);

* 参考 [#ie64de06]
- 「30日でできる! OS自作入門」のページ http://wiki.osask.jp/?HariboteOS

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS