changeset 283:55ea4465b1a2

fix test_render
author e065746@localhost.localdomain
date Fri, 05 Jun 2009 16:49:12 +0900
parents ef061be0baff
children 6ceb40aec7fb 181f693be3d5
files Renderer/test_render/Button.cpp Renderer/test_render/Button.h Renderer/test_render/Camera.cpp Renderer/test_render/Camera.h Renderer/test_render/ChangeLog Renderer/test_render/Func.h Renderer/test_render/Joystick.cpp Renderer/test_render/Joystick.h Renderer/test_render/Keyboard.cpp Renderer/test_render/Keyboard.h Renderer/test_render/Makefile Renderer/test_render/Makefile.def Renderer/test_render/Makefile.linux Renderer/test_render/Makefile.macosx Renderer/test_render/Makefile.ps3 Renderer/test_render/Pad.cpp Renderer/test_render/Pad.h Renderer/test_render/SGList.cpp Renderer/test_render/SGList.h Renderer/test_render/SceneGraph.cpp Renderer/test_render/SceneGraph.h Renderer/test_render/SceneGraphArray.h Renderer/test_render/SceneGraphIterator.cpp Renderer/test_render/SceneGraphIterator.h Renderer/test_render/SceneGraphRoot.cpp Renderer/test_render/SceneGraphRoot.h Renderer/test_render/Span.h Renderer/test_render/SpanC.cpp Renderer/test_render/SpanC.h Renderer/test_render/SpanPack.h Renderer/test_render/Tapestry.h Renderer/test_render/TextureHash.cpp Renderer/test_render/TextureHash.h Renderer/test_render/ball_bound.cpp Renderer/test_render/base64_de.cpp Renderer/test_render/boss1_action.cpp Renderer/test_render/boss1_action.h Renderer/test_render/bullet_action.cpp Renderer/test_render/bullet_action.h Renderer/test_render/camera_action.cpp Renderer/test_render/camera_action.h Renderer/test_render/cube_action.cpp Renderer/test_render/demonstration.h Renderer/test_render/direction.cpp Renderer/test_render/enemy_action.cpp Renderer/test_render/enemy_action.h Renderer/test_render/fb.h Renderer/test_render/hash_texture.h Renderer/test_render/hit_judge.cpp Renderer/test_render/hit_judge.h Renderer/test_render/icon.png Renderer/test_render/ieshoot.cpp Renderer/test_render/init_position.cpp Renderer/test_render/long_cube.cpp Renderer/test_render/main.cpp Renderer/test_render/node.cpp Renderer/test_render/panel.cpp Renderer/test_render/player_action.cpp Renderer/test_render/player_action.h Renderer/test_render/polygon.cpp Renderer/test_render/polygon.h Renderer/test_render/polygon_pack.h Renderer/test_render/post.cpp Renderer/test_render/scene.h Renderer/test_render/scene_graph_pack.h Renderer/test_render/spe/CreatePolygon.cpp Renderer/test_render/spe/CreatePolygon.h Renderer/test_render/spe/CreateSpan.cpp Renderer/test_render/spe/CreateSpan.h Renderer/test_render/spe/DrawBack.cpp Renderer/test_render/spe/DrawBack.h Renderer/test_render/spe/DrawSpan.cpp Renderer/test_render/spe/DrawSpan.h Renderer/test_render/spe/DrawSpanRenew.cpp Renderer/test_render/spe/DrawSpanRenew.h Renderer/test_render/spe/Load_Texture.cpp Renderer/test_render/spe/Load_Texture.h Renderer/test_render/spe/Set_Texture.cpp Renderer/test_render/spe/Set_Texture.h Renderer/test_render/spe/TileHash.cpp Renderer/test_render/spe/TileHash.h Renderer/test_render/spe/spe-main.cpp Renderer/test_render/spe/texture.h Renderer/test_render/spe/viewer_types.cpp Renderer/test_render/sys.cpp Renderer/test_render/sys.h Renderer/test_render/task/CreatePolygon.cpp Renderer/test_render/task/CreatePolygon.h Renderer/test_render/task/CreatePolygonFromSceneGraph.cpp Renderer/test_render/task/CreatePolygonFromSceneGraph.h Renderer/test_render/task/CreateSpan.cpp Renderer/test_render/task/CreateSpan.h Renderer/test_render/task/DrawBack.cpp Renderer/test_render/task/DrawBack.h Renderer/test_render/task/DrawSpan.cpp Renderer/test_render/task/DrawSpan.h Renderer/test_render/task/DrawSpanRenew.cpp Renderer/test_render/task/DrawSpanRenew.h Renderer/test_render/task/Load_Texture.cpp Renderer/test_render/task/Load_Texture.h Renderer/test_render/task/Set_Texture.cpp Renderer/test_render/task/Set_Texture.h Renderer/test_render/task/TileHash.cpp Renderer/test_render/task/TileHash.h Renderer/test_render/task/create_sgp.cpp Renderer/test_render/task/create_sgp.hpp Renderer/test_render/task/dummy.cpp Renderer/test_render/task/dummy.hpp Renderer/test_render/task/task_init.cpp Renderer/test_render/task/texture.h Renderer/test_render/task/update_sgp.cpp Renderer/test_render/task/update_sgp.hpp Renderer/test_render/texture.cpp Renderer/test_render/texture.h Renderer/test_render/tools/create_sglist.pl Renderer/test_render/triangle.cpp Renderer/test_render/triangle.h Renderer/test_render/universe.cpp Renderer/test_render/untitled.cpp Renderer/test_render/vacuum.cpp Renderer/test_render/vertex.cpp Renderer/test_render/vertex.h Renderer/test_render/viewer.cpp Renderer/test_render/viewer.h Renderer/test_render/viewerFB.cpp Renderer/test_render/viewerFB.h Renderer/test_render/viewerSDL.cpp Renderer/test_render/viewerSDL.h Renderer/test_render/viewer_types.cpp Renderer/test_render/viewer_types.h Renderer/test_render/xml.cpp Renderer/test_render/xml.h Renderer/test_render/xml_file/Ball.h Renderer/test_render/xml_file/Ball.xml Renderer/test_render/xml_file/LongCube.h Renderer/test_render/xml_file/LongCube.xml Renderer/test_render/xml_file/Venus.h Renderer/test_render/xml_file/Venus.xml Renderer/test_render/xml_file/blast.h Renderer/test_render/xml_file/blast.xml Renderer/test_render/xml_file/blend/Ball.blend Renderer/test_render/xml_file/blend/LongCube.blend Renderer/test_render/xml_file/blend/direction.blend Renderer/test_render/xml_file/blend/ieboss.blend Renderer/test_render/xml_file/blend/iejiki.blend Renderer/test_render/xml_file/blend/ietama.blend Renderer/test_render/xml_file/blend/images/ball.jpg Renderer/test_render/xml_file/blend/images/icon.jpg Renderer/test_render/xml_file/blend/images/iejiki.jpg Renderer/test_render/xml_file/blend/images/ietama.jpg Renderer/test_render/xml_file/blend/images/panel_1024.jpg Renderer/test_render/xml_file/blend/images/panel_2048.jpg Renderer/test_render/xml_file/blend/images/panel_512.jpg Renderer/test_render/xml_file/blend/panel_1024.blend Renderer/test_render/xml_file/blend/panel_2048.blend Renderer/test_render/xml_file/blend/panel_512.blend Renderer/test_render/xml_file/boss1.h Renderer/test_render/xml_file/boss1.xml Renderer/test_render/xml_file/cube.h Renderer/test_render/xml_file/cube.xml Renderer/test_render/xml_file/cube_big.h Renderer/test_render/xml_file/cube_big.xml Renderer/test_render/xml_file/cube_split.h Renderer/test_render/xml_file/cube_split.xml Renderer/test_render/xml_file/direction.h Renderer/test_render/xml_file/direction.xml Renderer/test_render/xml_file/ieboss.h Renderer/test_render/xml_file/ieboss.xml Renderer/test_render/xml_file/iejiki.h Renderer/test_render/xml_file/iejiki.xml Renderer/test_render/xml_file/ietama.h Renderer/test_render/xml_file/ietama.xml Renderer/test_render/xml_file/mcube.xml Renderer/test_render/xml_file/p_shot.h Renderer/test_render/xml_file/p_shot.xml Renderer/test_render/xml_file/panel_1024.h Renderer/test_render/xml_file/panel_1024.xml Renderer/test_render/xml_file/panel_2048.h Renderer/test_render/xml_file/panel_2048.xml Renderer/test_render/xml_file/panel_512.h Renderer/test_render/xml_file/panel_512.xml Renderer/test_render/xml_file/player.h Renderer/test_render/xml_file/player.xml Renderer/test_render/xml_file/sphere.h Renderer/test_render/xml_file/sphere.xml Renderer/test_render/xml_file/sphere_big.h Renderer/test_render/xml_file/sphere_big.xml Renderer/test_render/xml_file/universe.h Renderer/test_render/xml_file/universe.xml TaskManager/Test/test_render/Makefile TaskManager/Test/test_render/boss1_action.cpp TaskManager/Test/test_render/boss1_action.h TaskManager/Test/test_render/xml_file/blend/blast.blend TaskManager/Test/test_render/xml_file/blend/boss1.blend TaskManager/Test/test_render/xml_file/blend/images/boss1_organ.png TaskManager/Test/test_render/xml_file/blend/images/laser_1.png TaskManager/Test/test_render/xml_file/blend/images/player_idle.png TaskManager/Test/test_render/xml_file/blend/images/player_leftmove.png TaskManager/Test/test_render/xml_file/blend/images/player_rightmove.png TaskManager/Test/test_render/xml_file/blend/images/player_turntoleft.png TaskManager/Test/test_render/xml_file/blend/images/player_turntoright.png TaskManager/Test/test_render/xml_file/blend/images/redbomb_anim_0.png TaskManager/Test/test_render/xml_file/blend/images/redbomb_anim_1.png TaskManager/Test/test_render/xml_file/blend/images/redbomb_anim_2.png TaskManager/Test/test_render/xml_file/blend/images/redbomb_anim_3.png TaskManager/Test/test_render/xml_file/blend/images/redbomb_anim_4.png TaskManager/Test/test_render/xml_file/blend/images/redbomb_anim_5.png TaskManager/Test/test_render/xml_file/blend/images/redbomb_anim_6.png TaskManager/Test/test_render/xml_file/blend/images/redbomb_anim_7.png TaskManager/Test/test_render/xml_file/blend/p_shot.blend TaskManager/Test/test_render/xml_file/blend/player.blend TaskManager/Test/test_render/xml_file/player.xml TaskManager/Test/test_render/xml_file/player.xml.orig TaskManager/Test/test_render/xml_file/player1.xml
diffstat 214 files changed, 341194 insertions(+), 1449 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/Button.cpp	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,55 @@
+#include "Button.h"
+
+/**
+ * ボタン押下時に push, hold, release の状態を変更する
+ * push は押した瞬間にだけ 1 を持つ
+ * hold の状態では 0 を持つ
+ */
+void
+Button::push_work(void)
+{
+    push = (!hold);
+    hold = 1;
+    release = 0;
+}
+
+/**
+ * ボタンを離した時に push, hold, release の状態を変更する
+ */
+void
+Button::release_work(void)
+{
+    push = 0;
+    hold = 0;
+    release = 1;
+}
+
+/**
+ * @retval 1 ボタンが押された(このフレームのみ)
+ * @retval 0 押されていない
+ */
+int
+Button::isPush(void)
+{
+    return push;
+}
+
+/**
+ * @retval 1 ボタンは押され続けている
+ * @retval 0 ボタンは押されていない
+ */
+int
+Button::isHold(void)
+{
+    return hold;
+}
+
+/**
+ * @retval 1 ボタンは押されていない
+ * @retval 0 ボタンが押されている
+ */ 
+int
+Button::isRelease(void)
+{
+    return release;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/Button.h	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,19 @@
+#ifndef INCLUDED_BUTTON
+#define INCLUDED_BUTTON
+
+class Button {
+public:
+    int push;
+    int hold;
+    int release;
+
+    Button(void) : push(0), hold(0), release(0) {}
+
+    void push_work(void);
+    void release_work(void);
+    int isPush(void);
+    int isHold(void);
+    int isRelease(void);
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/Camera.cpp	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,251 @@
+#include <math.h>
+#include "SceneGraphRoot.h"
+#include "Camera.h"
+#include "sys.h"
+
+static void
+camera_move(SceneGraphPtr _node, int screen_w, int screen_h)
+{
+    Pad *pad = sgroot->getController();
+    CameraPtr node = (CameraPtr)_node;
+
+#if 0
+    if (pad->right.isHold()) {
+	node->xyz[0] += 10.0f;
+    } else if (pad->left.isHold()) {
+	node->xyz[0] -= 10.0f;
+    }
+
+    if (pad->up.isPush() || pad->up.isHold()) {
+	node->xyz[1] -= 2.0f;
+    } else if (pad->down.isPush() || pad->down.isHold()) {
+	node->xyz[1] += 2.0f;
+    }
+#endif
+
+    if (pad->r1.isPush() || pad->r1.isHold()) {
+	node->xyz[2] += 10.0f;
+    } else if (pad->l1.isPush() || pad->l1.isHold()) {
+	node->xyz[2] -= 10.0f;
+    }
+
+    if (pad->r2.isHold()) {
+	if (node->zd[0] <= 1.0f) {
+	    node->zd[0] += 0.02f;
+	}
+	if (node->zd[2] >= 0.0f) {
+	    node->zd[2] -= 0.02f;
+	}
+    } else if (pad->l2.isHold()) {
+	if (node->zd[0] > -1.0f) {
+	    node->zd[0] -= -0.02f;
+	}
+	if (node->zd[2] >= 0.0f) {
+	    node->zd[2] -= 0.02f;
+	}
+    } else {
+	node->zd[0] = 0.0f;
+	node->zd[2] = 1.0f;
+    }
+
+}
+
+static void
+camera_collision(SceneGraphPtr node, int screen_w, int screen_h,
+		 SceneGraphPtr tree)
+{
+}
+
+/**
+ * @param w Width of screen
+ * @param h Height of screen
+ */
+Camera::Camera(float w, float h)
+{
+    name = (char*)"Camera";
+
+
+    fov  = 60.0f;
+    near = 0.0f;
+    far  = 1000.0f;
+
+    zd[0] =  0.0f;
+    zd[1] =  0.0f;
+    zd[2] =  1.0f;
+    zd[3] =  1.0f;
+
+    yd[0] = 0.0f;
+    yd[1] = 1.0f;
+    yd[2] = 0.0f;
+    yd[3] = 1.0f;
+
+    // Screen の真ん中を初期値とする
+    xyz[0] = w/2.0f;
+    xyz[1] = h/2.0f;
+
+    // min(w, h) がちょうど一杯見えるような z の位置の計算
+    xyz[2] = -(((xyz[1] < xyz[0]) ? xyz[1] : xyz[0])/tanf((fov/2.0f)*M_PI/180.0f));
+    //xyz[2] = -200.0f;
+    xyz[3] = 1.0f;
+
+    m_view = new float[16];
+    m_pers = new float[16];
+    m_screen = new float[16];
+    
+    this->set_move_collision(camera_move, camera_collision);
+}
+
+Camera::~Camera(void)
+{
+    delete [] m_view;
+    delete [] m_pers;
+    delete [] m_screen;
+}
+
+void
+Camera::updateView(void)
+{
+    float radx,rady,radz;
+    float cx[4], cy[4], cz[4], p[4];
+    float tm[16];
+
+    radx = angle[0]*3.14/180;
+    rady = angle[1]*3.14/180;
+    radz = angle[2]*3.14/180;
+
+    float sinx = sin(radx);
+    float cosx = cos(radx);
+    float siny = sin(rady);
+    float cosy = cos(rady);
+    float sinz = sin(radz);
+    float cosz = cos(radz);
+
+    /* View Transform */
+    tm[0] = cosz*cosy+sinz*sinx*siny;
+    tm[1] = sinz*cosx;
+    tm[2] = -cosz*siny+sinz*sinx*cosy;
+    tm[3] = 0.0f;
+    tm[4] = -sinz*cosy+cosz*sinx*siny;
+    tm[5] = cosz*cosx;
+    tm[6] = sinz*siny+cosz*sinx*cosy;
+    tm[7] = 0.0f;
+    tm[8] = cosx*siny;
+    tm[9] = -sinx;
+    tm[10] = cosx*cosy;
+    tm[11] = 0.0f;
+    tm[12] = 0.0f;
+    tm[13] = 0.0f;
+    tm[14] = 0.0f;
+    tm[15] = 1.0f;
+
+    applyMatrix(cz, tm, zd);
+    applyMatrix(cy, tm, yd);
+    applyMatrix(p, tm, xyz);
+
+    outerProduct(cx, cy, cz);
+    normalize(cx, cx);
+    normalize(cz, cz);
+    outerProduct(cy, cz, cx);
+
+    m_view[ 0] = cx[0];
+    m_view[ 1] = cy[0];
+    m_view[ 2] = cz[0];
+    m_view[ 3] = 0.0f;
+
+    m_view[ 4] = cx[1];
+    m_view[ 5] = cy[1];
+    m_view[ 6] = cz[1];
+    m_view[ 7] = 0.0f;
+
+    m_view[ 8] = cx[2];
+    m_view[ 9] = cy[2];
+    m_view[10] = cz[2];
+    m_view[11] = 0.0f;
+
+    m_view[12] = innerProduct(xyz, cx)*(-1);
+    m_view[13] = innerProduct(xyz, cy)*(-1);
+    m_view[14] = innerProduct(xyz, cz)*(-1);
+    m_view[15] = 1.0f;
+}
+
+void
+Camera::updatePerspective(float w, float h)
+{
+    float sx, sy, sz;
+    float aspect = w/h;
+
+    sy = (1.0f/tanf((fov/2.0f)*M_PI/180.0f));
+    sx = sy/aspect;
+    //sz = far/(far+near);
+    sz = far/(far-near);
+
+    m_pers[ 0] = sx;
+    m_pers[ 1] = 0.0f;
+    m_pers[ 2] = 0.0f;
+    m_pers[ 3] = 0.0f;
+
+    m_pers[ 4] = 0.0f;
+    m_pers[ 5] = sy;
+    m_pers[ 6] = 0.0f;
+    m_pers[ 7] = 0.0f;
+
+    m_pers[ 8] = 0.0f;
+    m_pers[ 9] = 0.0f;
+    m_pers[10] = sz;
+    m_pers[11] = 1.0f;
+
+    m_pers[12] = 0.0f;
+    m_pers[13] = 0.0f;
+    m_pers[14] = -near*sz;
+    m_pers[15] = 0.0f;
+}
+
+void
+Camera::updateScreen(float _w, float _h)
+{
+    float w = _w/2.0f;
+    float h = _h/2.0f;
+
+    m_screen[ 0] = w;
+    m_screen[ 1] = 0.0f;
+    m_screen[ 2] = 0.0f;
+    m_screen[ 3] = 0.0f;
+
+    m_screen[ 4] = 0.0f;
+    m_screen[ 5] = h;
+    m_screen[ 6] = 0.0f;
+    m_screen[ 7] = 0.0f;
+
+    m_screen[ 8] = 0.0f;
+    m_screen[ 9] = 0.0f;
+    m_screen[10] = 1.0f;
+    m_screen[11] = 0.0f;
+
+    m_screen[12] = w;
+    m_screen[13] = h;
+    m_screen[14] = 0.0f;
+    m_screen[15] = 1.0f;    
+}
+
+void
+Camera::setCamera(float *pose)
+{
+    //memcpy(xyz, &pose[12], sizeof(float)*4);
+}
+
+void
+Camera::update(float w, float h)
+{
+#if 1
+    float tmp[16];
+
+    updateView();
+    updatePerspective(w, h);
+    updateScreen(w, h);
+    
+    matrix4x4(tmp, this->m_pers, this->m_screen);
+    matrix4x4(this->matrix, this->m_view, tmp);
+#else
+    get_matrix(matrix, angle, xyz, NULL);
+#endif
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/Camera.h	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,33 @@
+#ifndef INCLUDED_CAMERA
+#define INCLUDED_CAMERA
+
+#ifndef INCLUDED_SCENE_GRAPH
+#  include "SceneGraph.h"
+#endif
+
+class Camera : public SceneGraph {
+public:
+    Camera(float w = 640, float h = 480);
+    ~Camera(void);
+
+    float zd[4]; // direction z
+    float yd[4]; // direction y
+    float fov;
+    float near;
+    float far;
+
+    float *m_view;
+    float *m_pers;
+    float *m_screen;
+
+    void updateView(void);
+    void updatePerspective(float w, float h);
+    void updateScreen(float w, float h);
+
+    void setCamera(float *pose);
+    void update(float screen_w, float screen_h);
+};
+
+typedef Camera *CameraPtr;
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/ChangeLog	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,396 @@
+2009-03-29  Wataru MIYAGUNI  <gongo@cr.ie.u-ryukyu.ac.jp>
+
+	* Makefile
+	SGlist.{cpp,h} を make clean で消去し、
+	make で自動生成するようにしました。
+	けどなんか他のファイルと同じ書きかたしても
+	上手く行かなかった。何か見落としてるかもしれない。誰か直(ry
+
+2009-02-12  Wataru MIYAGUNI  <gongo@cr.ie.u-ryukyu.ac.jp>
+
+	* task/CreatePolygonFromSceneGraph.cpp (CreatePolygonFromSceneGraph::run): fix
+	下にあわせる様に
+
+	* SceneGraph.cpp (SceneGraph::SceneGraph, SceneGraph::init)
+	(SceneGraph::finalize_original): fix
+	今まで、Polygon が持つ vertex, normal, texture coordinate ってのが
+
+	       ---------------------------------------
+	data = |   vertex   |   normal   |  texture  | sizeof(data) = size*3
+	       ---------------------------------------
+                \  size    / \   size   / \  size   /
+
+	てな感じで、SceneGraph->data の中に 3 つ入ってたわけです。
+	これだと、アクセスする時にどれがどれかわからんくなるし、
+	ソース読む時に迷う(経験談)ので、data を消して、代わりに
+	coord_xyz, normal, coord_tex を作りました。
+	
+	* polygon.cpp (Polygon::pickup_coordinate)
+	(Polygon::pickup_normal, Polygon::pickup_texture): 
+
+2009-02-10  Wataru MIYAGUNI  <gongo@cr.ie.u-ryukyu.ac.jp>
+
+	* Makefile.macosx (depend): fix
+	depend.inc とかを吐き出す様にしました
+
+	* Camera.cpp (Camera::Camera, Camera::updateView)
+	(Camera::updatePerspective, Camera::updateScreen)
+	(Camera::update): fix
+	なんとかカメラできてるっぽいです。
+	Perspective とかも聞いてるし、中心に向かって遠くなってる。
+	あとは行列演算をもうちょいこぎれいにすればいい感じかなー。
+
+	残りは、ユーザ側からの設定。例えば
+	1. 車の運転席目線(FPS)
+	2. 車の後ろから(TPS)
+	3. 車の前から(SPS)
+
+	的なのを、ユーザが CameraData みたいな構造体に
+	zd とか yd とかを設定して camera->set(data) とかやれば
+	反映するみたいな!みたいな!
+	
+2009-02-09  Wataru MIYAGUNI  <gongo@cr.ie.u-ryukyu.ac.jp>
+
+	* SceneGraphRoot.cpp (SceneGraphRoot::allExecute)
+	(SceneGraphRoot): fix
+	SceneGraph を root から走査していきながら
+	その都度コピーしていき、最終的に全体の新しい SceneGraph ができる。
+	削除されていればコピーしない、っていうのは簡単だけど
+	追加された場合、コピー元に追加されるのは困るので
+	コピーしたやつに追加って形にしたら今のコードになった。
+	めんどくさいっちゃめんどくさい。もっと綺麗な書き方あるかね
+
+
+2009-02-01  Wataru MIYAGUNI  <gongo@cr.ie.u-ryukyu.ac.jp>
+
+	* SceneGraph.cpp (SceneGraph::SceneGraph)
+	(SceneGraph::SceneGraph, SceneGraph::SceneGraph)
+	(SceneGraph::finalize_original, SceneGraph)
+	(SceneGraph::finalize_copy): add, fix
+	今のところ、SceneGraph の作られ方は
+
+	a1. xml ファイルから生成 (sgid 毎、sg_src[] に格納)
+	a2. ID を指定し、sg_src[id] の SceneGraph を複製
+	a3. xml も ID も指定しない、何も表示しない SceneGraph
+
+	a1 の時はポリゴンデータ(data[])を生成するわけだけど、
+	a2 でも、オリジナルと同じ data[] を持つ必要は(今は)ない。
+	なので、a2 の場合、data[] は a1 と同じ場所を指せば良い。
+	しかし、今までは、SceneGraph::~SceneGraph では
+	どんな SceneGraph でも
+
+	  delete [] data;
+
+	とかやってたので、それならということで
+
+	b1. a1 用の、Desturctor で data[] を delete する finalize_original()
+	b2. a2,a3 用の、data[] を削除しない finalize_copy()
+
+	を用意し、a1,a2,a3 の Consturoctor で、どっちかを設定する。
+
+2009-01-30  Wataru MIYAGUNI  <gongo@cr.ie.u-ryukyu.ac.jp>
+
+	* spe/DrawSpan.cpp (DrawSpan::drawDot1): add
+	span->length_x == 1 の処理。
+
+	(DrawSpan::drawDot2): add
+	Dot1 の続き。要は Dot1 で load して、Dot2 で wait->書き込みって感じ
+	しかし、1ドットだとそこまで待つ必要もないかなって感じなので
+	今は Dot 2には何も書いてない。ちゃんとしらべて、必要そうだったら
+	ここで書き込みを行う
+
+	(DrawSpan::drawLine1): add
+	span->length_x > 1 の処理。
+	いくつか Load パターンを考えてる途中
+
+	1. 全部 load
+	  1. z buf で描きこむと判断したとき、その pixel の texture tile を
+	     load する。(すでにある、ないに関わらず。ある場合は、実際には
+	     Load の処理は行われないが)
+	  2. Line2 で描画する(ここで使う tile はすでに全部読み込まれてるとする
+
+	2. 無い物だけload
+	  1. 書き込むと判断したとき、tile があるかどうかを調べ
+	     あればそのまま linebuf に、無ければ load を掛けて continue;
+	     このとき、load した(つまりまだ書き込まれてない) 場所を覚えておく
+	  2. Line2 で、1. で覚えた場所から再び計算して描画する。
+	     tile はすでに全部読み込まれているとする
+
+	まだあったけど忘れた。
+	今のところ描画領域が 256x8、もしくは512x8 で、
+	単純に考えて、領域pixel と texture pixel が一緒だと考えると
+	一個の Span で最大 64 (512/8) 個の tile があればいいと考えられる。
+	一個の SPE には Tile を 128 個持っておけるし、
+	今は Span を二つ平行して処理しているので、
+	途中で Tile が足りなくなる!ってことはないはず。
+	とまあ、いろいろ考えてたんだけど、何書けばいいのか忘れた。。
+	思い出したらまた書きます。
+
+2009-01-26  Wataru MIYAGUNI  <gongo@cr.ie.u-ryukyu.ac.jp>
+
+	* spe/CreateSpan.cpp (CreateSpan::run): fix
+	ポリゴンをx軸に水平に分割し、その二つを計算するってのが
+	half_triangelで、上としたで、何故か渡すテクスチャの情報が違う。
+	なんでだろうと思いつつも、今まで特に問題が出なかったから無視してたが、
+	今回、三つのSceneGraph を動かしてる時に問題発生。
+	それぞれ違うテクスチャを貼ってるのに、なぜかそれらのうちの半分が
+	別のテクスチャが貼られていた。簡単に言うと、A,B,C の SG があった。 
+
+	A: 正常
+	B: 右上だけ A のテクスチャ
+	C: 右上だけ A のテクスチャ
+
+	といった具合。わけがわからなかったんだが、
+	half_triangle に渡すやつの所為だと気づきました
+	なんでここだけ pp->tri[0].tex_info.addr とか渡してんのか未だに謎。
+	単なる書き間違いか直し間違いか。微妙なところ。
+	これ書いた後輩はもう居ない
+	
+
+	* SceneGraphIterator.cpp (SceneGraphIterator::hasNext)
+	(SceneGraphIterator::next): fix
+	検索する引数を int id に変更。
+	
+	* SceneGraph.h (class SceneGraph): add variable
+	int flag_drawbale : この SceneGraph は描画する物かどうか
+	int sgid : SceneGraph の ID 。ID は SGList.h にあるものを使う
+
+	* SceneGraphIterator.cpp : add file
+	SceneGraph を走査する用。
+	基本、Java の Iterator を参考にしてます。
+	追加機能としては
+
+	- hasNext(const char* name);
+	名前が name の SceneGraph があるかどうか
+
+	- next(const char* name);
+	名前が name の SceneGraph まで進ませる
+
+	* SceneGraphIterator.cpp : TODO
+	hasNext とかは名前じゃなくて ID が良いかなーとも思うけどね。
+	てかその方がいいな。あとで直します
+	
+	* ieshoot.cpp (ieboss_move): add
+	(ieboss_collision): add
+	BOSSの動きを追加。
+	IETAMA が数回衝突したら BOSS を消すって処理。
+
+	* SceneGraphIterator.cpp (SceneGraphIterator::next): fix
+	break してなかった。そりゃ取れないわ
+
+	* SceneGraph.cpp (SceneGraph::realRemoveFromTree): fix
+
+	< p1 = p1->next;
+	< p = p->next;
+	=====
+	> p1 = p1->brother;
+	> p = p->brother;
+	
+
+	* viewer.cpp (Viewer::run_draw): fix
+	Spanの無い部分を塗りつぶす処理はタスクを走らせず、
+	そのまま memset とかの方が早い。
+	まとめてするタスクを立ち上げるってのもいいかもしれない。
+	あと、memsetで指定する値が、0xFF と 0x00 とで速度が違う。
+	universe だと、
+
+	0xFF 24fps
+	0x00 30fps
+
+	なんだろう。0x00 だと、ただのクリアになるから速いってことかな。
+
+	* Camera.h (class Camera): add
+	とりあえず Camera を作って、これを SceneGraph の Top にした。
+
+	* SceneGraph.cpp (SceneGraph::realRemoveFromTree): add
+	realRemove() の Tree構造用。削除後の tree top を返す様にしている。
+	まあ top が消えなければ返す必要も無いし、top が消えるってことは
+	SceneGraph そのものが消えるってことでそうは無い・・はずだけどね。
+	(SceneGraph::realRemoveFromList): add
+	realRemove() の list用。削除後の list top を返す様にしている。
+	(SceneGraph::realRemoveFromTree): fix
+	< p->next = p1->next;
+	===
+	> p->brother = p1->brother;
+
+2009-01-25  Wataru MIYAGUNI  <gongo@cr.ie.u-ryukyu.ac.jp>
+
+	* add (tools/create_sglist): new
+	必要な SceneGraph xml file から SceneGraph を抽出し、
+	名前と対応する ID を SGList.h に出力する。
+	また、名前から ID を求める sglist_table を SGList.cpp に出力する。
+	
+	* SceneGraph.cpp (SceneGraph::remove): add
+	User API。ここで削除するのではなく、まずはフラグを立てるだけ
+	ここですぐに消すと、allExecute() の走査で何気に困る
+
+	(SceneGraph::isRemoved): add
+	この SceneGraph 削除フラグが立っているかどうか
+	
+	(SceneGraph::realRemove): TODO
+	子を持つ SceneGraph が消された場合、
+	その子孫を全て削除するかどうか。まあ削除するのかな。
+
+	(SceneGraph::realRemove): add
+	Cerium System で呼ばれる。
+	remove flag の立った SceneGraph を削除する。
+	parentやbrother、next は繋ぎ直す。
+
+	* SceneGraphRoot.cpp (SceneGraphRoot::addNext): add
+	sg_available_list に追加していく
+	木の操作が要らないアクセスの際にはこっちの方がいい。
+
+	(SceneGraphRoot::setSceneData): add
+	Cerium に SceneGraph の tree を渡す。Cerium はこの tree を辿って
+	処理を行う
+	
+	(SceneGraphRoot::createFromXMLfile): add
+	xml file を指定して、そこから SceneGraph を生成し、
+	sg_src に格納する。ユーザはこの SceneGraph を直接は扱えない。
+	以下に示す createSceneGraph の、読み込み元データとして保存しておく。
+	
+	(SceneGraphRoot::createSceneGraph): add
+	オリジナルの SceneGraph を clone してユーザに返す。
+	この SceneGraph をユーザが操作する。
+	
+	* SceneGraphRoot.h (class SceneGraphRoot): new variables
+	sg_src, sg_exec_list, sg_draw_list, sg_available_list
+
+	* addfile (SceneGraphRoot.cpp)
+	SceneGraph を管理するクラス、ってところか。
+	Root ってのは SceneGraph という名前からすると
+	一番親と思われそうで微妙です。変えるかも。
+
+2009-01-12  Wataru MIYAGUNI  <gongo@cr.ie.u-ryukyu.ac.jp>
+
+	* Joystick.cpp: TODO
+	使用している Joystick が
+
+	1. PS3 コントローラ
+	2. PS2 コントローラにUSB変換をかましたやつ
+
+	によってボタンの番号配置が違うので
+	そこを自動的に取得して割り振りたい
+
+	SDL_JoystickName() で名前取れるんだけど
+	全部共通なのかなー。「PS3って文字列があるか否か」でわけてもいいけど
+	
+	* Joystick.cpp: fix
+	コントローラボタンの番号を PS3 コントローラに合わせました。
+
+	- 参考
+	PS3 Linux SDLでプログラミング -コントローラを使う-
+	http://yun.cup.com/ps3sdl007.html
+
+	アナログスティックの方はまだです
+	
+2009-01-08  Wataru MIYAGUNI  <gongo@cr.ie.u-ryukyu.ac.jp>
+
+	* spe/DrawSpanRenew.cpp (DrawSpanRenew::run): fix
+	next_spack を free() していたが、do-while の最初で
+	next_spack = NULL とかやっている。
+	DrawSpan だと、free するのは free_spack ってやつなので
+	問題なかったが、なぜここは free(next_spack) とかやってるのか。
+	というわけで、next_spack,spack 両方用の
+	free_spack1, free_spack2 を生成して、これを free させることに。
+	これで、ようやくまともに動くようになった。けど微妙です。
+	遅いですね。
+
+	* addFile : DrawSpanRenew.cpp
+	DrawSpan の再起動 ver。
+
+2008-12-22  Wataru MIYAGUNI  <gongo@cr.ie.u-ryukyu.ac.jp>
+
+	* fix
+	charles を Fedora 10 に上げて、コンパイラが新しくなったせいか、
+	以下のような warning が出始めた
+
+	warning: deprecated conversion from string constant to 'char *'
+
+	まあよくわからんが、例えば
+
+	char *str = "hoge";
+
+	みたいな所だとこの warning が出る。これを
+
+	const char *str = "hoge";
+
+	にすると消えた。
+	以後こういう形に統一しろよ的なやつなのかな。
+
+2008-12-19  Wataru MIYAGUNI  <gongo@cr.ie.u-ryukyu.ac.jp>
+
+	* viewer.cpp (Viewer::run_draw): fix
+	startx, endx に対して、start_y, end_y って名前は統一されてなくて
+	わかりづらいので、starty, endy に変更
+
+	* main.cpp (init): fix
+	bpp (BitsPerPixel) の値がデフォルトで 0 になっていた。
+	今のレンダリング方式では 32 がデフォルトなので、間違ってた。
+	今まで気づかなかったのは
+
+	1. SDL_SetVideoMode に bpp = 0 で渡される
+	2. SDL が開発・実行環境に合わせて bpp を設定
+	3. 今までそれが 32 になってた
+
+	しかし、ゲーム班の環境では bpp = 16 になってしまったため、
+	その次の bitmap の allocate の時に 
+	screen->pitch*height = 16*width*height となり、
+	DrawSpan では 32 のつもりで書き込んでいたため領域外への
+	メモリ書き込み->エラー
+
+	ゲーム班ありがとう
+	
+2008-12-16  Wataru MIYAGUNI  <gongo@cr.ie.u-ryukyu.ac.jp>
+
+	* SceneGraph.cpp (makeTapestry): add
+	SceneGraph::get_data にあったけど、ごちゃごちゃしてたので
+	関数として生成
+
+	* viewer.cpp (Viewer::run_init, Viewer::run_draw): fix
+	* spe/DrawSpan.cpp (DrawSpan::zRow_init): delete
+
+	Z Buffering に使う zRow は DrawSpan で毎回生成、初期化するのではなく、
+	PPE で生成、初期化を行っておき、DrawSpan に add_inData で
+	DMA で渡すという方法に変更。速度的にはほんのちょっとしか(ry
+	
+	* spe/CreateSpan.cpp (CreateSpan::half_triangle): fix
+	getScale に渡す tex_width,tex_height を修正。
+	比較にそのまま tex_width, tex_height を使うと、
+	Span が持つテクスチャが全体の一部分だったとしても
+	比較結果で縮小が行われてしまうため。
+
+	- 例
+	span->length_x = 32;
+	tex_width = 128;
+	tex_x_len = (span->tex_x2 - span->tex_x1) = (0.5 - 0.3) = 0.2;
+
+	今までの処理だと、span->length_x < tex_width の結果により
+	縮小されたテクスチャを使うことになる。
+	しかし、実際に Span が使う Texture の長さは
+
+	  tex_width*tex_x_len = 24
+
+	なので、縮小を行う必要は無い
+	
+
+2008-12-12  Wataru MIYAGUNI  <gongo@cr.ie.u-ryukyu.ac.jp>
+
+	* SceneGraph.cpp (SceneGraph::get_data): Todo
+	テクスチャの縦横が 8 の倍数でなければ弾く処理を入れる。
+
+	* spe/DrawSpan.cpp (DrawSpan::run): Todo
+	テクスチャの座標計算と、そこから取得できる Tile の DMA を
+	一スレッドで処理しているのでそれを分けないといけない
+
+	* spe/CreateSpan.cpp (getTapestry): Add
+	(getScale): Add
+
+	* memo: 雑記
+	ようやくこいつに ChangeLog を加えました。
+	なんか emacs で「C-x 4 a」とかすると、ChangeLog の entry が
+	加えれられるんだけど、上の階層のを探しにいくので、TaskManager/ のに
+	加えようとしてたわけさ。まあそういう仕様なんだけど。
+	で、だからといって不可能ってわけじゃないから書けばよかったんだが。
+
+	要するに、これからはちゃんと書いていこうと思います。
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/Func.h	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,23 @@
+enum {
+     INIT,
+     SDL_INIT,
+     FINISH,
+     VIEWER_RUN_INIT,
+     VIEWER_RUN_LOOP,
+     VIEWER_RUN_DRAW,
+     VIEWER_RUN_FINISH,
+
+     TASK_INIT_TEXTURE, 
+     TASK_CREATE_SGP,
+     TASK_UPDATE_SGP,
+     TASK_CREATE_PP,
+     TASK_CREATE_PP2,
+     TASK_CREATE_SPAN,
+     TASK_CS_START,
+     TASK_CS_RUN,
+     TASK_DRAW_SPAN,
+     TASK_DRAW_SPAN2,
+     TASK_DRAW_BACK,
+     TASK_SET_TEXTURE,
+     TASK_DUMMY,
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/Joystick.cpp	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,178 @@
+#include <SDL.h>
+#include "Joystick.h"
+
+/**
+ * PS3 コントローラの配置
+ */
+static const int SELECT   = 0;
+static const int L3       = 1;
+static const int R3       = 2;
+static const int START    = 3;
+static const int UP       = 4;
+static const int RIGHT    = 5;
+static const int DOWN     = 6;
+static const int LEFT     = 7;
+static const int L2       = 8;
+static const int R2       = 9;
+static const int L1       = 10;
+static const int R1       = 11;
+static const int TRIANGLE = 12;
+static const int CIRCLE   = 13;
+static const int CROSS    = 14;
+static const int SQUARE   = 15;
+static const int PS       = 16;
+
+#if 0 // PS2 コントローラ
+static const int CROSS = 0;
+static const int CIRCLE = 1;
+static const int SQUARE = 2;
+static const int TRIANGLE = 3;
+static const int L1 = 4;
+static const int R1 = 5;
+static const int L2 = 6;
+static const int R2 = 7;
+static const int START = 8;
+static const int SELECT = 9;
+static const int L3 = 10;
+static const int R3 = 11;
+static const int UP = 12;
+static const int DOWN = 13;
+static const int RIGHT = 14;
+static const int LEFT = 15;
+static const int ESCAPE = 16;
+static const int SPACE = 17;
+#endif
+
+Joystick::Joystick(SDL_Joystick *j)
+{
+    joy = j;
+}
+
+Joystick::~Joystick(void)
+{
+    SDL_JoystickClose(joy);    
+}
+
+void
+Joystick::check(void)
+{
+    SDL_JoystickUpdate();
+
+    if (SDL_JoystickGetButton(joy,CROSS)==SDL_PRESSED) {
+	    cross.push_work();
+    } else {
+	cross.release_work();
+    }
+
+    if (SDL_JoystickGetButton(joy,CIRCLE)==SDL_PRESSED) {
+	circle.push_work();
+    } else {
+	circle.release_work();
+    }
+
+    if (SDL_JoystickGetButton(joy,SQUARE)==SDL_PRESSED) {
+	square.push_work();
+    } else {
+	square.release_work();
+    }
+
+    if (SDL_JoystickGetButton(joy,TRIANGLE)==SDL_PRESSED) {
+	triangle.push_work();
+    } else {
+	triangle.release_work();
+    }
+
+    if (SDL_JoystickGetButton(joy,L1)==SDL_PRESSED) {
+	l1.push_work();
+    } else {
+	l1.release_work();
+    }
+
+    if (SDL_JoystickGetButton(joy,R1)==SDL_PRESSED) {
+	r1.push_work();
+    } else {
+	r1.release_work();
+    }
+
+    if (SDL_JoystickGetButton(joy,L2)==SDL_PRESSED) {
+	l2.push_work();
+    } else {
+	l2.release_work();
+    }
+
+    if (SDL_JoystickGetButton(joy,R2)==SDL_PRESSED) {
+	r2.push_work();
+    } else {
+	r2.release_work();
+    }
+
+    if (SDL_JoystickGetButton(joy,START)==SDL_PRESSED) {
+	start.push_work();
+    } else {
+	start.release_work();
+    }
+
+    if (SDL_JoystickGetButton(joy,SELECT)==SDL_PRESSED) {
+	select.push_work();
+    } else {
+	select.release_work();
+    }
+
+    if (SDL_JoystickGetButton(joy,L3)==SDL_PRESSED) {
+	l3.push_work();
+    } else {
+	l3.release_work();
+    }
+
+    if (SDL_JoystickGetButton(joy,R3)==SDL_PRESSED) {
+	r3.push_work();
+    } else {
+	r3.release_work();
+    }
+
+    if (SDL_JoystickGetButton(joy,UP)==SDL_PRESSED) {
+	up.push_work();
+    } else {
+	up.release_work();
+    }
+
+    if (SDL_JoystickGetButton(joy,DOWN)==SDL_PRESSED) {
+	down.push_work();
+    } else {
+	down.release_work();
+    }
+    if (SDL_JoystickGetButton(joy,RIGHT)==SDL_PRESSED) {
+	right.push_work();
+    } else {
+	right.release_work();
+    }
+    if (SDL_JoystickGetButton(joy,LEFT)==SDL_PRESSED) {
+	left.push_work();
+    } else {
+	left.release_work();
+    }
+
+    axis = SDL_JoystickGetAxis(joy,0);
+    if (axis >= 3200) {
+	left.release_work();
+	right.push_work();
+    } else if (axis <= -3200) {
+	right.release_work();
+	left.push_work();
+    } else {
+	left.release_work();
+	right.release_work();
+    }
+
+    axis = SDL_JoystickGetAxis(joy,1);
+    if (axis>=3200) {
+	up.release_work();
+	down.push_work();
+    } else if (axis<=-3200) {
+	down.release_work();
+	up.push_work();
+    } else {
+	up.release_work();
+	down.release_work();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/Joystick.h	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,21 @@
+#ifndef INCLUDED_JOYSTICK
+#define INCLUDED_JOYSTICK
+
+#include "SDL.h"
+
+#ifndef INCLUDED_PAD
+#  include "Pad.h"
+#endif
+
+class Joystick : public Pad {
+public:
+    SDL_Joystick *joy;
+    Sint16 axis;
+
+    Joystick(SDL_Joystick *j);
+    ~Joystick(void);
+
+    void check(void);
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/Keyboard.cpp	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,92 @@
+#include <SDL.h>
+#include "Keyboard.h"
+
+void
+Keyboard::check(void)
+{
+    Uint8 *keys = SDL_GetKeyState(NULL);
+
+    if (keys[SDLK_UP] == SDL_PRESSED) {
+	up.push_work();
+    } else {
+	up.release_work();
+    }
+
+    if (keys[SDLK_DOWN] == SDL_PRESSED) {
+	down.push_work();
+    } else {
+	down.release_work();
+    }
+
+    if (keys[SDLK_RIGHT] == SDL_PRESSED) {
+	right.push_work();
+    } else {
+	right.release_work();
+    }
+
+    if (keys[SDLK_LEFT] == SDL_PRESSED) {
+	left.push_work();
+    } else {
+	left.release_work();
+    }
+
+    if (keys[SDLK_RETURN] == SDL_PRESSED) {
+	start.push_work();
+    } else {
+	start.release_work();
+    }
+
+    if (keys[SDLK_ESCAPE] == SDL_PRESSED) {
+	select.push_work();
+    } else {
+	select.release_work();
+    }
+
+    if (keys[SDLK_a] == SDL_PRESSED) {
+	square.push_work();
+    } else {
+	square.release_work();
+    }
+
+    if (keys[SDLK_s] == SDL_PRESSED) {
+	triangle.push_work();
+    } else {
+	triangle.release_work();
+    }
+
+    if (keys[SDLK_z] == SDL_PRESSED) {
+	cross.push_work();
+    } else {
+	cross.release_work();
+    }
+
+    if (keys[SDLK_x] == SDL_PRESSED) {
+	circle.push_work();
+    } else {
+	circle.release_work();
+    }
+
+    if (keys[SDLK_k] == SDL_PRESSED) {
+	l1.push_work();
+    } else {
+	l1.release_work();
+    }
+
+    if (keys[SDLK_o] == SDL_PRESSED) {
+	l2.push_work();
+    } else {
+	l2.release_work();
+    }
+
+    if (keys[SDLK_l] == SDL_PRESSED) {
+	r1.push_work();
+    } else {
+	r1.release_work();
+    }
+
+    if (keys[SDLK_p] == SDL_PRESSED) {
+	r2.push_work();
+    } else {
+	r2.release_work();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/Keyboard.h	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,13 @@
+#ifndef INCLUDED_KEYBOARD
+#define INCLUDED_KEYBOARD
+
+#ifndef INCLUDED_PAD
+#  include "Pad.h"
+#endif
+
+class Keyboard : public Pad {
+public:
+    void check(void);
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/Makefile	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,30 @@
+default: macosx
+
+macosx: FORCE
+	@echo "Make for Mac OS X"
+	@$(MAKE) -f Makefile.macosx
+
+ps3: FORCE
+	@echo "Make for PS3 (Cell)"
+	@$(MAKE) -f Makefile.ps3
+
+linux: FORCE
+	@echo "Make for Linux"
+	@$(MAKE) -f Makefile.linux
+
+macosx-depend: FORCE
+	@$(MAKE) -f Makefile.macosx depend
+
+ps3-depend: FORCE
+	@$(MAKE) -f Makefile.ps3 depend
+
+linux-depend: FORCE
+	@$(MAKE) -f Makefile.linux depend
+
+FORCE:
+
+clean:
+	@$(MAKE) -f Makefile.macosx clean
+	@$(MAKE) -f Makefile.ps3 clean
+	@$(MAKE) -f Makefile.linux clean
+	rm -f depend.inc
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/Makefile.def	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,9 @@
+TARGET = test_nogl
+
+CERIUM = ../../../Cerium
+
+CC      = g++
+CFLAGS  = -O9 -g -Wall# -DDEBUG
+
+INCLUDE = -I$(CERIUM)/include/TaskManager -I.
+LIBS = -L$(CERIUM)/TaskManager
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/Makefile.linux	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,52 @@
+include ./Makefile.def
+
+SRCS_TMP = $(wildcard *.cpp)
+SRCS_EXCLUDE =   # 
+SRCS = $(filter-out $(SRCS_EXCLUDE),$(SRCS_TMP))
+OBJS = $(SRCS:.cpp=.o)
+
+TASK_DIR  = task
+TASK_SRCS_TMP = $(wildcard $(TASK_DIR)/*.cpp)
+TASK_SRCS_EXCLUDE = span_pack_draw.cpp
+TASK_SRCS = $(filter-out $(TASK_SRCS_EXCLUDE),$(TASK_SRCS_TMP))
+TASK_OBJS = $(TASK_SRCS:.cpp=.o)
+
+LIBS += -lFifoManager
+
+CFLAGS += `sdl-config --cflags` `xml2-config --cflags`
+LIBS   += `sdl-config --libs` -lSDL_image -lGL `xml2-config --libs`
+
+.SUFFIXES: .cpp .o
+
+.cpp.o:
+	$(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@
+
+all: $(TARGET)
+
+$(TARGET): SGList.o $(OBJS) $(TASK_OBJS)
+	$(CC) -o $@ $(OBJS) $(TASK_OBJS) SGList.o $(LIBS)
+
+SGList.o: create_sg_list
+	$(CC) $(CFLAGS) $(INCLUDE) -c SGList.cpp -o $@
+
+create_sg_list:
+	@if [ ! -f SGList.h ]; then \
+		cd tools/;\
+		./create_sglist.pl ../xml_file/*.xml;\
+		cd ../;\
+	fi
+
+run: $(TARGET)
+	sudo ./$(TARGET) -width 576 -height 384 -bpp 32
+
+debug: $(TARGET)
+	sudo ppu-gdb ./$(TARGET) 
+
+depend:
+	$(RM) depend.inc
+	$(CC) -MM -MG $(INCLUDE) $(CFLAGS) $(SRCS) $(TASK_SRCS) > depend.inc
+
+clean:
+	rm -f $(TARGET) $(OBJS) $(TASK_OBJS)
+	rm -f *~ \#*
+	rm -f SGList.h SGList.cpp
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/Makefile.macosx	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,55 @@
+include ./Makefile.def
+
+SRCS_TMP = $(wildcard *.cpp)
+SRCS_EXCLUDE =  # 
+SRCS = $(filter-out $(SRCS_EXCLUDE),$(SRCS_TMP))
+OBJS = $(SRCS:.cpp=.o)
+
+TASK_DIR  = task
+TASK_SRCS_TMP = $(wildcard $(TASK_DIR)/*.cpp)
+TASK_SRCS_EXCLUDE = span_pack_draw.cpp
+TASK_SRCS = $(filter-out $(TASK_SRCS_EXCLUDE),$(TASK_SRCS_TMP))
+TASK_OBJS = $(TASK_SRCS:.cpp=.o)
+
+LIBS += -lFifoManager
+
+CFLAGS += `sdl-config --cflags` `xml2-config --cflags`
+LIBS   += `sdl-config --libs` `xml2-config --libs` -lSDL_image -Wl,-framework,OpenGL
+
+.SUFFIXES: .cpp .o
+
+.cpp.o:
+	$(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@
+
+all: $(TARGET)
+
+$(TARGET): SGList.o $(OBJS) $(TASK_OBJS)
+	$(CC) -o $@ SGList.o $(OBJS) $(TASK_OBJS) $(LIBS)
+
+
+SGList.o: create_sg_list
+	$(CC) $(CFLAGS) $(INCLUDE) -c SGList.cpp -o $@
+
+create_sg_list:
+	@if [ ! -f SGList.h ]; then \
+		cd tools/;\
+		./create_sglist.pl ../xml_file/*.xml;\
+	fi
+
+
+run: $(TARGET)
+	sudo ./$(TARGET) -width 576 -height 384 -bpp 32
+
+debug: $(TARGET)
+	sudo ppu-gdb ./$(TARGET) 
+
+depend:
+	$(RM) depend.inc
+	$(CC) -MM -MG $(INCLUDE) $(CFLAGS) $(SRCS) $(TASK_SRCS) > depend.inc
+
+clean:
+	rm -f $(TARGET) $(OBJS) $(TASK_OBJS)
+	rm -f *~ \#*
+	rm -f SGList.h SGList.cpp
+
+-include depend.inc
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/Makefile.ps3	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,58 @@
+include ./Makefile.def
+
+SRCS_TMP = $(wildcard *.cpp)
+SRCS_EXCLUDE =   # 
+SRCS = $(filter-out $(SRCS_EXCLUDE),$(SRCS_TMP))
+OBJS = $(SRCS:.cpp=.o)
+
+TASK_DIR  = task
+TASK_SRCS_TMP = $(wildcard $(TASK_DIR)/*.cpp)
+TASK_SRCS_EXCLUDE = span_pack_draw.cpp
+TASK_SRCS = $(filter-out $(TASK_SRCS_EXCLUDE),$(TASK_SRCS_TMP))
+TASK_OBJS = $(TASK_SRCS:.cpp=.o)
+
+LIBS += -lCellManager -lspe2 -lpthread
+
+CFLAGS += `sdl-config --cflags` `xml2-config --cflags`
+LIBS   += `sdl-config --libs` -lSDL_image -lGL `xml2-config --libs`
+
+.SUFFIXES: .cpp .o
+
+.cpp.o:
+	$(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@
+
+default: all
+
+all: $(TARGET) speobject
+
+$(TARGET): SGList.o $(OBJS) $(TASK_OBJS)
+	$(CC) -o $@ SGList.o $(OBJS) $(TASK_OBJS) $(LIBS)
+
+SGList.o: create_sg_list
+	$(CC) $(CFLAGS) $(INCLUDE) -c SGList.cpp -o $@
+
+create_sg_list:
+	@if [ ! -f SGList.h ]; then \
+		cd tools/;\
+		./create_sglist.pl ../xml_file/*.xml;\
+	fi
+
+speobject:
+	cd spe; $(MAKE)
+
+run: $(TARGET)
+	sudo ./$(TARGET) -width 576 -height 384 -bpp 32
+
+debug: $(TARGET)
+	sudo ppu-gdb ./$(TARGET) 
+
+depend:
+	$(RM) depend.inc
+	$(CC) -MM -MG $(INCLUDE) $(CFLAGS) $(SRCS) $(TASK_SRCS) > depend.inc
+
+clean:
+	rm -f $(TARGET) $(OBJS) $(TASK_OBJS)
+	rm -f *~ \#*
+	rm -f SGList.h SGList.cpp
+	cd task; rm -f *~ \#*
+	cd spe; $(MAKE) clean
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/Pad.cpp	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,26 @@
+#include <stdio.h>
+#include "Keyboard.h"
+#include "Joystick.h"
+
+/**
+ * Joystick があればそれを使い、
+ * 無ければキーボードを返す
+ */
+Pad*
+create_controller(void)
+{
+    if (SDL_NumJoysticks()) {
+	SDL_Joystick *joy = SDL_JoystickOpen(0);
+	if (!joy) {
+	    printf("%s: failed to open joystick", __FUNCTION__);
+	    printf("Instead use Keyboard\n");
+	    return new Keyboard;
+	} else {
+	    printf("Use Joystick\n");
+	    return new Joystick(joy);
+	}
+    } else {
+	printf("Use Keyboard\n");
+	return new Keyboard;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/Pad.h	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,36 @@
+#ifndef INCLUDED_PAD
+#define INCLUDED_PAD
+
+#ifndef INCLUDED_BUTTON
+#  include "Button.h"
+#endif
+
+class Pad {
+public:
+    Button count;
+    Button cross;
+    Button circle;
+    Button square;
+    Button triangle;
+    Button l1;
+    Button r1;
+    Button l2;
+    Button r2;
+    Button start;
+    Button select;
+    Button l3;
+    Button r3;
+    Button up;
+    Button down;
+    Button right;
+    Button left;
+    Button escape;
+    Button space;
+
+    virtual ~Pad(void) {}
+    virtual void check(void) = 0;
+};
+
+#endif
+
+extern Pad *create_controller(void);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/SGList.cpp	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,5 @@
+#include "SGList.h"
+
+const char *sglist_table[SGLIST_LENGTH] = {
+    "Ball", "LongCube", "Venus000", "Venus001", "Venus002", "Venus008", "Venus003", "Venus007", "Venus006", "Venus004", "Venus005", "Venus009", "BLAST8", "BLAST7", "BLAST6", "BLAST5", "BLAST4", "BLAST3", "BLAST2", "BLAST1", "BOSS1", "BOSS1_L", "BOSS1_R", "Cube", "BigCube", "Plane", "SmallCube", "Diry", "Dirz", "Dirx", "IEBOSS", "IEJIKI", "IETAMA", "MCUBE_BACK", "MCUBE", "BIGMCUBE", "CUBE", "P_SHOT1", "PANEL_1024", "PANEL_2048", "PANEL_512", "PLAYER", "PLAYER_L", "PLAYER_LL", "PLAYER_R", "PLAYER_RR", "Sphere", "BigSphere", "Earth", "Moon"
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/SGList.h	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,102 @@
+#ifndef INCLUDED_SGLIST
+#define INCLUDED_SGLIST
+
+/* ../xml_file/Ball.xml */
+#define Ball	 0
+
+/* ../xml_file/LongCube.xml */
+#define LongCube	 1
+
+/* ../xml_file/Venus.xml */
+#define Venus000	 2
+#define Venus001	 3
+#define Venus002	 4
+#define Venus008	 5
+#define Venus003	 6
+#define Venus007	 7
+#define Venus006	 8
+#define Venus004	 9
+#define Venus005	 10
+#define Venus009	 11
+
+/* ../xml_file/blast.xml */
+#define BLAST8	 12
+#define BLAST7	 13
+#define BLAST6	 14
+#define BLAST5	 15
+#define BLAST4	 16
+#define BLAST3	 17
+#define BLAST2	 18
+#define BLAST1	 19
+
+/* ../xml_file/boss1.xml */
+#define BOSS1	 20
+#define BOSS1_L	 21
+#define BOSS1_R	 22
+
+/* ../xml_file/cube.xml */
+#define Cube	 23
+
+/* ../xml_file/cube_big.xml */
+#define BigCube	 24
+
+/* ../xml_file/cube_split.xml */
+#define Plane	 25
+#define SmallCube	 26
+
+/* ../xml_file/direction.xml */
+#define Diry	 27
+#define Dirz	 28
+#define Dirx	 29
+
+/* ../xml_file/ieboss.xml */
+#define IEBOSS	 30
+
+/* ../xml_file/iejiki.xml */
+#define IEJIKI	 31
+
+/* ../xml_file/ietama.xml */
+#define IETAMA	 32
+
+/* ../xml_file/mcube.xml */
+#define MCUBE_BACK	 33
+#define MCUBE	 34
+#define BIGMCUBE	 35
+#define CUBE	 36
+
+/* ../xml_file/p_shot.xml */
+#define P_SHOT1	 37
+
+/* ../xml_file/panel_1024.xml */
+#define PANEL_1024	 38
+
+/* ../xml_file/panel_2048.xml */
+#define PANEL_2048	 39
+
+/* ../xml_file/panel_512.xml */
+#define PANEL_512	 40
+
+/* ../xml_file/player.xml */
+#define PLAYER	 41
+#define PLAYER_L	 42
+#define PLAYER_LL	 43
+#define PLAYER_R	 44
+#define PLAYER_RR	 45
+
+/* ../xml_file/sphere.xml */
+#define Sphere	 46
+
+/* ../xml_file/sphere_big.xml */
+#define BigSphere	 47
+
+/* ../xml_file/universe.xml */
+#define Earth	 48
+#define Moon	 49
+
+/* Number of Scene */
+#define SGLIST_LENGTH 50
+
+/* Scene Table */
+extern const char *sglist_table[SGLIST_LENGTH];
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/SceneGraph.cpp	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,900 @@
+#include <iostream>
+#include <SDL.h>
+#include <SDL_opengl.h>
+#include <SDL_image.h>
+#include <libxml/parser.h>
+#include "SceneGraph.h"
+#include "xml.h"
+#include "sys.h"
+#include "TextureHash.h"
+#include "texture.h"
+#include "TaskManager.h"
+
+using namespace std;
+
+SceneGraphPtr scene_graph = NULL;
+SceneGraphPtr scene_graph_viewer = NULL;
+
+static TextureHash texture_hash;
+struct texture_list list[TABLE_SIZE];
+
+// TextureHash.cpp
+extern int id_count;
+
+extern int decode(char *cont, FILE *outfile);
+
+static void
+no_move(SceneGraphPtr self, int screen_w, int screen_h) {}
+
+static void
+no_collision(SceneGraphPtr self, int screen_w, int screen_h,
+	     SceneGraphPtr tree) {}
+
+/**
+ * 事前に計算したテクスチャの最大縮小率 scale まで、
+ * テクスチャを 1/2 縮小していく。
+ * このとき、テクスチャは TEXTURE_SPLIT_PIXELx2 のブロック (Tile) で分割し、
+ * これらを連続したメモリ領域に格納していく。
+ * 以下の (1), (2), (3) を Tapestry と呼ぶ
+ *
+ * 例 scale = 4 の場合
+ *
+ *   Tapestry(1) 1/1
+ * +---+---+---+---+
+ * | 0 | 1 | 2 | 3 |
+ * +---+---+---+---+
+ * | 4 | 5 | 6 | 7 |   (2) 1/2
+ * +---+---+---+---+  +---+---+
+ * | 8 | 9 | 10| 11|  | 16| 17|   (3) 1/4
+ * +---+---+---+---+  +---+---+  +---+
+ * | 12| 13| 14| 15|  | 18| 19|  | 20|
+ * +---+---+---+---+  +---+---+  +---|
+ *
+ * (1)                                                 (2)             (3)
+ *  +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
+ *  | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * | * | * | 14| 15| 16| 17| 18| 19| 20|
+ *  +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
+ *
+ * @param[in] tex_w         Width of orignal texture
+ * @param[in] tex_h         Height of orignal texture
+ * @param[in] tex_src       Original texture
+ * @param[in] all_pixel_num Tapestry の合計 pixel 数
+ * @param[in] scale         テクスチャの最大縮小率 (= 2^n)
+ * @return (1) のアドレス
+ */
+static uint32*
+makeTapestry(int tex_w, int tex_h, uint32 *tex_src,
+	     int all_pixel_num, int scale_cnt)
+{
+    uint32 *tex_dest;
+
+    int t = 0;
+    int diff = TEXTURE_SPLIT_PIXEL;
+    int p_diff = 1;
+	
+    tex_dest = (uint32*)manager->allocate(sizeof(int)*all_pixel_num);
+
+    while (scale_cnt) {
+	for (int y = 0; y < tex_h; y += diff) {
+	    for (int x = 0; x < tex_w; x += diff) {
+		for (int j = 0; j < diff; j += p_diff) {
+		    for (int i = 0; i < diff; i += p_diff) {
+			tex_dest[t++]
+			    = tex_src[(x+i) + tex_w*(y+j)];
+		    }
+		}
+	    }
+	}
+			
+	diff <<= 1;
+	p_diff <<= 1;
+	scale_cnt >>= 1;
+    }
+    
+    return tex_dest;
+}
+
+
+/**
+ * 何の情報も持ってない SceneGraph の生成
+ * 今のところ、とりあえず木構造の繋がりに使うぐらい
+ */
+SceneGraph::SceneGraph(void)
+{
+    init();
+    finalize = &SceneGraph::finalize_copy;
+
+    this->name = "NULLPO";
+}
+
+/**
+ * orig のコピーとして SceneGraph を生成する
+ */
+SceneGraph::SceneGraph(SceneGraphPtr orig)
+{
+    init();
+    memcpy(this, orig, sizeof(SceneGraph));
+
+    // コピーしない
+    //flag_remove = 0;
+    //flag_drawable = 1;
+    next = NULL;
+    prev = NULL;
+    last = NULL;
+
+    parent = NULL;
+    brother = NULL;
+    children = NULL;
+    lastChild = NULL;
+
+    finalize = &SceneGraph::finalize_copy;
+
+
+    frame = 0;    
+}
+
+
+/* construct polygon from xmlNode.  */
+SceneGraph::SceneGraph(xmlNodePtr surface)
+{
+    init();
+
+    size = atoi((char *)xmlGetProp(surface,(xmlChar *)"size"));
+    name = (char *)xmlGetProp(surface,(xmlChar *)"name");
+    parent_name = (char *)xmlGetProp(surface,(xmlChar *)"parent");
+
+    //data = new float[size*3*3];
+    coord_xyz = (float*)manager->allocate(sizeof(float)*size*3);
+    coord_tex = (float*)manager->allocate(sizeof(float)*size*3);
+    normal    = (float*)manager->allocate(sizeof(float)*size*3);
+
+    get_data(surface->children);
+
+    finalize = &SceneGraph::finalize_original;
+}
+
+void
+SceneGraph::init(void)
+{
+    next = NULL;
+    prev = NULL;
+    last = NULL;
+
+    parent = NULL;
+    brother = NULL;
+    children = NULL;
+    lastChild = NULL;
+
+    stack_xyz[0] = 0.0f;
+    stack_xyz[2] = 0.0f;
+    stack_xyz[1] = 0.0f;
+    stack_angle[0] = 0.0f;
+    stack_angle[1] = 0.0f;
+    stack_angle[2] = 0.0f;
+
+    size = 0;
+    //data = NULL;
+    coord_xyz = NULL;
+    normal = NULL;
+    coord_tex = NULL;
+
+    texture_id = -1;
+    move = no_move;
+    collision = no_collision;
+
+    flag_remove = 0;
+    flag_drawable = 1;
+    sgid = -1;
+
+    frame = 0;
+}
+
+SceneGraph::~SceneGraph(void)
+{
+    (this->*finalize)();
+}
+
+/**
+ * xml ファイルから生成されたオリジナル SceneGraph なので
+ * polygon data を削除
+ */
+void
+SceneGraph::finalize_original(void)
+{
+    //delete [] data;
+    free(coord_xyz);
+    free(coord_tex);
+    free(normal);
+}
+
+/**
+ * SceneGraph ID から生成された、コピー SceneGraph なので
+ * polygon data は削除しない。オリジナルの方で削除する。
+ */
+void
+SceneGraph::finalize_copy(void)
+{
+}
+
+/* XMLファイルからポリゴンを作成  */
+void
+SceneGraph::createFromXMLfile(const char *xmlfile)
+{
+    xmlDocPtr doc;
+    xmlNodePtr cur;
+    SceneGraphPtr root = NULL, tmp = NULL, parent;
+    
+    /* パース DOM生成 */
+    doc = xmlParseFile(xmlfile);
+    cur = xmlDocGetRootElement(doc);
+
+    /* ??  */
+    xmlStrcmp(cur->name,(xmlChar*)"OBJECT-3D");
+
+    /* XMLのノードを一つずつ解析  */
+    for (cur=cur->children; cur; cur=cur->next) {
+	/* 扱うのはsurfaceオンリー  */
+	//if (xmlStrcmp(cur->name,(xmlChar*)"surface") != 0) {
+	//    continue;
+	//}
+      if (!xmlStrcmp(cur->name,(xmlChar*)"surface")) {
+	/* ポリゴン(SceneGraph)生成  */
+	tmp = new SceneGraph(cur);
+	if ( tmp->parent_name==NULL || 0==strcmp(tmp->parent_name, "NULL")) {
+	    /* このsurfaceがroot  */
+	    root = tmp;
+	    scene_graph = tmp;
+	} else {
+	    /* 親はこのsurfaceより前に定義されているものとする (していい?)  */
+	    //  ここで parent_name を用いるのは間違っていて、
+	    //   *cur->properties->children から探すべきらしい kono
+	    parent = root->searchSceneGraph(tmp->parent_name);
+	    if (parent==NULL) {
+		fprintf(stderr, "[%s] No such parent %s\n",
+			tmp->name, tmp->parent_name);
+		root->addChild(tmp);
+	    } else {
+		parent->addChild(tmp);
+	    }
+
+	    scene_graph->add_next(tmp);
+	}
+      }else if (!xmlStrcmp(cur->name,(xmlChar*)"image")) {
+	
+	char *cont;
+	char image_name[20] = "/tmp/image_XXXXXX";
+	char *filename = (char *)xmlGetProp(cur, (xmlChar *)"name");
+	int fd = mkstemp(image_name);
+	FILE *outfile = fdopen(fd, "wb");
+	if(NULL == outfile)
+	  {
+	    cout << "error open file\n";
+	  }
+	cont = (char *)xmlNodeGetContent(cur);
+	decode(cont, outfile);
+	fclose(outfile);
+		
+	int tex_id = texture_hash.hash_regist(filename);
+	if (tex_id < 0) 
+	  {
+	    
+	    texture_image = IMG_Load(image_name);
+	    
+	    /**
+	     * image を 32bit(RGBA) に変換する
+	     */
+	    
+	    SDL_Surface *tmpImage
+	      = SDL_CreateRGBSurface(SDL_HWSURFACE, texture_image->w,
+				     texture_image->h, 32, redMask,
+				     greenMask, blueMask, alphaMask);
+	    SDL_Surface *converted;
+	    converted = SDL_ConvertSurface(texture_image, tmpImage->format,
+					   SDL_HWSURFACE);
+	    if (converted != NULL) {
+	      SDL_FreeSurface(texture_image);
+	      texture_image = converted;
+	    }
+	    
+	    uint32 *tapestry;
+	    int scale = 1;
+	    int tex_w = texture_image->w;
+	    int tex_h = texture_image->h;
+	    int all_pixel_num = 0;
+	    
+	    /**
+	     * テクスチャの w or h が 8 pixel で分割できる間、
+	     * 1/2 の縮小画像を作る。
+	     * ここでは、最大の scale (1/scale) を見つける
+	     *
+	     * (ex)
+	     *  (128,128) => 64,64 : 32,32: 16,16 : 8,8
+	     *     scale = 16
+	     *  (128, 64) => 64,32 : 32,16: 16,8
+	     *     scale = 8
+	     */
+	    
+	    while (tex_w % TEXTURE_SPLIT_PIXEL == 0 &&
+		   tex_h % TEXTURE_SPLIT_PIXEL == 0) {
+	      all_pixel_num += tex_w*tex_h;
+	      tex_w >>= 1; /* tex_w /= 2 */
+	      
+	      tex_h >>= 1;
+	      scale <<= 1; /* scale *= 2 */
+	      
+	    }
+	    
+	    scale >>= 1;
+	    
+	    tapestry = makeTapestry(texture_image->w, texture_image->h,
+				    (uint32*)texture_image->pixels,
+				    all_pixel_num,
+				    scale);
+	    
+	    list[id_count-1].t_w = texture_image->w;
+	    list[id_count-1].t_h = texture_image->h;
+	    list[id_count-1].pixels_orig = (Uint32*)texture_image->pixels;
+	    list[id_count-1].pixels = tapestry;
+	    list[id_count-1].scale_max = scale;
+	    
+	    tmp->texture_id = id_count-1;
+	    tmp->texture_info.t_w = texture_image->w;
+	    tmp->texture_info.t_h = texture_image->h;
+	    tmp->texture_info.pixels_orig = (Uint32*)texture_image->pixels;
+	    tmp->texture_info.pixels = tapestry;
+	    tmp->texture_info.scale_max = scale;
+
+	    if (unlink(image_name))
+	      {
+		cout << "unlink error\n";
+	      }
+	    
+	  } else {
+	  /**
+	   * 以前に Load されている Texture を共用
+	   */
+	  
+	  tmp->texture_id = tex_id;
+	  
+	  // こんなことすると list[] のいみあるのかなーと
+	  // 微妙に思う、自分で書き換えた感想 by gongo
+	  
+	  tmp->texture_info.t_w = list[tex_id].t_w;
+	  tmp->texture_info.t_h = list[tex_id].t_h;;
+	  tmp->texture_info.pixels_orig = list[tex_id].pixels_orig;
+	  tmp->texture_info.pixels = list[tex_id].pixels;
+	  tmp->texture_info.scale_max = list[tex_id].scale_max;
+	  
+	}
+      }else {
+	continue;
+      }
+    }
+  
+    xmlFreeDoc(doc);
+
+    //return root;
+    scene_graph_viewer = root;
+}
+
+
+/**
+ * add Children
+ * 親の登録と、brother のリストへ加える
+ *
+ * @param child new child
+ */
+SceneGraphPtr
+SceneGraph::addChild(SceneGraphPtr child)
+{
+    /* childrenのリストの最後に加える (brother として)*/
+    if (this->lastChild != NULL) {
+	SceneGraphPtr last = this->lastChild;
+	last->brother = child;
+    }
+
+    this->lastChild = child;
+
+    if (this->children == NULL) {
+	this->children = child;
+    }
+
+    child->parent = this;
+
+    return child;
+}
+
+
+/**
+ * add Brother
+ * addChild() でも brother の操作をしないといけないので、そっちに回す
+ *
+ * @param bro new Brother
+ */
+SceneGraphPtr
+SceneGraph::addBrother(SceneGraphPtr bro)
+{
+    if (this->parent) {
+	parent->addChild(bro);
+    } else {
+	fprintf(stderr, "error : SceneGraph::%s : %s doesn't have parent\n",
+		__FUNCTION__, this->name);
+    }
+
+    return bro;
+}
+
+/* thisの子や子孫にnameのものが存在すればそいつを返す なければNULL.  */
+SceneGraphPtr
+SceneGraph::searchSceneGraph(const char *name)
+{
+    SceneGraphPtr tmp;
+    SceneGraphPtr result;
+
+    /* 本人か  */
+    if( 0==strcmp(this->name, name) ) return this;
+
+    /* 子供から再帰的に探す  */
+    for(tmp = this->children; tmp; tmp = tmp->next) {
+	if ((result=tmp->searchSceneGraph(name)) != NULL)
+	    return result;
+    }
+
+    /* 無かったら NULL.  */
+    return NULL;
+}
+
+void
+SceneGraph::tree_check(void)
+{
+    SceneGraphPtr t = this;
+
+    while(t)
+    {
+	cout << "my_name : " << t->name << endl;
+	if(t->children != NULL)
+	{
+	    cout << "--move children : " << t->children->name << endl;
+	    t = t->children;
+	}
+	else if(t->brother != NULL)
+	{
+	    cout << "--move brother : " << t->brother->name << endl;
+	    t = t->brother;
+	}
+	else
+	{
+	    while(t)
+	    {
+		if(t->brother != NULL)
+		{
+		    cout << "--move brother : " << t->brother->name << endl;
+		    t = t->brother;
+		    break;
+		}
+		else
+		{
+		    if(t->parent)
+		    {
+			cout << "--move parent : " << t->parent->name << endl;
+		    }
+		    t = t->parent;
+		}
+	    }
+	}
+    }
+}
+
+
+void
+SceneGraph::print_member(void)
+{
+    cout << "size = " << size << endl;
+    cout << "name = " << name << endl;
+    cout << "parent_name = " << parent_name << endl;
+
+    if (parent != NULL) {
+	cout << "parent->name = " << parent->name << endl;
+    }
+
+    if (children != NULL) {
+	cout << "children->name = " << children->name << endl;
+    }
+}
+
+
+/*
+ * surface nodeからポリゴンの情報を読み出す 再帰しない
+ */
+void
+SceneGraph::get_data(xmlNodePtr cur)
+{
+    char *cont;
+    //char *image_name;
+
+    for(;cur;cur=cur->next)
+    {
+	if(!xmlStrcmp(cur->name,(xmlChar*)"coordinate"))
+        {
+	    cont = (char *)xmlNodeGetContent(cur);
+	    pickup_coordinate(cont);
+        }
+	else if(!xmlStrcmp(cur->name,(xmlChar*)"normal"))
+        {
+	    cont = (char *)xmlNodeGetContent(cur);
+	    pickup_normal(cont);
+        }
+	else if(!xmlStrcmp(cur->name,(xmlChar*)"model"))
+        {
+	    cont = (char *)xmlNodeGetContent(cur);
+	    pickup_model(cont);
+        }
+	else if(!xmlStrcmp(cur->name,(xmlChar*)"texture"))
+        {
+	    cont = (char *)xmlNodeGetContent(cur);
+	    pickup_texture(cont);
+	}
+	else if(!xmlStrcmp(cur->name,(xmlChar*)"imageflag"))
+        {
+	  char *filename = (char *)xmlGetProp(cur, (xmlChar *)"name");
+	  texture_hash.hash_regist(filename);
+	}
+	else if(!xmlStrcmp(cur->name,(xmlChar*)"image"))
+        {
+	    char image_name[20] = "/tmp/image_XXXXXX";
+	    char *filename = (char *)xmlGetProp(cur, (xmlChar *)"name");
+	    int fd = mkstemp(image_name);
+	    FILE *outfile = fdopen(fd, "wb");
+	    if(NULL == outfile)
+	    {
+		cout << "error open file\n";
+	    }
+	    cont = (char *)xmlNodeGetContent(cur);
+	    //decode(cont, image_name);
+	    decode(cont, outfile);
+	    fclose(outfile);
+
+	    /**
+	     * image_name を既に Load していれば何もしない
+	     */
+	    int tex_id = texture_hash.hash_regist(filename);
+	    if (tex_id < 0) {
+
+		texture_image = IMG_Load(image_name);
+		
+		/**
+		 * image を 32bit(RGBA) に変換する
+		 */
+		SDL_Surface *tmpImage
+		    = SDL_CreateRGBSurface(SDL_HWSURFACE, texture_image->w,
+					   texture_image->h, 32, redMask,
+					   greenMask, blueMask, alphaMask);
+		SDL_Surface *converted;
+		converted = SDL_ConvertSurface(texture_image, tmpImage->format,
+					       SDL_HWSURFACE);
+		if (converted != NULL) {
+		    SDL_FreeSurface(texture_image);
+		    texture_image = converted;
+		}
+
+		uint32 *tapestry;
+		int scale = 1;
+		int tex_w = texture_image->w;
+		int tex_h = texture_image->h;
+		int all_pixel_num = 0;
+
+		/**
+		 * テクスチャの w or h が 8 pixel で分割できる間、
+		 * 1/2 の縮小画像を作る。
+		 * ここでは、最大の scale (1/scale) を見つける
+		 *
+		 * (ex)
+		 *  (128,128) => 64,64 : 32,32: 16,16 : 8,8
+		 *     scale = 16
+		 *  (128, 64) => 64,32 : 32,16: 16,8
+		 *     scale = 8
+		 */
+		while (tex_w % TEXTURE_SPLIT_PIXEL == 0 && 
+		       tex_h % TEXTURE_SPLIT_PIXEL == 0) {
+		    all_pixel_num += tex_w*tex_h;
+		    tex_w >>= 1; /* tex_w /= 2 */
+		    tex_h >>= 1;
+		    scale <<= 1; /* scale *= 2 */
+		}
+
+		scale >>= 1;
+
+		tapestry = makeTapestry(texture_image->w, texture_image->h,
+					(uint32*)texture_image->pixels,
+					all_pixel_num, scale);
+
+		list[id_count-1].t_w = texture_image->w;
+		list[id_count-1].t_h = texture_image->h;
+		list[id_count-1].pixels_orig = (Uint32*)texture_image->pixels;
+		list[id_count-1].pixels = tapestry;
+		list[id_count-1].scale_max = scale;
+		
+		texture_id = id_count-1;
+
+		if (unlink(image_name))
+		{
+		    cout << "unlink error\n";
+		}
+	    } else {
+		/**
+		 * 以前に Load されている Texture を共用
+		 */
+		texture_id = tex_id;
+	    }
+ 
+	    // こんなことすると list[] のいみあるのかなーと
+	    // 微妙に思う、自分で書き換えた感想 by gongo
+	    texture_info.t_w = list[texture_id].t_w;
+	    texture_info.t_h = list[texture_id].t_h;;
+	    texture_info.pixels_orig = list[texture_id].pixels_orig;
+	    texture_info.pixels = list[texture_id].pixels;
+	    texture_info.scale_max = list[texture_id].scale_max;
+	}
+    }
+}
+
+
+void
+SceneGraph::delete_data(void)
+{
+    SceneGraphPtr n = this->next, m;
+
+    //n = this;
+    //delete [] n->data;
+
+    if (next) {
+	while (n) {
+	    m = n->next;
+	    delete n;
+	    n = m;
+	}
+    }
+}
+
+void
+SceneGraph::move_execute(int w, int h)
+{
+    (*move)(this, w, h);
+}
+
+void
+SceneGraph::collision_check(int w, int h, SceneGraphPtr tree)
+{
+    (*collision)(this, w, h, tree);
+}
+
+void
+SceneGraph::all_execute(int screen_w, int screen_h)
+{
+    SceneGraphPtr top = this;
+    SceneGraphPtr t = top;
+
+    while (t) {
+	t->move_execute(screen_w, screen_h);
+	t->collision_check(screen_w, screen_h, top);
+
+	t->frame++;
+
+	if (t->parent != NULL) {
+	    get_matrix(t->matrix, t->angle, t->xyz, t->parent->matrix);
+	} else {
+	    get_matrix(t->matrix, t->angle, t->xyz, NULL);
+	}
+
+	if (t->children != NULL) {
+	    t = t->children;
+	} else if (t->brother != NULL) {
+	    t = t->brother;
+	} else {
+	    while (t) {
+		if (t->brother != NULL) {
+		    t = t->brother;
+		    break;
+		} else {
+		    if (t->parent == NULL) {
+			t = NULL;
+			break;
+		    } else {
+			t = t->parent;
+		    }
+		}
+	    }
+	}
+    }
+}
+
+void
+SceneGraph::set_move_collision(SceneGraphPtr node, move_func new_move,
+			       collision_func new_collision)
+{
+    node->move = new_move;
+    node->collision = new_collision;
+}
+
+void
+SceneGraph::set_move_collision(move_func new_move,
+			       collision_func new_collision)
+{
+    this->move = new_move;
+    this->collision = new_collision;
+}
+
+void
+SceneGraph::add_next(SceneGraphPtr next)
+{
+    /* next のリストの最後に加える */
+    if (this->next != NULL) {
+	SceneGraphPtr tmp = this->last;
+	tmp->next = next;
+    } else {
+	this->next = next;
+    }
+
+    this->last = next;
+}
+
+/**
+ * SceneGraph の clone
+ * @return clone SceneGraph
+ */
+SceneGraphPtr
+SceneGraph::clone(void) {
+    SceneGraphPtr p = new SceneGraph(this);
+    return p;
+}
+
+/**
+ * SceneGraph の clone
+ * 予め allocate されてる領域への placement new を行う
+ *
+ * @param buf clone 領域
+ * @return clone SceneGraph
+ */
+SceneGraphPtr
+SceneGraph::clone(void *buf) {
+    SceneGraphPtr p = new(buf) SceneGraph(this);
+    return p;
+}
+
+void
+SceneGraph::remove(void)
+{
+    this->flag_remove = 1;
+}
+
+/**
+ * tree から node を削除する
+ * 
+ * @param tree SceneGraphTree
+ * @return node削除後の SceneGraphTree
+ */
+SceneGraphPtr
+SceneGraph::realRemoveFromTree(SceneGraphPtr tree)
+{
+    SceneGraphPtr node = this;
+    SceneGraphPtr parent = node->parent;
+    SceneGraphPtr ret = tree;
+
+    if (parent) {
+	SceneGraphPtr brother = parent->children;
+	SceneGraphPtr p, p1 = NULL;
+
+	p = brother;
+	if (p) {
+	    if (p == node) {
+		parent->children = NULL;
+		parent->lastChild = NULL;
+	    } else {
+		p1 = p->brother;
+
+		while (p1 && p1 != node) {
+		    p1 = p1->brother;
+		    p = p->brother;
+		}
+	    
+		if (p1) {
+		    p->brother = p1->brother;
+
+		    // node が最後尾なら、lastChild を変更
+		    if (parent->lastChild == p1) {
+			parent->lastChild = p;
+		    }
+		} else {
+		    // Can't find remove node
+		}
+	    }
+	}
+    } else {
+	// 親が居ない = tree root なので
+	// NULL を返す
+	ret = NULL;
+    }
+
+    return ret;
+}
+
+/**
+ * list から node を削除する
+ * 
+ * @param list SceneGraphList
+ * @return node削除後の SceneGraphList
+ */
+SceneGraphPtr
+SceneGraph::realRemoveFromList(SceneGraphPtr list)
+{
+    SceneGraphPtr node = this;
+    SceneGraphPtr prev = node->prev;
+    SceneGraphPtr next = node->next;
+    SceneGraphPtr ret = list;
+    
+    if (prev) {
+	prev->next = next;
+    } else {
+	ret = next;
+    }
+
+    if (next) {
+	next->prev = prev;
+    }
+
+    return ret;
+}
+
+int
+SceneGraph::isRemoved(void)
+{
+    return flag_remove;
+}
+
+/**
+ * 平行移動
+ *
+ * @param x Ttranslate in the x direction
+ * @param y Ttranslate in the y direction
+ * @param z Ttranslate in the z direction
+ */
+void
+SceneGraph::translate(float x, float y, float z)
+{
+    this->xyz[0] = x;
+    this->xyz[1] = y;
+    this->xyz[2] = z;
+}
+
+/**
+ * x 軸方向への平行移動
+ *
+ * @param x Ttranslate in the x direction
+ */
+void
+SceneGraph::translateX(float x)
+{
+    this->xyz[0] = x;
+}
+
+/**
+ * y 軸方向への平行移動
+ *
+ * @param y Ttranslate in the y direction
+ */
+void
+SceneGraph::translateY(float y)
+{
+    this->xyz[1] = y;
+}
+
+/**
+ * z 軸方向への平行移動
+ *
+ * @param z Ttranslate in the z direction
+ */
+void
+SceneGraph::translateZ(float z)
+{
+    this->xyz[2] = z;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/SceneGraph.h	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,103 @@
+#ifndef INCLUDED_SCENE_GRAPH
+#define INCLUDED_SCENE_GRAPH
+
+#ifndef INCLUDED_POLYGON
+#  include "polygon.h"
+#endif
+
+#ifndef INCLUDED_PAD
+#  include "Pad.h"
+#endif
+
+class SceneGraph;
+
+typedef void (*move_func)(SceneGraph* node, int screen_w, int screen_h);
+typedef void (*collision_func)(SceneGraph* node, int screen_w, int screen_h,
+			       SceneGraph* tree);
+typedef SceneGraph* SceneGraphPtr;
+
+class SceneGraph : public Polygon {
+public:
+    SceneGraph(void);
+    SceneGraph(xmlNodePtr surface);
+    SceneGraph(SceneGraphPtr orig);
+    ~SceneGraph(void);
+
+    // Node がもつ状態変数(というべきか否か
+    // xyz,angle ぐらいあればおk?
+    float stack_xyz[3];
+    float stack_angle[3];
+
+    // xml ファイルから生成した時のオブジェクトリスト
+    SceneGraphPtr next;
+    SceneGraphPtr prev;
+    SceneGraphPtr last;
+
+    // Tree Structure
+    SceneGraphPtr parent;
+    SceneGraphPtr brother;
+    SceneGraphPtr children;
+    SceneGraphPtr lastChild;
+
+    // Tree から削除されていたら 1 をセット。default = 0
+    int flag_remove;
+
+    // SceneGraph ID (SGList.h)
+    int sgid;
+
+    // この SceneGraph は描画するものかどうか (0:しない 1:する
+    int flag_drawable;
+
+    // anime frame num
+    int frame;
+
+    // 関数ポインタ
+    move_func move;
+    collision_func collision;
+
+    // desutroctor で呼ばれる
+    void (SceneGraph::*finalize)(void);
+
+    void init(void);
+    void finalize_original(void);
+    void finalize_copy(void);
+    void move_execute(int screen_w, int screen_h);
+    void collision_check(int screen_w, int screen_h, SceneGraphPtr tree);
+    void all_execute(int screen_w, int screen_h);
+
+    void add_next(SceneGraphPtr next);
+    SceneGraphPtr addChild(SceneGraphPtr child);
+    SceneGraphPtr addBrother(SceneGraphPtr bro);
+    SceneGraphPtr clone(void);
+    SceneGraphPtr clone(void *buf);
+    SceneGraphPtr searchSceneGraph(const char *name);
+    void set_move_collision(SceneGraphPtr node,
+			    move_func new_move, collision_func new_collision);
+    void set_move_collision(move_func new_move, collision_func new_collision);
+    void remove(void);
+    SceneGraphPtr realRemoveFromTree(SceneGraphPtr tree);
+    SceneGraphPtr realRemoveFromList(SceneGraphPtr list);
+    int isRemoved(void);
+
+    static void createFromXMLfile(const char *);
+    static SceneGraphPtr createSceneGraph(int id);
+
+    void translate(float x, float y, float z);
+    void translateX(float x);
+    void translateY(float y);
+    void translateZ(float z);
+
+
+    void tree_check(void);
+    void print_member(void);
+    void get_data(xmlNodePtr cur);
+    void delete_data(void);
+};
+
+#endif
+
+// オリジナル (Linked List)
+extern SceneGraphPtr scene_graph;
+
+// 描画用 (同じオブジェクトが複数ある) Tree
+extern SceneGraphPtr scene_graph_view;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/SceneGraphArray.h	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,45 @@
+#ifndef INCUDED_SCENE_GRAPH_ARRAY
+#define INCUDED_SCENE_GRAPH_ARRAY
+
+#ifndef INCLUDED_SCENE_GRAPH
+#  include "SceneGraph.h"
+#endif
+
+// 下ですぐ #undef してます
+#define MAX_SIZE 32
+
+class SceneGraphArray {
+public:
+    SceneGraph buf[MAX_SIZE];
+    int size;
+    int pad[3];
+
+    SceneGraphArray(void) : size(0) {}
+
+    /**
+     * array の初期化
+     */
+    void init(void) {
+	size = 0;
+    }
+
+    /**
+     * buf から SceneGraph buffer を返す
+     *
+     * @retval SceneGraph if size < MAX_SIZE
+     * @retval NULL if size >= MAX_SIZE
+     */
+    SceneGraphPtr getNext(void) {
+	if (size >= MAX_SIZE) {
+	    return NULL;
+	} else {
+	    return &buf[size++];
+	}
+    }
+};
+
+typedef SceneGraphArray *SceneGraphArrayPtr;
+
+#undef MAX_SIZE
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/SceneGraphIterator.cpp	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,89 @@
+#include "SceneGraphIterator.h"
+
+void
+SceneGraphIterator::set(SceneGraphPtr _list)
+{
+    list = cur = _list;
+}
+
+/**
+ * 次の SceneGraph があるか返す
+ *
+ * @retval 1 next がある
+ * @retval 0 next がない
+ */
+int
+SceneGraphIterator::hasNext(void)
+{
+    return (cur->next) ? 1 : 0;
+}
+
+/**
+ * 指定した名前をもつ SceneGraph が以降存在するか
+ *
+ * @param id 検索したい SceneGraph の ID
+ * @retval 1 next がある
+ * @retval 0 next がない
+ */
+int
+SceneGraphIterator::hasNext(int id)
+{
+    SceneGraphPtr p;
+
+    for (p = cur->next; p; p = p->next) {
+	if (p->sgid == id) {
+	    return 1;
+	}
+    }
+
+    return 0;
+}
+
+/**
+ * iterator を次に進める
+ */
+void
+SceneGraphIterator::next(void)
+{
+    cur = cur->next;
+}
+
+/**
+ * iterator を指定した ID を持つ SceneGraph まで進める
+ * SceneGraph が無い場合、NULL にする
+ *
+ * @param id 検索したい SceneGraph の ID
+ */
+void
+SceneGraphIterator::next(int id)
+{
+    SceneGraphPtr p;
+
+    for (p = cur->next; p; p = p->next) {
+	if (p->sgid == id) {
+	    break;
+	}
+    }
+
+    cur = p;
+}
+
+/**
+ * 参照中の SceneGraph を削除する
+ */
+void
+SceneGraphIterator::remove(void)
+{
+    cur->remove();
+}
+
+/**
+ * 参照中の SceneGraph を返す
+ *
+ * @return current SceneGraph
+ */
+SceneGraphPtr
+SceneGraphIterator::get(void)
+{
+    return cur;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/SceneGraphIterator.h	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,27 @@
+#ifndef INCLUDED_SCENE_GRAPH_ITERATOR
+#define INCLUDED_SCENE_GRAPH_ITERATOR
+
+#ifndef INCLUDED_SCENE_GRAPH
+#  include "SceneGraph.h"
+#endif
+
+class SceneGraphIterator {
+public:
+    // 走査する SceneGraphList
+    SceneGraphPtr list;
+
+    // 現在参照中の SceneGraph
+    SceneGraphPtr cur;
+
+    void set(SceneGraphPtr list);
+    int hasNext(void);
+    int hasNext(int id);
+    void next(void);
+    void next(int id);
+    void remove(void);
+    SceneGraphPtr get(void);
+};
+
+typedef SceneGraphIterator *SceneGraphIteratorPtr;
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/SceneGraphRoot.cpp	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,316 @@
+#include <SDL.h>
+#include <SDL_image.h>
+#include <libxml/parser.h>
+#include "SceneGraphRoot.h"
+#include "xml.h"
+#include "sys.h"
+#include "TextureHash.h"
+#include "texture.h"
+#include "SGList.h"
+
+int cnt = 0;
+
+SceneGraphRoot::SceneGraphRoot(float w, float h)
+{
+    sg_src = new SceneGraphPtr[SGLIST_LENGTH];
+    camera = new Camera(w, h);
+    iterator = new SceneGraphIterator;
+    controller = create_controller();
+
+    sg_exec_tree = NULL;
+    sg_draw_tree = NULL;
+    sg_available_list = NULL;
+    sg_remove_list = NULL;
+
+    // TODO
+    //   今はとりあえず camera を Root にしています
+    //   今はそれすらもしてません
+    //sg_exec_tree = camera;
+}
+
+SceneGraphRoot::~SceneGraphRoot(void)
+{
+    SceneGraphPtr p = sg_available_list;
+
+    while (p) {
+	SceneGraphPtr tmp = p->next;
+	delete p;
+	p = tmp;
+	cnt--;
+    }
+
+    p = sg_remove_list;
+
+    while (p) {
+	SceneGraphPtr tmp = p->next;
+	delete p;
+	p = tmp;
+	cnt--;
+    }
+
+    delete [] sg_src;
+    delete camera;
+    delete iterator;
+    delete controller;
+}
+
+/**
+ * xml ファイルから生成された SceneGraph を sg_src に登録する。
+ *
+ * @param sg SceneGraph created by xmlfile
+ */
+void
+SceneGraphRoot::registSceneGraph(SceneGraphPtr sg)
+{
+    for (int i = 0; i < SGLIST_LENGTH; i++) {
+	if (strcmp(sg->name, sglist_table[i]) == 0) {
+	    sg->sgid = i;
+	    sg_src[i] = sg;
+	    return;
+	}
+    }
+
+    fprintf(stderr, "error: (%s:%3d) Can't find Scene \"%s\"\n",
+	    __FUNCTION__, __LINE__, sg->name);
+}
+
+void
+SceneGraphRoot::addNext(SceneGraphPtr sg)
+{
+    SceneGraphPtr last = sg_available_list;
+
+    if (!last) {
+	sg_available_list = sg;
+    } else {
+	while (last->next) {
+	    last = last->next;
+	}
+	last->next = sg;
+	sg->prev = last;
+    }
+
+    cnt++;
+}
+
+/* XMLファイルからポリゴンを作成  */
+void
+SceneGraphRoot::createFromXMLfile(const char *xmlfile)
+{
+    xmlDocPtr doc;
+    xmlNodePtr cur;
+    SceneGraphPtr tmp;
+    
+    /* パース DOM生成 */
+    doc = xmlParseFile(xmlfile);
+    cur = xmlDocGetRootElement(doc);
+
+    /* ??  */
+    xmlStrcmp(cur->name,(xmlChar*)"OBJECT-3D");
+
+    /* XMLのノードを一つずつ解析  */
+    for (cur=cur->children; cur; cur=cur->next) {
+	/* 扱うのはsurfaceオンリー  */
+	if (xmlStrcmp(cur->name,(xmlChar*)"surface") != 0) {
+	    continue;
+	}
+
+	/* ポリゴン(SceneGraph)生成  */
+	tmp = new SceneGraph(cur);
+
+	registSceneGraph(tmp);
+    }
+
+    xmlFreeDoc(doc);
+}
+
+SceneGraphPtr
+SceneGraphRoot::createSceneGraph(int id)
+{
+    SceneGraphPtr src;
+    SceneGraphPtr p;
+
+    if (id < 0 || id > SGLIST_LENGTH) {
+	return NULL;
+    }
+
+    /* オリジナルの SceneGraph */
+    src = sg_src[id];
+
+    /* ユーザーにはオリジナルの clone を返す */
+    p = src->clone();
+
+    addNext(p);
+
+    return p;
+}
+
+/**
+ * 何も表示しない、move,collision もしない SceneGraph を生成
+ * いずれ、Transform3D 的なものに回す予定
+ */
+SceneGraphPtr
+SceneGraphRoot::createSceneGraph(void)
+{
+    SceneGraphPtr p = new SceneGraph;
+
+    addNext(p);
+    p->flag_drawable = 0;
+
+    return p;
+}
+
+void
+SceneGraphRoot::allExecute(int screen_w, int screen_h)
+{
+    SceneGraphPtr list = sg_available_list;
+    SceneGraphPtr t = sg_exec_tree;
+    SceneGraphPtr cur_parent = camera;
+
+    // 前フレームで描画した SceneGraph は削除
+    allRemove(sg_remove_list);
+
+    // 前フレームに作られた SceneGraph は描画用に移行
+    // 現フレームでの操作は以下の tree,list には適用されない
+    sg_draw_tree = sg_exec_tree;
+    sg_remove_list = sg_available_list;
+
+    // 現フレームで新しく SceneGraph がコピーされるので初期化
+    sg_exec_tree = NULL;
+    sg_available_list = NULL;
+
+    camera->move_execute(screen_w, screen_h);
+    camera->update(screen_w, screen_h);
+
+    camera->children = NULL;
+    camera->lastChild = NULL;
+
+    while (t) {
+	SceneGraphPtr c = t->clone();
+
+	addNext(c);
+	cur_parent->addChild(c);
+	c->frame = t->frame;
+
+	c->move_execute(screen_w, screen_h);
+	c->collision_check(screen_w, screen_h, list);
+
+	if (c->isRemoved()) {
+	    sg_exec_tree = c->realRemoveFromTree(cur_parent);
+	    sg_available_list = c->realRemoveFromList(sg_available_list);
+	    delete c;
+	    cnt--;
+	    t->children = NULL;
+	    t->parent = cur_parent;
+	} else {
+	    c->frame++;
+	    get_matrix(c->matrix, c->angle, c->xyz, c->parent->matrix);
+	}
+
+	if (t->children != NULL) {
+	    cur_parent = c;
+	    t = t->children;
+	} else if (t->brother != NULL) {
+	    cur_parent = c->parent;
+	    t = t->brother;
+	} else {
+	    while (t) {
+		if (t->brother != NULL) {
+		    cur_parent = t->parent;
+		    t = t->brother;
+		    break;
+		} else {
+		    if (t->parent == NULL) {
+			t = NULL;
+			break;
+		    } else {
+			t = t->parent;
+		    }
+		}
+	    }
+	}
+    }
+
+    // 現在、allExecute が終わった時点では
+    // camera->children が User SceneGraph の root になる
+    sg_exec_tree = camera->children;
+}
+
+void
+SceneGraphRoot::allRemove(SceneGraphPtr list)
+{
+    SceneGraphPtr p = list;
+
+    while (p) {
+	SceneGraphPtr p1 = p->next;
+	delete p;
+	p = p1;
+	cnt--;
+    }
+}
+
+void
+SceneGraphRoot::checkRemove(void)
+{
+    SceneGraphPtr p = sg_available_list;
+    SceneGraphPtr p1;
+
+    while (p) {
+	p1 = p->next;
+	if (p->isRemoved()) {
+	    sg_exec_tree = p->realRemoveFromTree(sg_exec_tree);
+	    sg_available_list = p->realRemoveFromList(sg_available_list);
+	}
+	delete p;
+	p = p1;
+    }
+}
+
+SceneGraphPtr
+SceneGraphRoot::getExecuteSceneGraph(void)
+{
+    return sg_exec_tree;
+}
+
+SceneGraphPtr
+SceneGraphRoot::getDrawSceneGraph(void)
+{
+    return sg_draw_tree;
+}
+
+void
+SceneGraphRoot::updateControllerState(void)
+{
+    controller->check();
+}
+
+void
+SceneGraphRoot::setSceneData(SceneGraphPtr sg)
+{
+    sg_exec_tree = sg;
+}
+
+Pad*
+SceneGraphRoot::getController(void)
+{
+    return controller;
+}
+
+SceneGraphIteratorPtr
+SceneGraphRoot::getIterator(void)
+{
+    iterator->set(sg_remove_list);
+    return iterator;
+}
+
+SceneGraphIteratorPtr
+SceneGraphRoot::getIterator(SceneGraphPtr list)
+{
+    iterator->set(list);
+    return iterator;
+}
+
+CameraPtr
+SceneGraphRoot::getCamera(void)
+{
+    return camera;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/SceneGraphRoot.h	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,86 @@
+#ifndef INCLUDED_SCENE_GRAPH_ROOT
+#define INCLUDED_SCENE_GRAPH_ROOT
+
+#ifndef INCLUDED_SCENE_GRAPH
+#  include "SceneGraph.h"
+#endif
+
+#ifndef INCLUDED_SCENE_GRAPH_ARRAY
+#  include "SceneGraphArray.h"
+#endif
+
+#ifndef INCLUDED_CAMERA
+#  include "Camera.h"
+#endif
+
+#ifndef INCLUDED_SCENE_GRAPH_ITERATOR
+#  include "SceneGraphIterator.h"
+#endif
+
+class SceneGraphRoot {
+public:
+    /* Constructor, Destructor */
+    SceneGraphRoot(float w, float h);
+    ~SceneGraphRoot(void);
+
+    /* Variables */
+    // xml から読み込んだ、オリジナルの SceneGraph
+    SceneGraphPtr *sg_src;
+
+    // move, collision 用の SceneGraph (tree)
+    SceneGraphPtr sg_exec_tree;
+
+    // 描画用の SceneGraph List (tree)
+    SceneGraphPtr sg_draw_tree;
+
+    // sg_exec_tree に対応する list
+    SceneGraphPtr sg_available_list;
+
+    // sg_draw_tree に対応する list
+    // draw_tree は描画後削除される
+    SceneGraphPtr sg_remove_list;
+
+    SceneGraphArrayPtr sg_array1;
+    SceneGraphArrayPtr sg_array2;
+    SceneGraphArrayPtr sg_curArray;
+
+    // コントローラーオブジェクト (Keyboard, Joystick, ..)
+    Pad *controller;
+
+    // カメラオブジェクト
+    Camera *camera;
+
+    // SceneGraphIterator
+    SceneGraphIteratorPtr iterator;
+
+    /**
+     * Functions
+     */
+    /* User API */
+    void createFromXMLfile(const char *);
+    SceneGraphPtr createSceneGraph(int id);
+    SceneGraphPtr createSceneGraph(void);
+    void setSceneData(SceneGraphPtr sg);
+    Pad *getController(void);
+    SceneGraphIteratorPtr getIterator(void);
+    SceneGraphIteratorPtr getIterator(SceneGraphPtr list);
+    CameraPtr getCamera(void);
+
+    /* Other System API */
+    void allExecute(int screen_w, int screen_h);
+    void checkRemove(void);
+    SceneGraphPtr getExecuteSceneGraph(void);
+    SceneGraphPtr getDrawSceneGraph(void);
+    void updateControllerState(void);
+
+    /* System API */
+    void registSceneGraph(SceneGraphPtr sg);
+    void addNext(SceneGraphPtr sg);
+    void allRemove(SceneGraphPtr list);
+};
+
+typedef SceneGraphRoot *SceneGraphRootPtr;
+
+#endif
+
+extern SceneGraphRootPtr sgroot;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/Span.h	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,75 @@
+#ifndef INCLUDED_SPAN
+#define INCLUDED_SPAN
+
+#ifndef INCLUDED_TAPESTRY
+#  include "Tapestry.h"
+#endif
+
+#ifndef INCLUDED_TYPES
+#  include "types.h"
+#endif
+
+#define MAX_TILE_LIST 64
+
+#if 0
+typedef struct tile {
+    void *tile;
+    int tix, tiy;
+     //int padding; // 16バイト倍数にする用
+} TileInfo, *TileInfoPtr;
+
+typedef struct tile_list {
+    int size;
+    struct tile_list *next;
+    int pad[2];
+    TileInfo tileinfo[MAX_TILE_LIST];
+
+    void init(void) {
+	size = 0;
+	next = 0;
+    }
+} TileInfoList, *TileInfoListPtr; // 4*4+64*sizeof(Tile) = 16+768
+#endif
+
+class Span {
+public:
+    uint32 *tex_addr;
+    int tex_width;
+    int tex_height;
+    int x;
+    int y;
+    int length_x;
+    float start_z;
+    float end_z;
+    float tex_x1;
+    float tex_x2;
+    float tex_y1;
+    float tex_y2;
+
+#if 0
+    TileInfoListPtr tilelist;
+#endif
+
+#if 0
+    void init(void) {
+	tilelist = 0;
+    }
+    
+    void reinit(void) {
+	TileInfoListPtr tlist = this->tilelist;
+	TileInfoListPtr t;
+
+	while (tlist) {
+	    t = tlist->next;
+	    free(tlist);
+	    tlist = t;
+	}
+
+	tilelist = 0;
+    }
+#endif
+};
+
+typedef Span* SpanPtr;
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/SpanC.cpp	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,398 @@
+#include <iostream>
+#include "SpanC.h"
+#include "triangle.h"
+#include "polygon.h"
+using namespace std;
+
+
+// f1:x$B$NA}2CNL(B  f2:y$B$NA}2CNL(B  i:.......    base:$B4pK\$H$J$kD:E@$N(By$B:BI8(B
+static float calc(float f1, float f2,int i, float base){
+	float ans;
+	ans = f1/f2*i + base;
+	return ans;
+}
+
+
+static Vertex *vMid1(Vertex *vMid1,Vertex *vMin, Vertex *vMid, Vertex *vMax) {
+	float d,d1;
+
+	vMid1->y = vMid->y;
+	//vMid1->tex_y = vMid->tex_y;
+    d = (int)vMax->y-(int)vMin->y;
+	d1 = (int)vMid->y - (int)vMin->y;
+	/*
+
+	if (-1.0<=vMax->y&&vMax->y<=1.0) {
+		a = 0.5;
+	} else {
+		a = (vMax->x-vMin->x)/d;
+	}
+	*/
+	//vMid1->tex_x  = vMin->tex_x + a * (vMax->tex_x-vMin->tex_x);
+	vMid1->tex_x  = calc(vMax->tex_x - vMin->tex_x, d, (int)d1 , vMin->tex_x);
+	vMid1->tex_y  = calc(vMax->tex_y - vMin->tex_y, d, (int)d1 , vMin->tex_y);
+	//vMid1->x      = vMin->x     + a * (vMax->y     -vMin->y);
+	vMid1->x      = calc(vMax->x - vMin->x, d, (int)d1 , vMin->x);
+	//vMid1->z      = vMin->z     + a * (vMax->y     -vMin->y);
+	vMid1->z      = calc(vMax->z - vMin->z, d, (int)d1 , vMin->z);
+	//printf("x:%f y:%f z:%f tex_x:%f tex_y:%f\n",vMid1->x,vMid1->y,vMid1->z,vMid1->tex_x, vMid1->tex_y);
+	return vMid1;
+}
+
+
+
+void
+Span_c::half_triangle(Vertex *vMin, Vertex *vMid, Vertex *vMid1,
+		    SDL_Surface *image)
+{
+
+	float tmp_z,tmp_tex1, tmp_tex2 ,tmp_tey1,tmp_tey2;
+	//tmp_x,tmp_y,tmp_ypos ......unused
+	float tex_x, tex_y,tex_z;
+	float tmp_xpos,tmp_end,tmp_zpos;
+	int tex_xpos,tex_ypos,tex_zpos;
+	int i,j;
+	float div_y;
+	Uint32 rgb;
+	float z,zpos;
+	int x,y;
+	int k =0;
+	int l = 1;
+	//float incli_x1, incli_x2;
+	//float incli_z1, incli_z2;
+	//float base_x1, base_x2  , base_z1, base_z2;
+	//int base_y;
+
+	/*
+	incli_x1 = vMid1->x - vMin->x;
+	incli_x2 = vMid->x  - vMin->x;
+	incli_z1 = vMid1->z - vMin->z;
+	incli_z2 = vMid->z  - vMin->z;
+	base_x1 = vMin->x;
+	base_x2 = vMin->x;
+	base_z1 = vMin->z;
+	base_z2 = vMin->z;
+	*/
+	//cout << vMin->x << vMin->y << vMin->z << endl;
+	int start_y = (int)vMid->y;
+	int end_y   = (int)vMin->y;
+	
+	if (start_y<end_y) { 
+	    int i; i=end_y; end_y=start_y; start_y = i;   //y$B$NF~$lBX$((B 
+	    //Vertex *v; v = vMin; vMin = vMid; vMid = v;	
+	    /*
+	      incli_x1 = vMin->x - vMid->x; incli_x2 = vMin->x - vMid1->x;
+	      incli_z1 = vMin->z - vMid->z; incli_z2 = vMin->z - vMid1->z;
+	      base_z1 = vMid->z; base_z2 = vMid1->z;
+	      base_y = (int)vMid->y;
+	    */
+	    k = 1;
+	    l = -1;
+	}
+
+
+
+	div_y = start_y - end_y;  // > 0
+
+	//if(div_y < 1 && div_y > -1) div_y = 1;
+	for(i = k; i < div_y+1; i++) {
+		//$B$3$3$G(Bspan$B$N:8C<$H1&C<$N(Bx,z$B$r5a$a$F$k(B
+		tmp_xpos = calc(vMid1->x - vMin->x ,div_y, i, vMin->x);
+		tmp_end =  calc(vMid->x  - vMin->x ,div_y, i, vMin->x);	
+		tmp_z =    calc(vMid1->z - vMin->z ,div_y, i, vMin->z);
+	   	tmp_zpos = calc(vMid->z  - vMin->z ,div_y, i, vMin->z);
+		//printf("x:%f end:%f z:%f zpos:%f\n",tmp_xpos,tmp_end,tmp_z,tmp_zpos);
+		//$B$3$3$+$i(Bspan$B$N:8C<$H1&C<$KBP1~$9$k%F%/%9%A%c$r7W;;$9$k(B
+		tmp_tex1 =((i/(div_y)) * vMid1->tex_x) + \
+			   ( ((div_y - i)/(div_y)) * vMin->tex_x); 
+		tmp_tex2 =( (i/(div_y)) * vMid->tex_x) + \
+			   ( ((div_y - i)/(div_y)) * vMin->tex_x); 
+
+		tmp_tey1 =( (i/(div_y)) * vMid1->tex_y) + \
+			   ( ((div_y - i)/(div_y)) * vMin->tex_y); 
+		tmp_tey2 =( (i/(div_y)) * vMid->tex_y) + \
+			   ( ((div_y - i)/(div_y)) * vMin->tex_y); 
+
+		//$B$3$3$G:8C<$,(Bxpos$B$+(Bend$B$rH=CG$7!"IA2h$9$k(Bspan$B$r:n$k(B
+		if(tmp_xpos > tmp_end) {
+			x = (int)tmp_end;
+			y = (int)vMin->y + i*l;
+			end = (int)(tmp_xpos)-(int)(tmp_end)+1;
+			z = tmp_zpos;
+			zpos = tmp_z;
+			tex1 = tmp_tex2;
+			tex2 = tmp_tex1;
+			tey1 = tmp_tey2;
+			tey2 = tmp_tey1;
+		} else {
+			x = (int)tmp_xpos;
+			y = (int)vMin->y + i*l;
+			end = (int)(tmp_end)-(int)(tmp_xpos)+1;
+			z = tmp_z;
+			zpos = tmp_zpos;
+			tex1 = tmp_tex1;
+			tex2 = tmp_tex2;
+			tey1 = tmp_tey1;
+			tey2 = tmp_tey2;
+		}
+		//printf("%d:%f,%f  ",(int)vMin->y + i,xpos,end);
+		//printf("%d:%d:%d:x:%d,end:%d\n",x, y , end,(int)(tmp_end),(int)(tmp_xpos));
+		//printf("x:%d y:%d end:%d z:%f zpos:%f\n",x,y,end,z , zpos);
+		//printf("tex1:%f tex2:%f tey1:%f tey2:%f\n",tex1,tex2,tey1,tey2); 
+		if(end == 1) {
+				//printf("tex_x:%f tex_y:%f\n",tex1,tex2);
+				if(tex1 > 1) tex1 = 1;
+				if(tey1 > 1) tey1 = 1;
+				tex_xpos = (int)((image->h-1) * tex1); 
+				tex_ypos = (int)((image->w-1) * tey1); 
+				tex_zpos = (int)z;
+				//printf("tex_xpos:%d tex_ypos:%d\n",tex_xpos,tex_ypos);	
+				//printf("image->h:%d tex_x:%f\n",image->h,tex1);
+				rgb = p->get_rgb(tex_xpos,tex_ypos);	
+				//viewer->write_pixel(x,y,zpos,rgb);
+		}else {
+			for(j = 0; j < end; j++) {
+				tex_x = tex1*(end-1-j)/(end-1) + tex2*j/(end-1);
+				tex_y = tey1*(end-1-j)/(end-1) + tey2*j/(end-1);
+				tex_z = z*(end-1-j)/(end-1) + zpos*j/(end-1);
+				if(tex_x > 1) tex_x = 1;
+				if(tex_y > 1) tex_y = 1;
+				tex_xpos = (int)((image->h-1) * tex_x); 
+				tex_ypos = (int)((image->w-1) * tex_y); 
+				//printf("tex_xpos:%d tex_ypos:%d\n",tex_xpos,tex_ypos);	
+				//printf("z:%f zpos:%f tex_z:%f\n",z,zpos,tex_z);
+				//printf("tex_x:%f tex_y:%f\n",tex_x,tex_y);
+				rgb = p->get_rgb(tex_xpos,tex_ypos);	
+				//viewer->write_pixel(j+x,y,tex_z,rgb);
+			}
+		}
+	}
+}
+
+void Span_c::create_span(Triangle *tri,SDL_Surface *image) {
+	Vertex *vMin , *vMid, *vMax;
+	/*
+	float tmp_z,tmp_tex1, tmp_tex2 ,tmp_tey1,tmp_tey2;
+	//tmp_x,tmp_y,tmp_ypos ......unused
+	float tex_x, tex_y,tex_z;
+	float tmp_xpos,tmp_end,tmp_zpos;
+	int top_triangle;
+	int tex_xpos,tex_ypos,tex_zpos;
+	int i,j;
+	float div_x,div_y;
+	float z,zpos;
+	Uint32 rgb;
+	*/
+
+	//cout << "x = " << tri->vertex1->x << endl;
+	if(tri->vertex1->y <= tri->vertex2->y) {
+		if(tri->vertex2->y <= tri->vertex3->y) {
+			//printf("condition 1\n");
+			vMin = tri->vertex1;
+			vMid = tri->vertex2;
+			vMax = tri->vertex3;
+		} else if(tri->vertex3->y <= tri->vertex1->y) {
+			//printf("condition 2\n");
+			vMin = tri->vertex3;
+			vMid = tri->vertex1;
+			vMax = tri->vertex2;
+		} else {
+			//printf("condition 3\n");
+			vMin = tri->vertex1;
+			vMid = tri->vertex3;
+			vMax = tri->vertex2;
+		}
+	} else {
+		if(tri->vertex1->y <= tri->vertex3->y) {
+			//printf("condition 4\n");
+			vMin = tri->vertex2;
+			vMid = tri->vertex1;
+			vMax = tri->vertex3;
+		} else if(tri->vertex3->y <= tri->vertex2->y) {
+			//printf("condition 5\n");
+			vMin = tri->vertex3;
+			vMid = tri->vertex2;
+			vMax = tri->vertex1;
+		} else {
+			//printf("condition 6\n");
+			vMin = tri->vertex2;
+			vMid = tri->vertex3;
+			vMax = tri->vertex1;
+		}
+	}
+
+	Vertex *vMid10 =  new Vertex(0,0,0,0,0);
+	vMid1(vMid10,vMin,vMid,vMax);
+
+	half_triangle(vMin,vMid,vMid10,image);
+	half_triangle(vMax,vMid,vMid10,image);
+
+	free(vMid10);
+#if 0
+	//cout << vMin->x << vMin->y << vMin->z << endl;
+	div_x = (int)vMid->y - (int)vMin->y;
+	if(div_x < 1 && div_x > -1) div_x = 1;
+	div_y = (int)vMax->y - (int)vMin->y;
+	if(div_y < 1 && div_y > -1) div_y = 1;
+
+	for(i = 0; i < div_x+1; i++) {
+		//$B$3$3$G(Bspan$B$N:8C<$H1&C<$N(Bx,z$B$r5a$a$F$k(B
+		tmp_xpos = calc(vMax->x - vMin->x,div_y, i, vMin->x);
+		tmp_end =  calc(vMid->x - vMin->x,div_x, i, vMin->x);	
+		tmp_z =    calc(vMax->z - vMin->z,div_y, i, vMin->z);
+	   	tmp_zpos = calc(vMid->z - vMin->z,div_x, i, vMin->z);
+
+		//$B$3$3$+$i(Bspan$B$N:8C<$H1&C<$KBP1~$9$k%F%/%9%A%c$r7W;;$9$k(B
+		tmp_tex1 =( (i/(div_y)) * vMax->tex_x) + \
+			   ( ((div_y - i)/(div_y)) * vMin->tex_x); 
+		tmp_tex2 =( (i/(div_x)) * vMid->tex_x) + \
+			   ( ((div_x - i)/(div_x)) * vMin->tex_x); 
+
+		tmp_tey1 =( (i/(div_y)) * vMax->tex_y) + \
+			   ( ((div_y - i)/(div_y)) * vMin->tex_y); 
+		tmp_tey2 =( (i/(div_x)) * vMid->tex_y) + \
+			   ( ((div_x - i)/(div_x)) * vMin->tex_y); 
+
+		//$B$3$3$G:8C<$,(Bxpos$B$+(Bend$B$rH=CG$7!"IA2h$9$k(Bspan$B$r:n$k(B
+		if(tmp_xpos > tmp_end) {
+			x = (int)tmp_end;
+			y = (int)vMin->y + i;
+			end = (int)(tmp_xpos)-(int)(tmp_end)+1;
+			z = tmp_z;
+			zpos = tmp_zpos;
+			tex1 = tmp_tex2;
+			tex2 = tmp_tex1;
+			tey1 = tmp_tey2;
+			tey2 = tmp_tey1;
+		} else {
+			x = (int)tmp_xpos;
+			y = (int)vMin->y + i;
+			end = (int)(tmp_end)-(int)(tmp_xpos)+1;
+			z = tmp_zpos;
+			zpos = tmp_z;
+			tex1 = tmp_tex1;
+			tex2 = tmp_tex2;
+			tey1 = tmp_tey1;
+			tey2 = tmp_tey2;
+		}
+		//printf("%d:%f,%f  ",(int)vMin->y + i,xpos,end);
+		//printf("%d:%d:%d:x:%d,end:%d\n",x, y , end,(int)(tmp_end),(int)(tmp_xpos));
+		//printf("x:%d y:%d end:%d z:%f zpos:%f\n",x,y,end,z , zpos);
+		//printf("tex1:%f tex2:%f tey1:%f tey2:%f\n",tex1,tex2,tey1,tey2); 
+		if(end == 1) {
+				//printf("tex_x:%f tex_y:%f\n",tex1,tex2);
+				if(tex1 > 1) tex1 = 1;
+				if(tey1 > 1) tey1 = 1;
+				tex_xpos = (int)(image->h-1) * tex1; 
+				tex_ypos = (int)(image->w-1) * tey1; 
+				tex_zpos = z;
+				//printf("tex_xpos:%d tex_ypos:%d\n",tex_xpos,tex_ypos);	
+				//printf("image->h:%d tex_x:%f\n",image->h,tex1);
+				rgb = p->get_rgb(tex_xpos,tex_ypos);	
+				//viewer->write_pixel(x,y,zpos,rgb);
+		}else {
+			for(j = 0; j < end; j++) {
+				tex_x = tex1*(end-1-j)/(end-1) + tex2*j/(end-1);
+				tex_y = tey1*(end-1-j)/(end-1) + tey2*j/(end-1);
+				tex_z = z*(end-1-j)/(end-1) + zpos*j/(end-1);
+				if(tex_x > 1) tex_x = 1;
+				if(tex_y > 1) tex_y = 1;
+				tex_xpos = (int)(image->h-1) * tex_x; 
+				tex_ypos = (int)(image->w-1) * tex_y; 
+				//printf("tex_xpos:%d tex_ypos:%d\n",tex_xpos,tex_ypos);	
+				//printf("z:%f zpos:%f tex_z:%f\n",z,zpos,tex_z);
+				//printf("tex_x:%f tex_y:%f\n",tex_x,tex_y);
+				rgb = p->get_rgb(tex_xpos,tex_ypos);	
+				//viewer->write_pixel(j+x,y,tex_z,rgb);
+			}
+		}
+	}
+
+	top_triangle = (int)vMid->y - (int)vMin->y;
+	div_x = (int)vMax->y - (int)vMid->y;
+	if(div_x < 1 && div_x > -1) div_x = 1;
+	div_y = (int)vMax->y - (int)vMin->y;
+	if(div_y < 1 && div_y > -1) div_y = 1;
+	
+	for(i = 0; i < div_x; i++) {
+		//$B$3$3$G(Bspan$B$N:8C<$H1&C<$N(Bx,z$B$r5a$a$F$k(B
+		tmp_xpos = calc(vMax->x-vMin->x, div_y, (i+1+top_triangle), vMin->x);
+		tmp_end =  calc(vMax->x-vMid->x, div_x, (i+1), vMid->x);	
+		tmp_z =    calc(vMax->z-vMin->z, div_y, (i+1+top_triangle), vMin->z);
+        tmp_zpos = calc(vMax->z-vMid->z, div_x, (i+1), vMid->z);
+
+		tmp_tex1 =( ((i + 1 +top_triangle)/(div_y)) * vMax->tex_x) + \
+			   ( ((div_y - i - 1 - top_triangle)/(div_y)) * vMin->tex_x); 
+		tmp_tex2 =( ((i+1)/(div_x)) * vMax->tex_x) + \
+			   ( ((div_x - i -1)/(div_x)) * vMid->tex_x); 
+
+		tmp_tey1 =( ((i+1+top_triangle)/(div_y)) * vMax->tex_y) + \
+			   ( ((div_y - i - 1 - top_triangle)/(div_y)) * vMin->tex_y); 
+		tmp_tey2 =( ((i+1)/(div_x)) * vMax->tex_y) + \
+			   ( ((div_x - i -1)/(div_x)) * vMid->tex_y); 
+		if(tmp_xpos > tmp_end) {
+			x = (int)tmp_end;
+			y = (int)vMid->y+i+1;
+			end = (int)(tmp_xpos)-(int)(tmp_end)+1;
+			z = tmp_z;
+			zpos = tmp_zpos;
+			tex1 = tmp_tex2;
+			tex2 = tmp_tex1;
+			tey1 = tmp_tey2;
+			tey2 = tmp_tey1;
+		} else {
+			x = (int)tmp_xpos;
+			y = (int)vMid->y+i+1;
+			end = (int)(tmp_end)-(int)(tmp_xpos)+1;
+			z = tmp_zpos;
+			zpos = tmp_z;
+			tex1 = tmp_tex1;
+			tex2 = tmp_tex2;
+			tey1 = tmp_tey1;
+			tey2 = tmp_tey2;
+		}
+		if(end == 0) end = 1;
+		//printf("%d:%d:%d\n",x, y , end);
+		//printf("x:%d y:%d end:%d z:%f zpos:%f\n",x,y,end,z,zpos);
+		//printf("tex1:%f tex2:%f tey1:%f tey2:%f\n",tex1,tex2,tey1,tey2); 
+		if(end == 1) {
+				//printf("tex_x:%f tex_y:%f\n",tex1,tex2);
+				if(tex1 > 1) tex1 = 1;
+				if(tey1 > 1) tey1 = 1;
+				tex_xpos = (int)(image->h-1) * tex1; 
+				tex_ypos = (int)(image->w-1) * tey1; 
+				tex_zpos = z;
+				//printf("tex_x:%f tex_y:%f\n",tex_x,tex_y);
+				//printf("tex_xpos:%d tex_ypos:%d\n",tex_xpos,tex_ypos);	
+				//printf("tex_x:%f tex_y:%f\n",tex_x,tex_y);
+				rgb = p->get_rgb(tex_xpos,tex_ypos);	
+				//viewer->write_pixel(x,y,tex_zpos,rgb);
+		}else {
+			for(j = 0; j < end; j++) {
+				tex_x = tex1*(end-1-j)/(end-1) + tex2*j/(end-1);
+				tex_y = tey1*(end-1-j)/(end-1) + tey2*j/(end-1);
+				tex_z = z*(end-1-j)/(end-1) + zpos*j/(end-1);
+				//printf("tex_x:%f tex_y:%f\n",tex_x,tex_y);
+				if(tex_x > 1) tex_x = 1;
+				if(tex_y > 1) tex_y = 1;
+				tex_xpos = (int)(image->h-2) * tex_x; 
+				tex_ypos = (int)(image->w-1) * tex_y; 
+				//printf("z:%f zpos:%f tex_z:%f\n",z,zpos,tex_z);
+				//printf("tex_xpos:%d tex_ypos:%d\n",tex_xpos,tex_ypos);	
+				//printf("tex_x:%f tex_y:%f\n",tex_x,tex_y);
+				//printf("tex_x:%f tex_y:%f\n",tex_x,tex_y);
+				rgb = p->get_rgb(tex_xpos,tex_ypos);	
+				//viewer->write_pixel(j+x,y,tex_z,rgb);
+			}
+		}
+	}
+#endif
+}
+
+// i:$BJ,;R!"(Bf1:$BD9$5(B   f2:$BBP1~$9$kD:E@(B1    f3:$BBP1~$9$kD:E@(B2
+/*
+float Span::calc2(int i, float f1, float f2, float f3) {
+	float ans;
+	ans = i/f1 * f2 + (f1-i)/f1  * f3;
+
+	*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/SpanC.h	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,20 @@
+#ifndef INCLUDE_Span
+#define INCLUDE_Span
+
+#include "triangle.h"
+#include "viewer.h"
+#include "polygon.h"
+
+class Span_c {
+public:
+    int x,y,end;
+    float z,zpos;
+    float tex1,tex2,tey1,tey2;
+    void create_span(Triangle *tri,SDL_Surface *image);
+    // float calc(float f1, float f2,int i, float base);
+    void half_triangle(Vertex*, Vertex*, Vertex*, SDL_Surface *image);
+    Viewer *viewer;
+    Polygon *p;
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/SpanPack.h	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,53 @@
+#ifndef INCLUDED_SPAN_PACK
+#define INCLUDED_SPAN_PACK
+
+#ifndef INCLUDED_SPAN
+#  include "Span.h"
+#endif
+
+#define MAX_SIZE_SPAN 64
+
+class SpanPack {
+public: /* fields */
+    struct SpanInfo {
+	int start;
+	int size;
+	int y_top;
+	int light_pos[3];
+	int light_rgb[3];
+    } info; // 36
+
+    Span span[MAX_SIZE_SPAN]; // 48*MAX_SIZE_SPAN = 3072
+    SpanPack *next; // 4
+
+    int pad[2]; // 8
+
+    void init(int ytop) {
+	this->info.start = 0;
+	this->info.size = 0;
+	this->info.y_top = ytop;
+	this->next = NULL;
+    }
+
+    void reinit(int ytop) {
+	SpanPack* top = this;
+	SpanPack* p;
+	SpanPack* p1;
+
+	p = top->next;
+	while (p != NULL) {
+	    p1 = p->next;
+	    free(p);
+	    p = p1;
+	}
+	
+	this->info.start = 0;
+	this->info.size = 0;
+	this->info.y_top = ytop;
+	this->next = NULL;
+    }
+};
+
+typedef SpanPack* SpanPackPtr;
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/Tapestry.h	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,124 @@
+#ifndef INCLUDED_TAPESTRY
+#define INCLUDED_TAPESTRY
+
+#ifndef INCLUDED_TYPES
+#  include "types.h"
+#endif
+
+#ifndef INCLUDED_VIEWER_TYPES
+#  include "viewer_types.h"
+#endif
+
+/**
+ * image file name と tapestry DB の binary tree
+ *
+ * // PPE
+ * main memory の tapestry DB (Array)
+ * tapestry DB への accessor 
+ *
+ *   TapestryPtr getTapestry(int TapestryID);
+ *   TilePtr getTile(TapestryPtr tapsetry, int tx, int ty, int scale);
+ *
+ * SPE が生成する tapestry List (in CreateSpan)
+ *   (no texture image)
+ *   @in  TapestryDBPtr, Tapestry ID, x, y, tx, ty, px, py
+ *     x, y   : polygon の中の平面座標
+ *     tx, ty : texture の座標
+ *     px, py : texture の分割数
+ *
+ *   @out (TilePtr, tix1, tiy1, tix2, tiy2)*
+ * 
+ *
+ * SPE に渡す tapestry List
+ *   @in Tile
+ *
+ * // SPE
+ * SPE 内部での tapestry DB (Hash)
+ *   TapestryID, scale, TilePtr, Tile
+ *
+ *
+ * SPE 内部での tapestry DB への accessor
+ *   TileEntryPtr getTile(int TapestryID, int tx, int ty, int scale);
+ *
+ *   if (TileEntry == NULL) {
+ *      DMA read
+ *   }
+ *  
+ *
+ * Rendering
+ *   1pass Zbuffer と Texture の有無の判定
+ *     if (zbuffer ok) {
+ *       if (texture ある) {
+ *         zbuffer 、linebunf に書き込む
+ *       } else {
+ *         texture の load list に加える
+ *         zbuffer だけ更新しておく
+ *       }
+ *     } else {
+ *       無視
+ *     }
+ *
+ *    1pass で texture が一杯になったら、中断して
+ *    ここまでのを書き込んどけ
+ *
+ *
+ *    2pass rgb の書き込み
+ *
+ *    if (zbuffer の値が自分と一緒) {
+ *       read した texture みて
+ *       書き込め!
+ *    }
+ *
+ */
+struct texture_block {
+    
+};
+
+typedef struct {
+    uint32 pixel[TEXTURE_BLOCK_SIZE]; // 8*8
+    uint32 *texture_addr;
+    int pad[3];
+} Tile, *TilePtr;
+
+#define MAX_TILE 128
+
+/**
+ * TileList 中の Tile の追い出しは、現在 FIFO で実装している
+ */
+class TileList {
+public:
+    int curIndex;
+    int pad[3];
+    Tile tile[MAX_TILE];
+
+    TileList(void) {
+	curIndex = 0;
+    }
+
+    /**
+     * 次に扱う tile を取得する
+     *
+     * @return tile
+     *
+     * tile[] をリングバスっぽく扱うことで
+     * FIFO を実現することに。
+     */
+    TilePtr nextTile(void) {
+	TilePtr t = &tile[curIndex];
+	curIndex = (curIndex + 1) % MAX_TILE;
+	return t;
+    }
+
+    /**
+     * TileList のクリア
+     * //tile 自体は clear する必要は無い
+     * あるかもしれない
+     */
+    void clear(void) {
+	curIndex = 0;
+    }
+};
+
+typedef TileList* TileListPtr;
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/TextureHash.cpp	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,51 @@
+#include <string.h>
+#include <stdlib.h>
+#include "TextureHash.h"
+
+int id_count;
+
+TextureHash::TextureHash(void)
+{
+    table = (hashtable*)malloc(sizeof(hashtable)*TABLE_SIZE);
+
+    for (int i = 0; i < TABLE_SIZE; i++) {
+	table[i].tx_id = -1;
+	table[i].key = NULL;
+    }
+}
+
+TextureHash::~TextureHash(void)
+{
+    free(table);
+}
+
+int
+TextureHash::hash_function(const char *key)
+{
+    //float value = 0.0;
+    int value = 0;
+
+    for (int i = 0; key[i]; i++) {
+	value += key[i]*(i+1)*17+1;
+    }
+
+    return value%TABLE_SIZE;
+}
+
+int
+TextureHash::hash_regist(const char* key)
+{
+    int hash = hash_function(key);
+    
+    for (int i = 0; ; i++) {
+	if (table[hash].tx_id == -1) {
+	    table[hash].key   = (char*)key;
+	    table[hash].tx_id = id_count++;
+	    return -1;
+	} else if (strcmp(key, table[hash].key) == 0
+		   && table[hash].tx_id != -1){
+	    return table[hash].tx_id;
+	}
+	hash = ((37*hash)^(11*i)) % TABLE_SIZE;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/TextureHash.h	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,21 @@
+#ifndef INCLUDED_TEXTURE_HASH
+#define INCLUDED_TEXTURE_HASH
+
+const int TABLE_SIZE = 8192;
+
+struct hashtable{
+    int tx_id;
+    char* key;
+};
+
+class TextureHash {
+public:
+    hashtable *table;
+
+    TextureHash(void);
+    ~TextureHash(void);
+    int hash_function(const char*);
+    int hash_regist(const char*);
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/ball_bound.cpp	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,126 @@
+#include <math.h>
+#include <stdlib.h>
+#include "SceneGraphRoot.h"
+#include "SGList.h"
+
+// prototype
+static void ball_move(SceneGraphPtr node, int screen_w, int screen_h);
+static void ball_collision(SceneGraphPtr node, int screen_w, int screen_h, SceneGraphPtr tree);
+static void ball_collision_idle(SceneGraphPtr, int w, int h, SceneGraphPtr tree);
+
+
+static float vy = 0.0f; // y 方向速度
+static float dt = 1.0/1.0f; // frame rate 
+
+static float e = -0.8f;  // 反発係数
+static float g = 9.8f;  // 重力加速度
+//static float v0 = 0.0f; // 初速は 0
+
+static float h0; // 初期高さ
+static float ball_radius = 100.0f;
+
+static int speed = 10.0f;
+
+static void
+ball_move_idle2(SceneGraphPtr node, int screen_w, int screen_h)
+{
+    Pad *pad = sgroot->getController();
+
+    if (pad->circle.isHold()) {
+	if (pad->left.isHold()) {
+	    node->xyz[0] -= speed;
+	    if(node->xyz[0] < ball_radius)
+	        node->xyz[0] = ball_radius;
+	} else if (pad->right.isHold()) {
+	    node->xyz[0] += speed;
+	    if(node->xyz[0] > screen_w  - ball_radius)
+  	        node->xyz[0] = screen_w - ball_radius;
+	}
+
+	if (pad->up.isHold()) {
+	    node->xyz[1] -= speed;
+	} else if (pad->down.isHold()) {
+	    node->xyz[1] += speed;
+            if(node->xyz[1] > screen_h - ball_radius)
+	        node->xyz[1] = screen_h - ball_radius;
+	}
+    } else {
+	node->set_move_collision(ball_move, ball_collision);
+    }
+}
+
+static int time = 0;
+
+static void
+ball_move_idle(SceneGraphPtr node, int screen_w, int screen_h)
+{
+    Pad *pad = sgroot->getController();
+
+    if (pad->circle.isPush()) {
+	node->set_move_collision(ball_move_idle2, ball_collision_idle);
+	time = 0;
+    }
+
+    time++;
+
+    if (time > 90) {
+      float w = (float)random();
+      
+      w = fmodf(w, screen_w - ball_radius*2);
+      node->xyz[0] = w + ball_radius;
+      node->xyz[1] = h0;
+      node->set_move_collision(ball_move, ball_collision);
+      time = 0;
+    }
+}
+
+static void
+ball_move(SceneGraphPtr node, int screen_w, int screen_h)
+{
+    vy += g * dt;
+    node->xyz[1] += vy * dt;
+    //    node->xyz[0] += 10.0f;
+}
+
+static void
+ball_collision_idle(SceneGraphPtr, int w, int h, SceneGraphPtr tree)
+{
+}
+
+static void
+ball_collision(SceneGraphPtr node, int screen_w, int screen_h,
+	       SceneGraphPtr tree)
+{
+    if (node->xyz[1] > screen_h - ball_radius) {
+	node->xyz[1] = screen_h - ball_radius;
+
+	vy *= e;
+	if (vy > -g && vy < 0) {
+	    vy = 0.0;
+	    node->set_move_collision(ball_move_idle, ball_collision_idle);
+	}
+    }
+}
+
+
+void
+ball_bound_init(int screen_w, int screen_h)
+{
+    SceneGraphPtr ball;
+
+    srandom(100);
+
+    sgroot->createFromXMLfile("xml_file/Ball.xml");
+    ball = sgroot->createSceneGraph(Ball);
+    ball->set_move_collision(ball_move, ball_collision);
+
+    h0 = screen_h/2;
+    h0 = -1000;
+
+    ball->xyz[0] = screen_w/2;
+    //ball->xyz[0] = 0.0f;
+    ball->xyz[1] = h0;
+    ball->xyz[2] = 30.0f;
+
+    sgroot->setSceneData(ball);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/base64_de.cpp	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,91 @@
+#include <iostream>
+#include <fstream>
+using namespace std;
+
+class tagTT
+{
+public:
+  unsigned char buf;
+  char *cont;
+  int nlen;
+};
+
+
+unsigned char CtoNum(int c)
+{
+  if (c >= 'A' && c <= 'Z') return c-'A';
+  if (c >= 'a' && c <= 'z') return (c - 'a')+26;
+  if (c >= '0' && c <= '9') return (c - '0')+52;
+  if (c == '+') return 62;
+  if (c == '/') return 63;
+  return 0;
+}
+
+
+int GetNumB64(tagTT &pWork)
+{
+  char wr;
+  unsigned char w;
+  unsigned char r;
+  
+  wr = *pWork.cont;
+  pWork.cont++;
+  if (wr=='\0' || wr=='=')
+    return -1;
+  
+  while(wr=='\n' || wr=='\t')
+    {
+      wr = *pWork.cont;
+      pWork.cont++;
+    }
+
+  w = CtoNum(wr);
+  if (pWork.nlen == 0)
+    {
+      unsigned char w2;
+
+      wr = *pWork.cont;
+      pWork.cont++;
+      if (wr!='\0' && wr!='=')
+        w2 = CtoNum(wr);
+      else
+        w2 = 0;
+
+      pWork.buf = w << 2;
+      w = w2;
+      pWork.nlen = 6;
+    }
+
+  pWork.nlen -= 2;     
+
+  r = pWork.buf | (w >> pWork.nlen);
+
+  pWork.buf = (w << (8 - pWork.nlen));
+  return r;
+}
+
+
+//int decode(char *cont, char *file_name)
+int decode(char *cont, FILE *outfile)
+{
+  int rw;
+  tagTT work;
+
+  //ofstream outfile(file_name);
+  
+  work.buf = 0;
+  work.nlen = 0;
+  work.cont = cont;
+  
+  rw = GetNumB64(work);
+  while ( rw != -1 ) 
+    {
+      //outfile << (char)rw;
+      putc(rw, outfile);
+      rw = GetNumB64(work);
+    }
+
+  //outfile.close();
+
+  return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/boss1_action.cpp	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,230 @@
+#include "boss1_action.h"
+
+static void
+null_collision(SceneGraphPtr node, int screen_w, int screen_h,
+	       SceneGraphPtr tree)
+{
+}
+
+static void
+boss1_move_right(SceneGraphPtr node, int screen_w, int screen_h) {
+  node->xyz[0] += node->stack_xyz[0];
+  if(node->xyz[0] > (screen_w - boss_radius_x)) {
+    node->set_move_collision(boss1_move_left, null_collision);
+  }
+}
+
+//ボスが左に移動する動作
+static void
+boss1_move_left(SceneGraphPtr node, int screen_w, int screen_h) {
+  node->xyz[0] -= node->stack_xyz[0];
+  if(node->xyz[0] < boss_radius_x) {
+    node->set_move_collision(boss1_move_right, null_collision);
+  }
+}
+
+static void
+player_move(SceneGraphPtr node, int screen_w, int screen_h)
+{
+  Pad *pad = sgroot->getController();
+  
+  if (pad->left.isPush()
+      || pad->left.isHold()) {
+#if 0
+    SceneGraphPtr player_left;
+    player_left =  sgroot->createSceneGraph(PLAYER_L);
+    player_left->set_move_collision(player_move_left, null_collision);
+    player_left->xyz[0] = node->xyz[0];
+    player_left->xyz[1] = node->xyz[1];
+    node->addChild(player_left);
+    node->flag_drawable = 1;
+#endif
+    node->xyz[0] -= player_speed;
+    
+    if (node->xyz[0] - player_radius< 0) {
+      node->xyz[0] = player_radius;
+    }
+  }
+  
+  
+  if (pad->right.isPush()
+      || pad->right.isHold()) {
+    node->xyz[0] += player_speed;
+    
+    if (node->xyz[0] + player_radius > screen_w) {
+      node->xyz[0] = screen_w - player_radius;
+    }
+  }
+  
+  if (pad->up.isPush()
+      || pad->up.isHold()) {
+    node->xyz[1] -= player_speed;
+    
+    if (node->xyz[1] - player_radius < 0) {
+      node->xyz[1] = player_radius;
+    }
+  }
+  
+  if (pad->down.isPush()
+      || pad->down.isHold()) {
+    node->xyz[1] += player_speed;
+    
+    if (node->xyz[1] + player_radius > screen_h) {
+      node->xyz[1] = screen_h - player_radius;
+    }
+  }
+  
+  if (pad->circle.isPush()) {
+    SceneGraphPtr shot = sgroot->createSceneGraph(P_SHOT1);
+    shot->set_move_collision(shot_move, shot_collision);
+    shot->xyz[0] = node->xyz[0];
+    shot->xyz[1] = node->xyz[1] - player_radius;
+    node->addBrother(shot);
+  }    
+}
+
+static void
+player_collision(SceneGraphPtr node, int screen_w, int screen_h,
+		 SceneGraphPtr tree)
+{
+  //自機とボスのx,y座標での距離と2点間の距離
+  static float x_distant, y_distant, distance;
+  //ボスの四角形の四隅の座標
+  //  static float boss_low_x, boss_low_y, boss_high_x, boss_high_y;
+  
+  SceneGraphIteratorPtr it = sgroot->getIterator(tree);
+  
+  
+  for (; it->hasNext(BOSS1);) {
+    it->next(BOSS1);
+    SceneGraphPtr enemy = it->get();
+    
+    //各変数の初期化
+    x_distant = node->xyz[0] - enemy->xyz[0];
+    y_distant = node->xyz[1] - enemy->xyz[1];
+    
+    //hypotfで2点間の距離を求める
+    distance = hypotf(x_distant, y_distant);
+    
+    /*四角形と円のcollision
+    if( (fabs( node->xyz[1] - ( boss_low_y )))
+    */
+    
+    //円同士のcollision
+    if(distance < (player_radius + boss_radius_y)) {
+      printf("!!!CAUTION!!!\n");
+    }
+  }
+}
+
+static void
+shot_move(SceneGraphPtr node, int screen_w, int screen_h)
+{
+  node->xyz[1] -= shot_speed;
+  
+  // 描画領域から抜けたら削除
+  if (node->xyz[1] < 0) {
+    node->remove();
+  }
+}
+
+static void
+shot_collision(SceneGraphPtr node, int screen_2, int screen_h,
+	       SceneGraphPtr tree)
+{
+  //自機とボスのx,y座標での距離と2点間の距離
+  static float x_distant, y_distant, distance;
+  //ボスの四角形の四隅の座標
+  //  static float boss_low_x, boss_low_y, boss_high_x, boss_high_y;
+  
+  SceneGraphIteratorPtr it = sgroot->getIterator(tree);
+  
+  
+  for (; it->hasNext(BOSS1);) {
+    it->next(BOSS1);
+    SceneGraphPtr enemy = it->get();
+    
+    x_distant = node->xyz[0] - enemy->xyz[0];
+    y_distant = node->xyz[1] - enemy->xyz[1];
+    
+    //hypotfで2点間の距離を求める
+    distance = hypotf(x_distant, y_distant);
+    
+    //円同士のcollision
+    if(distance <  boss_radius_y) {
+      SceneGraphPtr blast = sgroot->createSceneGraph(BLAST1);
+      
+      blast->set_move_collision(blast_move, null_collision);
+      blast->xyz[0] = node->xyz[0];
+      blast->xyz[1] = node->xyz[1];
+      node->addBrother(blast);
+      node->remove();
+    }
+  }
+}
+
+static void
+blast_move(SceneGraphPtr node, int screen_w, int screen_h)
+{
+  if(node->sgid > BLAST8) {
+    SceneGraphPtr blast = sgroot->createSceneGraph(node->sgid - 1);
+    blast->set_move_collision(blast_move, null_collision);
+    blast->xyz[0] = node->xyz[0];
+    blast->xyz[1] = node->xyz[1];
+    node->addBrother(blast);
+  }
+  
+  if (node->sgid == BLAST8) {
+    node->flag_drawable = 1;
+  }
+  
+  if((node->frame > 1)) {
+    node->remove();
+  }
+  node->frame += 1;
+}
+  
+void
+boss1_init(int screen_w, int screen_h)
+{
+  SceneGraphPtr root;
+  SceneGraphPtr player;
+  SceneGraphPtr boss1;
+  SceneGraphPtr left_parts;
+  SceneGraphPtr right_parts;
+
+  sgroot->createFromXMLfile("xml_file/boss1.xml");
+  sgroot->createFromXMLfile("xml_file/player.xml");
+  sgroot->createFromXMLfile("xml_file/p_shot.xml");
+  sgroot->createFromXMLfile("xml_file/blast.xml");
+  
+  //rootとなるSceneGraphを生成
+  root = sgroot->createSceneGraph();
+  
+  //自機の初期化
+  player = sgroot->createSceneGraph(PLAYER);
+  player->xyz[0] = screen_w/2;
+  player->xyz[1] = screen_h - player_radius;
+  root->addChild(player);
+
+  //ボスの初期化
+  boss1 = sgroot->createSceneGraph(BOSS1);
+  boss1->xyz[0] = screen_w/2;
+  boss1->xyz[1] = boss_radius_y;
+  //  boss1->xyz[2] = first_boss1_depth;
+  boss1->stack_xyz[0] = first_boss1_speed;
+  root->addChild(boss1);
+
+  //ボスの左右パーツを追加
+  left_parts = sgroot->createSceneGraph(BOSS1_L);
+  boss1->addChild(left_parts);
+  right_parts = sgroot->createSceneGraph(BOSS1_R);
+  boss1->addChild(right_parts);
+
+  //各機体の動きと当たり判定をセット
+  player->set_move_collision(player_move, player_collision);  
+  boss1->set_move_collision(boss1_move_left, null_collision);
+  
+  //仕上げ
+  sgroot->setSceneData(root);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/boss1_action.h	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,54 @@
+#include <math.h>
+#include "SceneGraphRoot.h"
+#include "SGList.h"
+
+static const float player_speed = 10.0f;
+static const float player_radius = 42.0f;
+
+static const float boss_radius_x = 65.4f;
+static const float boss_radius_y = 130.8f;
+static const float first_boss1_speed = 10.0;
+static const float first_boss1_depth = 500.0;
+static const float return_boss1_depth_speed = 10.0;
+
+static const float shot_speed = 30.0f;
+static const float shot_radius = 42.4f;
+
+
+
+void
+null_move(SceneGraphPtr node, int screen_w, int screen_h);
+
+static void
+null_collision(SceneGraphPtr node, int screen_w, int screen_h,
+		SceneGraphPtr tree);
+
+static void
+boss1_move_right(SceneGraphPtr node, int screen_w, int screen_h);
+
+static void
+boss1_move_left(SceneGraphPtr node, int screen_w, int screen_h);
+
+void
+boss1_move_return(SceneGraphPtr node, int screen_w, int screen_h);
+
+void
+boss1_first_move(SceneGraphPtr node, int screen_w, int screen_h);
+
+static void
+player_move(SceneGraphPtr node,int screen_2, int screen_h);
+
+void
+player_move_left(SceneGraphPtr node,int screen_2, int screen_h);
+
+static void
+player_collision(SceneGraphPtr node, int screen_w, int screen_h,
+		SceneGraphPtr tree);
+static void
+shot_move(SceneGraphPtr node, int screen_w, int screen_h);
+
+static void
+shot_collision(SceneGraphPtr node, int screen_2, int screen_h,
+	       SceneGraphPtr tree);
+static void
+blast_move(SceneGraphPtr node, int screen_w, int screen_h);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/bullet_action.cpp	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,65 @@
+#include <math.h>
+#include "SceneGraphRoot.h"
+#include "SGList.h"
+#include "hit_judge.h"
+#define PI M_PI
+
+int i = 0;
+
+void
+bullet_init(SceneGraphPtr bullet, SceneGraphPtr player)
+{
+    bullet->xyz[0] = player->xyz[0];
+    bullet->xyz[1] = player->xyz[1];
+    bullet->xyz[2] = player->xyz[2];
+
+    bullet->angle[0] = player->angle[0];
+    bullet->angle[1] = player->angle[1];
+    bullet->angle[2] = player->angle[2];
+}
+
+void 
+bluebullet_move(SceneGraphPtr node, int screen_w, int screen_h)
+{  
+    double a = (node->angle[2]+90)*PI/180;
+    double b = (node->angle[0]+90)*PI/180;
+      
+    double y = sin(a);
+    double x = cos(a);
+    double z = -cos(b);
+    
+    node->xyz[0] += x * 5;//x軸方向
+    node->xyz[1] += y * 5;//y軸方向
+    node->xyz[2] += z * 5;//z軸方向  
+}
+
+void
+bullet_collision(SceneGraphPtr node, int screen_w, int screen_h, SceneGraphPtr tree)
+{
+    SceneGraphIteratorPtr it = sgroot->getIterator(tree);
+    //static int damage = 0;
+
+    for (; it->hasNext(E_PLANE);) {
+	it->next(E_PLANE);
+	SceneGraphPtr enemy = it->get();
+
+	int judge = square_judge(node, enemy);
+	if(judge == HIT)
+	{
+	    //node->set_move_collision(null_move, bullet_collision);
+	    //E_PLANE->set_move_collision(null_move, enemy_collision);
+	  enemy->remove();
+	    node->remove();
+	    //printf("hit!!!\n");
+	    //bullet_delete(node, scene_graph);
+	}
+    }
+
+    if(node->xyz[1] > 100)
+    {
+	node->remove();
+	//scene_graph->delete_object(node, node->next,node->prev);
+	//i -= 1;
+	//printf("bullet_delete:残り弾数=%d\n",i);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/bullet_action.h	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,3 @@
+void bullet_init(SceneGraphPtr scene_graph, SceneGraphPtr node);
+void bluebullet_move(SceneGraphPtr node, int screen_w, int screen_h);
+void bullet_collision(SceneGraphPtr node, int screen_w, int screen_h ,SceneGraphPtr tree);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/camera_action.cpp	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,58 @@
+#include "SceneGraphRoot.h"
+#include "SGList.h"
+#include "camera_action.h"
+
+#define MOVE_SPEED 0.10
+
+void
+camera_init(SceneGraphPtr node, int screen_w, int screen_h)
+{
+    node->xyz[0] = screen_w/2;
+    node->xyz[1] = screen_h/2 + 50;
+    node->xyz[2] = 0;
+    node->angle[0] = 120;
+}
+
+void
+c_move(SceneGraphPtr node, int screen_w, int screen_h)
+{
+    Pad *pad = sgroot->getController();
+
+    if(pad->right.isHold())
+    {
+	if(node->xyz[0]>screen_w/2 - 50)
+	{
+          node->xyz[0]-=MOVE_SPEED;
+        }
+    }
+
+    if(pad->left.isHold())
+    {
+      if(node->xyz[0]<screen_w/2 + 50)
+        {
+          node->xyz[0]+=MOVE_SPEED;
+        }
+    }
+
+  if(pad->down.isHold())
+    {
+      if(node->xyz[2]>-25)
+        {
+          node->xyz[2]-=MOVE_SPEED;
+        }
+    }
+
+  if(pad->up.isHold())
+  {
+      if(node->xyz[2]<25)
+      {
+          node->xyz[2]+=MOVE_SPEED;
+      }
+  }
+
+}
+
+void
+camera_collision(SceneGraphPtr node, int screen_w, int screen_h,SceneGraphPtr tree)
+{
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/camera_action.h	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,3 @@
+void camera_init(SceneGraphPtr node, int screen_w, int screen_h);
+void c_movet(SceneGraphPtr node, int screen_w, int screen_h);
+void camera_collision(SceneGraphPtr node, int screen_w, int screen_h, SceneGraphPtr tree);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/cube_action.cpp	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,132 @@
+#include <math.h>
+#include "SceneGraphRoot.h"
+#include "SGList.h"
+
+static void cube_move_left(SceneGraphPtr node, int screen_w, int screen_h);
+static void cube_move_right(SceneGraphPtr node, int screen_w, int screen_h);
+static void cube_move_idle(SceneGraphPtr node, int screen_w, int screen_h);
+static void cube_collision(SceneGraphPtr node, int screen_w, int screen_h,
+			   SceneGraphPtr tree);
+
+static void cube_split(SceneGraphPtr root);
+
+static void
+cube_move_left(SceneGraphPtr node, int screen_w, int screen_h)
+{
+    node->xyz[0] -= node->stack_xyz[0];
+    node->xyz[1] -= node->stack_xyz[0] * node->stack_xyz[1];
+    node->xyz[2] -= node->stack_xyz[0] * node->stack_xyz[2];
+
+    if (node->xyz[0] < 0) {
+	node->set_move_collision(cube_move_right, cube_collision);
+    }
+
+    if (node->xyz[1] < 0 || node->xyz[1] > screen_h) {
+	node->stack_xyz[1] = -node->stack_xyz[1];
+    }
+
+    node->angle[0] += 2.0f;
+    node->angle[1] += 2.0f * node->stack_xyz[1];
+    node->angle[2] += 2.0f * node->stack_xyz[2];
+
+    node->angle[0] = fmodf(node->angle[0], 360.0f);
+    node->angle[1] = fmodf(node->angle[1], 360.0f);
+    node->angle[2] = fmodf(node->angle[2], 360.0f);
+    
+    if (node->frame > 10 && sgroot->controller->circle.isPush()) {
+	cube_split(node);
+    }
+}
+
+static void
+cube_move_right(SceneGraphPtr node, int screen_w, int screen_h)
+{
+    node->xyz[0] += node->stack_xyz[0];
+    node->xyz[1] -= node->stack_xyz[0] * node->stack_xyz[1];
+    node->xyz[2] -= node->stack_xyz[0] * node->stack_xyz[2];
+
+    if (node->xyz[0] > screen_w) {
+	node->set_move_collision(cube_move_left, cube_collision);
+    }
+
+    if (node->xyz[1] < 0 || node->xyz[1] > screen_h) {
+	node->stack_xyz[1] = -node->stack_xyz[1];
+    }
+
+    node->angle[0] += 2.0f;
+    node->angle[1] += 2.0f * node->stack_xyz[1];
+    node->angle[2] += 2.0f * node->stack_xyz[2];
+
+    node->angle[0] = fmodf(node->angle[0], 360.0f);
+    node->angle[1] = fmodf(node->angle[1], 360.0f);
+    node->angle[2] = fmodf(node->angle[2], 360.0f);
+
+    if (node->frame > 10 && sgroot->controller->circle.isPush()) {
+	cube_split(node);
+    }
+}
+
+static void
+cube_split(SceneGraphPtr root)
+{
+    SceneGraphPtr p = root->clone();
+    root->addBrother(p);
+
+    root->set_move_collision(cube_move_left, cube_collision);
+    p->set_move_collision(cube_move_right, cube_collision);
+ 
+    p->xyz[0] = root->xyz[0] + 2;
+    p->xyz[1] = root->xyz[1];
+    p->xyz[2] = root->xyz[2];
+
+    p->stack_xyz[0] = 2.0f;
+    p->stack_xyz[1] = random()%3-1;
+    p->stack_xyz[2] = random()%3-1;
+
+    root->xyz[0] -= 2;
+    root->stack_xyz[0] = 2.0f;
+    root->stack_xyz[1] = random()%3-1;
+    root->stack_xyz[2] = random()%3-1;
+}
+
+
+static void
+cube_move_idle(SceneGraphPtr node, int screen_w, int screen_h)
+{
+    node->xyz[0] = screen_w/2;
+    node->xyz[1] = screen_h/2;
+    //node->xyz[2] = -300.0f;
+
+    if (sgroot->controller->circle.isPush()) {
+	cube_split(node);
+    }
+}
+
+static void
+cube_collision(SceneGraphPtr node, int screen_w, int screen_h,
+	       SceneGraphPtr tree)
+{
+}
+
+void
+create_cube_split(int number)
+{
+    SceneGraphPtr cube;
+    SceneGraphPtr back;
+
+    sgroot->createFromXMLfile("xml_file/cube.xml");
+
+    // 何もしない親
+    // cube は brother として繋がっていくので
+    // 親が居ないとだめ。
+    back = sgroot->createSceneGraph();
+
+    cube = sgroot->createSceneGraph(Cube);
+    cube->xyz[0] = 960.0f;
+    cube->xyz[1] = 540.0f;
+    cube->set_move_collision(cube_move_idle, cube_collision);
+
+    back->addChild(cube);
+
+    sgroot->setSceneData(back);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/demonstration.h	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,20 @@
+#ifndef INCLUDED_DEMONSTRATION
+#define INCLUDED_DEMONSTRATION
+
+#ifndef INCLUDED_POLYGON
+#include "polygon.h"
+#endif
+
+class Demonstration{
+ public:
+  Polygon *list;
+  void (Demonstration::*action_demo)();
+
+  Demonstration();
+  //~Demonstration();
+  void test_init();
+  void test_play();
+  void test_end();
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/direction.cpp	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,93 @@
+#include "SceneGraphRoot.h"
+#include "SGList.h"
+
+static void
+x_move(SceneGraphPtr node, int w, int h)
+{
+    Pad *pad = sgroot->getController();
+
+    node->xyz[0] = w/2;
+    node->xyz[1] = h/2;
+
+    if (pad->circle.isPush() || pad->circle.isHold()) {
+	node->angle[1] += 10.0f;
+	if (node->angle[1] > 360.0f) node->angle[1] = 0.0f;
+    }
+
+    if (pad->triangle.isPush() || pad->triangle.isHold()) {
+	node->angle[0] += 10.0f;
+	if (node->angle[0] > 360.0f) node->angle[0] = 0.0f;
+    }    
+
+    if (pad->start.isPush()) {
+	node->angle[0] = 0.0f;
+	node->angle[1] = 90.0f;
+    }
+    
+}
+
+static void
+y_move(SceneGraphPtr node, int w, int h)
+{
+    Pad *pad = sgroot->getController();
+
+    node->xyz[0] = w/2;
+    node->xyz[1] = h/2;
+
+    if (pad->cross.isPush() || pad->cross.isHold()) {
+	node->angle[2] += 10.0f;
+    }
+
+    if (pad->square.isPush() || pad->square.isHold()) {
+	node->angle[0] += 10.0f;
+    }
+
+    if (pad->start.isPush()) {
+	node->angle[0] = 90.0f;
+	node->angle[1] = 0.0f;
+    }
+    
+}
+
+static void
+z_move(SceneGraphPtr node, int w, int h)
+{
+    node->xyz[0] = w/2;
+    node->xyz[1] = h/2;
+}
+
+static void
+dir_collision(SceneGraphPtr node, int w, int h, SceneGraphPtr tree)
+{
+}
+
+void
+direction_init(void)
+{
+    SceneGraphPtr dx;
+    SceneGraphPtr dy;
+    SceneGraphPtr dz;
+    SceneGraphPtr back;
+
+    sgroot->createFromXMLfile("xml_file/direction.xml");
+
+    dx = sgroot->createSceneGraph(Dirx);
+    dy = sgroot->createSceneGraph(Diry);
+    dz = sgroot->createSceneGraph(Dirz);
+    back = sgroot->createSceneGraph();
+    
+    back->addChild(dx);
+    back->addChild(dy);
+    back->addChild(dz);
+
+    dx->set_move_collision(x_move, dir_collision);
+    dx->angle[1] = 90.0f;
+    dy->set_move_collision(y_move, dir_collision);
+    dy->angle[0] = 90.0f;
+    dz->set_move_collision(z_move, dir_collision);
+
+    back->angle[0] = 30.0f;
+    back->angle[1] = -30.0f;
+
+    sgroot->setSceneData(back);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/enemy_action.cpp	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,38 @@
+#include <math.h>
+#include "SceneGraph.h"
+#include "enemy_action.h"
+
+#define PI M_PI
+
+double vx = 5.0;
+
+void 
+enemy_move(SceneGraphPtr node, int screen_w, int screen_h)
+{
+  double vxr = (node->xyz[0])*PI/180;
+  if(node->xyz[0] > screen_w/2 || node->xyz[0] < -screen_w/2) 
+    {
+      vx *= -1;
+    }
+  //printf("%f\n", vx);
+  node->angle[1]+=vx;
+  
+  node->xyz[0] += vx;
+  node->xyz[1] = -sin(vxr*2)*20*vx;
+  node->xyz[2] = sin(vxr*4)*2*vx;
+}
+
+
+void
+enemy_collision(SceneGraphPtr node, int screen_w, int screen_h, SceneGraphPtr tree)
+{
+#if 0
+  int judge = square_judge(E_PLANE, BULEBULLET, tree);
+  if(judge == HIT)
+    {
+      E_PLANE->set_move_collision(null_move, enemy_collision);
+      printf("ENEMY_hit!!!_n");
+      //scene_graph->delete_object(node, node->next,node->prev);
+    }
+#endif
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/enemy_action.h	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,2 @@
+extern void enemy_move(SceneGraphPtr node, int screen_w, int screen_h);
+extern void enemy_collision(SceneGraphPtr node, int screen_w, int screen_h, SceneGraphPtr tree);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/fb.h	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,91 @@
+#if defined(__linux__)
+#include <unistd.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <linux/fb.h>
+#include <linux/fs.h>
+#include <sys/mman.h>
+#include <sys/ioctl.h>
+#include <stdlib.h>
+#include <iostream>
+using namespace std;
+
+#define DEVICE_NAME "/dev/fb0"
+#define DIV_BYTE 8
+
+/* function prototype */
+void send_current_error_msg(const char *ptr);
+void send_current_information(const char *ptr);
+
+int get_fbdev_addr(void)
+{
+	int fd_framebuffer ;
+	struct fb_var_screeninfo vinfo;
+	struct fb_fix_screeninfo finfo;
+	long int screensize ;
+	//long int location;
+	char *fbptr ;
+	char tmp[DIV_BYTE*10];
+
+	//int x , y ;
+	int xres,yres,vbpp,line_len;
+	//unsigned short tcolor ;
+
+	/* ɤ߽Ѥ˥ե򳫤 */
+	fd_framebuffer = open( DEVICE_NAME , O_RDWR);
+	if ( !fd_framebuffer ) {
+	    send_current_error_msg("Framebuffer device open error !");
+	    exit(1);
+	}
+	send_current_information("The framebuffer device was opened !");
+	
+	/* ꥹ꡼ */
+	if ( ioctl( fd_framebuffer , FBIOGET_FSCREENINFO , &finfo ) ) {
+	    send_current_error_msg("Fixed information not gotton !");
+	    exit(2);
+	}
+
+	/* ư꡼ */
+	if ( ioctl( fd_framebuffer , FBIOGET_VSCREENINFO , &vinfo ) ) {
+		send_current_error_msg("Variable information not gotton !");
+		exit(3);
+	}
+	xres = vinfo.xres ;
+	yres = vinfo.yres ;
+	vbpp = vinfo.bits_per_pixel ;
+	line_len = finfo.line_length ;
+	sprintf( tmp , "%d(pixel)x%d(line), %dbpp(bits per pixel)",xres,yres,vbpp);
+	send_current_information( tmp );
+
+	/* Хñ̤ǤΥ꡼Υ׻ */
+	screensize = xres * yres * vbpp / DIV_BYTE ;
+
+	/* ǥХ˥ޥåפ */
+	fbptr = (char *)mmap(0,screensize,PROT_READ | PROT_WRITE,MAP_SHARED,fd_framebuffer,0);
+	if ( (int)fbptr == -1 ) {
+		send_current_error_msg("Don't get framebuffer device to memory !");
+		exit(4);
+	}
+	send_current_information("The framebuffer device was mapped !");
+
+	printf("fb: 0x%x \n", (unsigned int)fbptr);
+	return (int)fbptr;
+	//munmap(fbptr,screensize);
+	//close(fd_framebuffer);
+	//return 0;
+}
+
+void send_current_error_msg(const char *ptr)
+{
+    fprintf( stderr , "%s\n" , ptr );
+}
+
+void send_current_information(const char *ptr)
+{
+    fprintf( stdout , "%s\n" , ptr );
+}
+#else /* !defined(__linux__) */
+int get_fbdev_addr(void) {return 0;}
+#endif /* defined(__linux__) */
+
+extern int get_fbdev_addr(void);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/hash_texture.h	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,15 @@
+const int N = 8192;
+
+struct
+hashtable{
+    int tx_id;
+    char* key;
+};
+
+class TextureHash {
+    hashtable table[N];
+public:
+    hash(void);
+    int hash_function(const char*);
+    int hash_regist(const char*);
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/hit_judge.cpp	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,80 @@
+#include "SceneGraph.h"
+#include "hit_judge.h"
+#include "SGList.h"
+
+#define FUSELAGE_W 6
+#define FUSELAGE_H 6
+#define FUSELAGE_Z 6
+#define E_PLANE_W 6*4
+#define E_PLANE_H 6*4
+#define E_PLANE_Z 6*4
+#define BULLTE_W 2*4
+#define BULLTE_H 6*4
+#define BULLTE_Z 2*4
+
+int 
+square_judge(SceneGraphPtr oneself, SceneGraphPtr partner)
+{
+  int ow = 0, oh = 0, oz = 0;
+  int pw = 0, ph = 0, pz = 0;
+  if (oneself->sgid == IDLE)
+    {
+      ow = FUSELAGE_W;
+      oh = FUSELAGE_H;
+      oz = FUSELAGE_Z;
+    }
+  else if (oneself->sgid == E_PLANE)
+    {
+      ow = E_PLANE_W;
+      oh = E_PLANE_H;
+      oz = E_PLANE_Z;
+    }
+  else if(oneself->sgid == BULEBULLET)
+    {
+      ow = BULLTE_W;
+      oh = BULLTE_H;
+      oz = BULLTE_Z;
+    }
+  if(partner->sgid == IDLE)
+  {
+	pw = FUSELAGE_W;
+	ph = FUSELAGE_H;
+	pz = FUSELAGE_Z;
+  }
+  else if(partner->sgid == E_PLANE)
+  {
+      pw = E_PLANE_W;
+      ph = E_PLANE_H;
+      pz = E_PLANE_Z;
+  }
+  else if(partner->sgid == BULEBULLET)
+    {
+      pw = BULLTE_W;
+      ph = BULLTE_H;
+      pz = BULLTE_Z;
+    }
+
+
+  int ox_min = (int)(oneself->xyz[0] + oneself->c_xyz[0] - ow/2);
+  int oy_min = (int)(oneself->xyz[1] + oneself->c_xyz[1] - oh/2);
+  int oz_min = (int)(oneself->xyz[2] + oneself->c_xyz[2] - oz/2);
+
+  int ox_max = (int)(oneself->xyz[0] + oneself->c_xyz[0] + ow/2);
+  int oy_max = (int)(oneself->xyz[1] + oneself->c_xyz[1] + oh/2);
+  int oz_max = (int)(oneself->xyz[2] + oneself->c_xyz[2] + oz/2);
+
+  int px_min = (int)(partner->xyz[0] + partner->c_xyz[0] - pw/2);
+  int py_min = (int)(partner->xyz[1] + partner->c_xyz[1] - ph/2);
+  int pz_min = (int)(partner->xyz[2] + partner->c_xyz[2] - pz/2);
+
+  int px_max = (int)(partner->xyz[0] + partner->c_xyz[0] + pw/2);
+  int py_max = (int)(partner->xyz[1] + partner->c_xyz[1] + ph/2);
+  int pz_max = (int)(partner->xyz[2] + partner->c_xyz[2] + pz/2);
+
+  if(ox_max < px_min || px_max < ox_min || oy_max < py_min || py_max < oy_min || oz_max < pz_min || pz_max < oz_min)
+  {
+  }  else {
+      return HIT;
+  }
+  return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/hit_judge.h	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,7 @@
+#define TOUCH_LOWER 1
+#define TOUCH_TOP 2
+#define TOUCH_RIGHT 3
+#define TOUCH_LEFT 4
+#define HIT 5
+
+extern int square_judge(SceneGraphPtr oneself, SceneGraphPtr partner);
Binary file Renderer/test_render/icon.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/ieshoot.cpp	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,216 @@
+#include "SceneGraphRoot.h"
+#include "SGList.h"
+
+static const float jiki_speed = 6.0f;
+static const float jiki_radius = 32.0f;
+
+static const float tama_speed = 10.0f;
+static const float tama_radius = 16.0f;
+
+static const float boss_radius_x = 64.0f;
+static const float boss_radius_y = 128.0f;
+
+static const float iebosstama_speed = 15.0f;
+
+static void
+ieboss_collision(SceneGraphPtr node, int screen_w, int screen_h,
+		 SceneGraphPtr tree);
+static void
+ieboss_collision_invincibil(SceneGraphPtr node, int screen_w, int screen_h, SceneGraphPtr tree);
+static void ieboss_move(SceneGraphPtr node, int screen_w, int screen_h);
+
+static void iebosstama_move(SceneGraphPtr node, int screen_w, int screen_h);
+
+
+static void
+iejiki_collision(SceneGraphPtr node, int screen_w, int screen_h,
+	       SceneGraphPtr tree)
+{
+}
+
+static void
+ietama_collision(SceneGraphPtr node, int screen_w, int screen_h,
+		 SceneGraphPtr tree)
+{
+}
+
+static void
+ieboss_collision(SceneGraphPtr node, int screen_w, int screen_h,
+		 SceneGraphPtr tree)
+{
+    SceneGraphIteratorPtr it = sgroot->getIterator(tree);
+    static int damage = 0;
+
+    for (; it->hasNext(IETAMA);) {
+	it->next(IETAMA);
+	SceneGraphPtr tama = it->get();
+
+	if (node->xyz[0] - boss_radius_x < tama->xyz[0] + tama_radius
+	    && node->xyz[0] + boss_radius_x > tama->xyz[0] - tama_radius
+	    && node->xyz[1] + boss_radius_y > tama->xyz[1] - tama_radius) {
+	    tama->remove();
+
+	    node->set_move_collision(ieboss_move, ieboss_collision_invincibil);
+
+	    SceneGraphPtr iebosstama = sgroot->createSceneGraph(Earth);
+	    iebosstama->set_move_collision(iebosstama_move, ietama_collision);
+	    iebosstama->xyz[0] = node->xyz[0];
+	    iebosstama->xyz[1] = node->xyz[1] + boss_radius_y;
+	    //iebosstama->xyz[2] = 50.0f;
+	    node->addBrother(iebosstama);
+
+	    damage++;
+	}
+    }
+
+    if (damage > 10) {
+	node->remove();
+    }
+}
+
+static void
+ieboss_move(SceneGraphPtr node, int screen_w, int screen_h)
+{
+    /**
+     * TODO
+     *  Boss が複数居た場合、これじゃ駄目
+     */
+    static int x_speed = 5.0f;
+    static int z_speed = 5.0f;
+
+    node->xyz[0] += x_speed;
+
+    if (node->xyz[0] - boss_radius_x < 0) {
+	x_speed = -x_speed;
+	node->xyz[0] = boss_radius_x;
+    } else if (node->xyz[0] + boss_radius_x > screen_w) {
+	x_speed = -x_speed;
+	node->xyz[0] = screen_w - boss_radius_x;
+    }
+
+    //node->xyz[2] += z_speed;
+    if (node->xyz[2] >= 100.0f) {
+	node->xyz[2] = 99.99f;
+	z_speed = -z_speed;
+    } else if (node->xyz[2] <= -100.0f) {
+	node->xyz[2] = -99.99f;
+	z_speed = -z_speed;
+    }
+}
+
+static void
+ieboss_collision_invincibil(SceneGraphPtr node, int screen_w, int screen_h,
+			    SceneGraphPtr tree)
+{
+    static int frame = 0;
+
+    frame++;
+
+    node->flag_drawable ^= 1;
+
+    if (frame > 60) {
+	frame = 0;
+	node->flag_drawable = 1;
+	node->set_move_collision(ieboss_move, ieboss_collision);
+    }
+}
+
+static void
+iebosstama_move(SceneGraphPtr node, int screen_w, int screen_h)
+{
+    node->xyz[1] += iebosstama_speed;
+
+    // 描画領域から抜けたら削除
+    if (node->xyz[1] > screen_h) {
+	node->remove();
+    }
+}
+
+static void
+ietama_move(SceneGraphPtr node, int screen_w, int screen_h)
+{
+    node->xyz[1] -= tama_speed;
+
+    // 描画領域から抜けたら削除
+    if (node->xyz[1] < 0) {
+	node->remove();
+    }
+}
+
+static void
+iejiki_move(SceneGraphPtr node, int screen_w, int screen_h)
+{
+    Pad *pad = sgroot->getController();
+
+    if (pad->left.isPush()
+	|| pad->left.isHold()) {
+	node->xyz[0] -= jiki_speed;
+
+	if (node->xyz[0] - jiki_radius< 0) {
+	    node->xyz[0] = jiki_radius;
+	}
+    }
+
+    if (pad->right.isPush()
+	|| pad->right.isHold()) {
+	node->xyz[0] += jiki_speed;
+
+	if (node->xyz[0] + jiki_radius > screen_w) {
+	    node->xyz[0] = screen_w - jiki_radius;
+	}
+    }
+
+    if (pad->up.isPush()
+	|| pad->up.isHold()) {
+	node->xyz[1] -= jiki_speed;
+
+	if (node->xyz[1] - jiki_radius < 0) {
+	    node->xyz[1] = jiki_radius;
+	}
+    }
+
+    if (pad->down.isPush()
+	|| pad->down.isHold()) {
+	node->xyz[1] += jiki_speed;
+
+	if (node->xyz[1] + jiki_radius > screen_h) {
+	    node->xyz[1] = screen_h - jiki_radius;
+	}
+    }
+
+    if (pad->circle.isPush()) {
+	SceneGraphPtr ietama = sgroot->createSceneGraph(IETAMA);
+	ietama->set_move_collision(ietama_move, ietama_collision);
+	ietama->xyz[0] = node->xyz[0];
+	ietama->xyz[1] = node->xyz[1];
+	node->addBrother(ietama);
+    }
+}
+
+
+void
+ieshoot_init(void)
+{
+    SceneGraphPtr iejiki;
+    SceneGraphPtr enemy;
+    SceneGraphPtr back;
+
+    sgroot->createFromXMLfile("xml_file/ietama.xml");
+    sgroot->createFromXMLfile("xml_file/ieboss.xml");
+    sgroot->createFromXMLfile("xml_file/iejiki.xml");
+    sgroot->createFromXMLfile("xml_file/universe.xml");
+
+    back = sgroot->createSceneGraph();
+
+    iejiki = sgroot->createSceneGraph(IEJIKI);
+    iejiki->set_move_collision(iejiki_move, iejiki_collision);
+    iejiki->xyz[2] = 20;
+    back->addChild(iejiki);
+
+    enemy = sgroot->createSceneGraph(IEBOSS);
+    enemy->set_move_collision(ieboss_move, ieboss_collision);
+    enemy->xyz[1] = boss_radius_y;
+    back->addChild(enemy);
+
+    sgroot->setSceneData(back);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/init_position.cpp	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,36 @@
+#include "SceneGraphRoot.h"
+#include "SGList.h"
+#include "player_action.h"
+#include "enemy_action.h"
+#include "camera_action.h"
+
+void
+init_position(int w, int h)
+{
+    SceneGraphPtr back;
+    SceneGraphPtr player;
+    SceneGraphPtr enemy;
+    //SceneGraphPtr bullet;
+
+    sgroot->createFromXMLfile("xml_file/player.xml");
+    back   = sgroot->createSceneGraph(BACK);
+    //back = sgroot->createSceneGraph();
+    player = sgroot->createSceneGraph(IDLE);
+    //bullet = sgroot->createSceneGraph(BULEBULLET);
+    
+    camera_init(back, w, h);
+    back->set_move_collision(camera_init, camera_collision);
+    player->set_move_collision(player_move_all, player_collision);
+
+
+    back->addChild(player);
+
+    for (int i = 0; i < 10; i++) {
+	enemy  = sgroot->createSceneGraph(E_PLANE);
+	enemy->set_move_collision(enemy_move, enemy_collision);
+	enemy->xyz[0] = 50.0*i;
+	back->addChild(enemy);
+    }
+
+    sgroot->setSceneData(back);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/long_cube.cpp	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,31 @@
+#include "SceneGraphRoot.h"
+#include "SGList.h"
+
+// prototype
+static void lcube_move(SceneGraphPtr node, int screen_w, int screen_h);
+//static void lcube_collision(SceneGraphPtr node, int screen_w, int screen_h);
+
+
+static void
+lcube_move(SceneGraphPtr node, int screen_w, int screen_h)
+{
+}
+
+static void
+lcube_collision(SceneGraphPtr node, int screen_w, int screen_h,
+	       SceneGraphPtr tree)
+{
+}
+
+
+void
+lcube_init(int screen_w, int screen_h)
+{
+    SceneGraphPtr lcube;
+
+    sgroot->createFromXMLfile("xml_file/LongCube.xml");
+    lcube = sgroot->createSceneGraph(LongCube);
+    lcube->set_move_collision(lcube_move, lcube_collision);
+
+    sgroot->setSceneData(lcube);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/main.cpp	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,101 @@
+#include "TaskManager.h"
+#include "viewer.h"
+#include "viewerSDL.h"
+#include "viewerFB.h"
+#include "Func.h"
+
+/* prototype */
+static int init(int argc, char *argv[]);
+static void TMend(void);
+
+extern void task_initialize();
+
+Viewer *screen;
+
+static int sg_number = 0;
+
+static const char *help_str = "Usage: ./test_nogl [OPTION]\n\
+  -cpu Number of SPE (default 1)\n\
+  -width, -height window size (default 640x480)\n\
+  -sg Draw SceneGraph\n\
+      0: Joystick の 丸ボタン(Keyboard だとx) を押すと、キューブが二つに分かれる\n\
+      1: 0 のキューブが大きい版\n\
+      2: テクスチャテスト:576x384\n\
+      3: テクスチャテスト:1024x768\n\
+      4: テクスチャテスト:2048x1536\n\
+      5: 地球が動き、その周りを月が自転、公転する\n\
+      6 以降: キューブが跳ね返りながら、勝手にキューブが増えて行く\n";
+
+int
+init(int argc, char *argv[])
+{
+    int bpp    = 32;
+    int width  = 640;
+    int height = 480;
+    int spenum = 1;
+    const char *xml  = "xml_file/cube.xml";
+    video_type vtype = VTYPE_SDL;
+
+    for(int i = 1; argv[i]; ++i)
+    {
+	if (strcmp(argv[i], "-bpp") == 0) {
+	    bpp = atoi(argv[++i]);
+	}
+	if (strcmp(argv[i], "-width") == 0) {
+	    width = atoi(argv[++i]);
+	} 
+	if (strcmp(argv[i], "-height") == 0) {
+	    height = atoi(argv[++i]);
+	}
+	if (strcmp(argv[i], "-xml") == 0) {
+	    xml = argv[++i];
+	}
+	if (strcmp(argv[i], "-sg") == 0) {
+	    sg_number = (atoi)(argv[++i]);
+	}
+	if (strcmp(argv[i], "-cpu") == 0) {
+	    spenum = atoi(argv[++i]);
+	}
+	if (strcmp(argv[i], "-help") == 0) {
+	    printf("%s\n", help_str);
+	    return -1;
+	}
+	if (strcmp(argv[i], "-video") == 0) {
+	    if (strcmp(argv[i+1], "sdl") == 0) { 
+		vtype = VTYPE_SDL;
+	    } else if (strcmp(argv[i+1], "fb") == 0) {
+		vtype = VTYPE_FB;
+	    }
+	    i++;
+	}
+    }
+
+    if (vtype == VTYPE_SDL) {
+	screen = new ViewerSDL(bpp, width, height, spenum);
+    } else if (vtype == VTYPE_FB) {
+	screen = new ViewerFB(bpp, width, height, spenum);
+    }
+
+    screen->video_init();
+    screen->run_init(xml, sg_number);
+
+    manager->set_TMend(TMend);
+
+    return 0;
+}
+
+int
+TMmain(int argc, char *argv[])
+{
+    task_initialize();
+
+    return init(argc, argv);
+
+    //return 0;
+}
+
+void
+TMend(void)
+{
+    printf("test_nogl end\n");
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/node.cpp	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,70 @@
+#include <stdlib.h>
+#include "SceneGraph.h"
+#include "xml_file/cube.h"
+
+static void
+cube_collision(SceneGraphPtr node, int screen_w, int screen_h,
+	       SceneGraphPtr tree)
+{
+}
+
+static void
+cube_move2(SceneGraphPtr node, int screen_w, int screen_h)
+{
+    node->angle[1] += 1.0f;
+    if (node->angle[1] > 360.0f) {
+	node->angle[1] = 0.0f;
+    }
+
+    node->xyz[0] += node->stack_xyz[0];
+    if ((int)node->xyz[0] > screen_w || (int)node->xyz[0] < 0) {
+	node->stack_xyz[0] = -node->stack_xyz[0];
+    }
+
+    node->xyz[1] += node->stack_xyz[1];
+    if ((int)node->xyz[1] > screen_h || (int)node->xyz[1] < 0) {
+	node->stack_xyz[1] = -node->stack_xyz[1];
+    }
+}
+
+static void
+cube_move(SceneGraphPtr node, int screen_w, int screen_h)
+{
+    node->angle[1] += 1.0f;
+    if (node->angle[1] > 360.0f) {
+	node->angle[1] = 0.0f;
+    }
+
+    node->xyz[0] += node->stack_xyz[0];
+    if ((int)node->xyz[0] > screen_w || (int)node->xyz[0] < 0) {
+	node->stack_xyz[0] = -node->stack_xyz[0];
+    }
+
+    node->xyz[1] += node->stack_xyz[1];
+    if ((int)node->xyz[1] > screen_h || (int)node->xyz[1] < 0) {
+
+	// 実は微妙に意味が無い
+	srandom(random());
+
+	SceneGraphPtr p = node->clone();
+	p->position_init();
+	node->addBrother(p);
+	p->set_move_collision(cube_move2, cube_collision);
+	p->stack_xyz[0] = (float)(random() % 5);
+	p->stack_xyz[1] = (float)(random() % 5);
+	//p->xyz[0] = screen_w/2;
+	//p->xyz[1] = screen_h/2;
+	p->xyz[2] = node->xyz[2]+1000.0f;
+
+	node->stack_xyz[1] = -node->stack_xyz[1];
+    }
+}
+
+void
+node_init(void)
+{
+    SceneGraph::createFromXMLfile("xml_file/cube.xml");
+    Cube->set_move_collision(cube_move, cube_collision);
+    Cube->stack_xyz[0] = 2.0f;
+    Cube->stack_xyz[1] = 2.0f;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/panel.cpp	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,38 @@
+#include "SceneGraphRoot.h"
+#include "SGList.h"
+
+static void panel_move(SceneGraphPtr node, int screen_w, int screen_h);
+static void panel_collision(SceneGraphPtr node, int screen_w, int screen_h,
+			    SceneGraphPtr tree);
+
+static void
+panel_move(SceneGraphPtr node, int screen_w, int screen_h)
+{
+}
+
+static void
+panel_collision(SceneGraphPtr node, int screen_w, int screen_h,
+	       SceneGraphPtr tree)
+{
+}
+
+void
+panel_init(int bg)
+{
+    SceneGraphPtr panel;
+
+    if (bg == 2) {
+	sgroot->createFromXMLfile("xml_file/panel_512.xml");
+	panel = sgroot->createSceneGraph(PANEL_512);
+    } else if (bg == 3) {
+	sgroot->createFromXMLfile("xml_file/panel_1024.xml");
+	panel = sgroot->createSceneGraph(PANEL_1024);
+    } else {
+	sgroot->createFromXMLfile("xml_file/panel_2048.xml");
+	panel = sgroot->createSceneGraph(PANEL_2048);
+    }
+
+    panel->set_move_collision(panel_move, panel_collision);
+    panel->xyz[2] = 30.0f;
+    sgroot->setSceneData(panel);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/player_action.cpp	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,146 @@
+#include "SceneGraphRoot.h"
+#include "bullet_action.h"
+#include "SGList.h"
+
+#define MOVE_SPEED 5.00
+
+
+void
+player_move_right(SceneGraphPtr node, int screen_w, int screen_h)
+{
+  if(node->xyz[0]<screen_w/2)
+    {
+      node->xyz[0] += MOVE_SPEED;
+    }
+  if(node->angle[1]<=20)
+    {
+      node->angle[1]+=1.0;
+    }
+  if(node->angle[2]>=-45)
+    {
+      node->angle[2]-=1.0;
+    }
+}
+
+void 
+player_move_left(SceneGraphPtr node, int screen_w, int screen_h)
+{
+  if(node->xyz[0]> -screen_w/2)
+    {
+      node->xyz[0] -= MOVE_SPEED;
+    }
+  if(node->angle[1]>=-20)
+    {
+      node->angle[1]-=1.0;
+    }
+  if(node->angle[2]<=45)
+    {
+      node->angle[2]+=1.0;
+    }
+}
+
+void 
+player_move_up(SceneGraphPtr node, int screen_w, int screen_h)
+{
+  if(node->xyz[2]<screen_h/2 + 100)
+    {
+      node->xyz[2] += MOVE_SPEED;
+    }
+  if(node->angle[0]<45)
+    {
+      node->angle[0] += 2.0;
+    }
+}
+
+void 
+player_move_down(SceneGraphPtr node, int screen_w, int screen_h)
+{
+  if(node->xyz[2]> -screen_h/2)
+    {
+      node->xyz[2] -= MOVE_SPEED;
+    }
+  if(node->angle[0]>-45)
+    {
+      node->angle[0] -= 2.0;
+    }
+}
+
+void
+player_move_idle(SceneGraphPtr node)
+{
+    if (node->angle[1]>0)
+    {
+	node->angle[1]-=1.0;
+    }
+    else if(node->angle[1]<0)
+    {
+	node->angle[1]+=1.0;
+    }
+  
+  if(node->angle[2]<0)
+    {
+      node->angle[2]+=0.5;
+    }
+  else if(node->angle[2]>0)
+    {
+      node->angle[2]-=0.5;
+    }
+
+  if(node->angle[0]<0)
+    {
+      node->angle[0]+=1.0;
+    }
+  else if(node->angle[0]>0)
+    {
+      node->angle[0]-=1.0;
+    }
+}
+
+void
+player_move_all(SceneGraphPtr node, int screen_w, int screen_h)
+{
+    Pad *pad = sgroot->getController();
+
+    if (pad->right.isHold() || pad->left.isHold() ||
+	pad->up.isHold() || pad->down.isHold()) {
+	if (pad->right.isHold()) {
+	    player_move_right(node, screen_w, screen_h);
+	} else if (pad->left.isHold()) {
+	    player_move_left(node, screen_w, screen_h);
+	}
+	
+	if (pad->down.isHold()) {
+	    player_move_up(node, screen_w, screen_h);
+	} else if(pad->up.isHold()) {
+	    player_move_down(node, screen_w, screen_h);
+	}
+    } else {
+	player_move_idle(node);
+    }
+
+    if (pad->r2.isHold()) {
+      node->xyz[2] -= 10.0f;
+    }
+
+    if (pad->circle.isPush()) {
+	SceneGraphPtr bullet = sgroot->createSceneGraph(BULEBULLET);
+	bullet->set_move_collision(bluebullet_move, bullet_collision);
+	bullet_init(bullet, node);
+	node->addBrother(bullet);
+    }
+}
+
+void
+player_collision(SceneGraphPtr node, int screen_w, int screen_h,
+		 SceneGraphPtr tree)
+{
+#if 0
+    int judge = square_judge(node, BULEBULLET, scene_graph);
+    
+    if (judge == HIT)
+    {
+	node->set_move_collision(player_move_all,player_collision);
+    }
+#endif
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/player_action.h	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,7 @@
+void player_move_right(SceneGraphPtr node, int screen_w, int screen_h);
+void player_move_left(SceneGraphPtr node, int screen_w, int screen_h);
+void player_move_up(SceneGraphPtr node, int screen_w, int screen_h);
+void player_move_down(SceneGraphPtr node, int screen_w, int screen_h);
+void player_move_idle(SceneGraphPtr node);
+void player_move_all(SceneGraphPtr node, int screen_w, int screen_h);
+void player_collision(SceneGraphPtr node, int screen_w, int screen_h ,SceneGraphPtr tree);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/polygon.cpp	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,309 @@
+#include <iostream>
+#include <SDL.h>
+#include <SDL_opengl.h>
+#include <SDL_image.h>
+#include "polygon.h"
+#include "xml.h"
+#include "sys.h"
+#include "triangle.h"
+#include "vertex.h"
+#include "Span.h"
+#include "SpanC.h"
+#include "scene_graph_pack.h"
+#include "error.h"
+#include "viewer_types.h"
+using namespace std;
+
+//extern int decode(char *cont, char *file_name);
+extern int decode(char *cont, FILE *outfile);
+
+
+SDL_Surface* Polygon::texture_image;
+
+Polygon::Polygon(void)
+{
+    xyz[0] = 0;
+    xyz[1] = 0;
+    xyz[2] = 0;
+    xyz[3] = 1;
+    c_xyz[0] = 0;
+    c_xyz[1] = 0;
+    c_xyz[2] = 0;
+    c_xyz[3] = 1;
+    angle[0] = 0;
+    angle[1] = 0;
+    angle[2] = 0;
+    angle[3] = 1;
+
+    for (int i = 0; i < 16; i++) {
+	matrix[i] = 0;
+    }
+}
+
+void
+Polygon::position_init(void)
+{
+    xyz[0] = 0;
+    xyz[1] = 0;
+    xyz[2] = 0;
+    xyz[3] = 1;
+    c_xyz[0] = 0;
+    c_xyz[1] = 0;
+    c_xyz[2] = 0;
+    c_xyz[3] = 1;
+    angle[0] = 0;
+    angle[1] = 0;
+    angle[2] = 0;
+    angle[3] = 1;
+
+    for (int i = 0; i < 16; i++) {
+	matrix[i] = 0;
+    }
+}
+
+#if 0
+void Polygon::draw(SceneGraphPack *sgp)
+{
+    float xyz1[4],xyz2[4],xyz3[4];
+
+    /***SceneGraphUpdate***/
+    //sgp_update();
+    for (int i = 0; i < sgp->info.size; i++) {
+	SceneGraphNode node = sgp->node[i];
+
+	/***draw***/
+	int n,nt;
+	for(n=0,nt=0; n<node.size*3; n+=9,nt+=6) {
+	    xyz1[0] = node.vertex[n];
+	    xyz1[1] = node.vertex[n+1];
+	    xyz1[2] = node.vertex[n+2]*-1;
+	    xyz1[3] = 1;
+	    xyz2[0] = node.vertex[n+3];
+	    xyz2[1] = node.vertex[n+3+1];
+	    xyz2[2] = node.vertex[n+3+2]*-1;
+	    xyz2[3] = 1;
+	    xyz3[0] = node.vertex[n+6];
+	    xyz3[1] = node.vertex[n+6+1];
+	    xyz3[2] = node.vertex[n+6+2]*-1;
+	    xyz3[3] = 1;
+
+	    rotate(xyz1, node.translation);
+	    rotate(xyz2, node.translation);
+	    rotate(xyz3, node.translation);
+
+	    Vertex *ver1 = new Vertex(xyz1[0],xyz1[1],xyz1[2],node.texture[nt],node.texture[nt+1]);
+	    Vertex *ver2 = new Vertex(xyz2[0],xyz2[1],xyz2[2],node.texture[nt+2],node.texture[nt+2+1]);
+	    Vertex *ver3 = new Vertex(xyz3[0],xyz3[1],xyz3[2],node.texture[nt+4],node.texture[nt+4+1]);
+
+	    Triangle *tri = new Triangle(ver1,ver2,ver3);
+	    Span_c *span = new Span_c();
+	    span->viewer = viewer;
+	    span->p = this;
+	    span->create_span(tri,texture_image);
+	    delete ver1;
+	    delete ver2;
+	    delete ver3;
+	    delete tri;
+	    delete span;
+	}
+    }
+}
+
+
+void Polygon::draw(PolygonPack *pp)
+{
+    for(int n=0; n<pp->info.size; n++)
+    {
+	Vertex *ver1 = new Vertex(pp->tri[n].ver1.x,pp->tri[n].ver1.y,pp->tri[n].ver1.z,pp->tri[n].ver1.tex_x,pp->tri[n].ver1.tex_y);
+	Vertex *ver2 = new Vertex(pp->tri[n].ver2.x,pp->tri[n].ver2.y,pp->tri[n].ver2.z,pp->tri[n].ver2.tex_x,pp->tri[n].ver2.tex_y);
+	Vertex *ver3 = new Vertex(pp->tri[n].ver3.x,pp->tri[n].ver3.y,pp->tri[n].ver3.z,pp->tri[n].ver3.tex_x,pp->tri[n].ver3.tex_y);
+
+	Triangle *tri = new Triangle(ver1,ver2,ver3);
+	Span_c *span = new Span_c();
+	span->viewer = viewer;
+	span->p = this;
+	span->create_span(tri,texture_image);
+	delete ver1;
+	delete ver2;
+	delete ver3;
+	delete tri;
+	delete span;
+    }
+}
+
+void Polygon::draw(SpanPack *sp)
+{
+    Span *span;
+
+    for (int n = 0; n < sp->info.size; n++) {
+	span = &sp->span[n];
+
+	//int x = span->x;
+	//int y = span->y;
+	float z = span->start_z;
+	int end = span->length_x;
+	float zpos = span->end_z;
+	float tex1 = span->tex_x1;
+	float tex2 = span->tex_x2;
+	float tey1 = span->tex_y1;
+	float tey2 = span->tex_y2;
+	Uint32 rgb;
+	int tex_xpos;
+	int tex_ypos;
+	int tex_zpos;
+	float tex_x, tex_y, tex_z;
+
+	if (end == 1) {
+	    tex_xpos = (int)((span->tex_height-1) * tex1);
+	    tex_ypos = (int)((span->tex_width-1) * tey1);
+	    tex_zpos = (int)z;
+	    rgb = get_rgb(tex_xpos, tex_ypos);
+	    //viewer->write_pixel(x, y, zpos, rgb);
+	} else {
+	    for (int j = 0; j < end; j++) {
+		tex_x = tex1*(end-1-j)/(end-1) + tex2*j/(end-1);
+		tex_y = tey1*(end-1-j)/(end-1) + tey2*j/(end-1);
+		tex_z = z*(end-1-j)/(end-1) + zpos*j/(end-1);
+		if (tex_x > 1) tex_x = 1;
+		if (tex_y > 1) tex_y = 1;
+		tex_xpos = (int)((span->tex_height-1) * tex_x);
+		tex_ypos = (int)((span->tex_width-1) * tex_y);
+		rgb = get_rgb(tex_xpos,tex_ypos);
+		//viewer->write_pixel(j + x, y, tex_z, rgb);
+	    }
+	}
+    }
+}
+
+#endif
+
+void Polygon::pickup_coordinate(char *cont)
+{
+    for(int n=0; n<size*3; n+=3)
+    {
+	cont = pickup_float(cont, coord_xyz+n);
+	cont = pickup_float(cont, coord_xyz+n+1);
+	cont = pickup_float(cont, coord_xyz+n+2);
+      
+	if (cont == NULL)
+	{
+	    cout << "Analyzing obj data failed coordinate\n";
+	}
+    }
+}
+
+void Polygon::pickup_normal(char *cont)
+{
+    for (int n = 0; n<size*3; n += 3)
+    {
+	cont = pickup_float(cont, normal+n);
+	cont = pickup_float(cont, normal+n+1);
+	cont = pickup_float(cont, normal+n+2);
+      
+	if (cont == NULL)
+	{
+	    cout << "Analyzing obj data failed normal\n";
+	}
+    }
+}
+
+void Polygon::pickup_model(char *cont)
+{
+    cont = pickup_float(cont,c_xyz);
+    cont = pickup_float(cont,c_xyz+1);
+    cont = pickup_float(cont,c_xyz+2);
+  
+    if (cont == NULL)
+    {
+	cout << "Analyzing obj data failed model\n";
+    }
+}
+
+void Polygon::pickup_texture(char *cont)
+{
+    for (int n = 0; n < size*3; n += 3)
+    {
+	cont = pickup_float(cont, coord_tex+n);
+	cont = pickup_float(cont, coord_tex+n+1);
+	coord_tex[n+2] = 1.0;
+      
+	if (cont == NULL)
+	{
+	    cout << "Analyzing obj data failed texture\n";
+	}
+    }
+}
+
+char *get_pixel(int tx, int ty, SDL_Surface *texture_image)
+{
+    return (char*)texture_image->pixels+(texture_image->format->BytesPerPixel*((texture_image->w)*ty+tx));
+}
+
+unsigned my_ntohl(unsigned u) {
+    //     rr gg bb 00
+    //           rr
+    //     bb gg rr
+    //unsigned u1 =   ((u&0xff)<<24) +
+    //         ((u&0xff00)<<8) +
+    //         ((u&0xff0000)>>8) +
+    //         ((u&0xff000000)>>24);
+    unsigned u1;
+    unsigned b = (u&0xff000000)>>24;
+    unsigned g = (u&0xff0000)>>16;
+    unsigned r = (u&0xff00)>>8;
+    u1 = r + (g<<8) + (b<<16);
+    //printf("pixel %x->%x\n",u,u1);
+    return u1;
+}
+
+Uint32 Polygon::get_rgb(int tx, int ty)
+{
+    SDL_PixelFormat *fmt;
+    //Uint32 temp, pixel;
+    Uint8 red, green, blue;
+  
+    fmt = texture_image->format;
+
+    if (tx<0) tx = 0;
+    if (texture_image->w-1< tx) tx = texture_image->w-1 ;
+    if (ty<0) ty = 0;
+    if (texture_image->h-1< ty) ty = texture_image->h-1 ;
+
+
+
+    //SDL_LockSurface(texture_image);
+    char *p = get_pixel(tx,ty,texture_image);
+#if 0
+    pixel = my_ntohl(*(Uint32*)p);
+    //printf("pixel = %d\n", pixel);
+    //printf("pixel %x bpp = %d ",p, fmt->BytesPerPixel);
+    //SDL_UnlockSurface(texture_image);
+  
+    temp = pixel&fmt->Rmask;
+    temp = temp>>fmt->Rshift;
+    temp = temp<<fmt->Rloss;
+    red = (Uint8)temp;
+  
+    temp = pixel&fmt->Gmask;
+    temp = temp>>fmt->Gshift;
+    temp = temp<<fmt->Gloss;
+    green = (Uint8)temp;
+  
+    temp = pixel&fmt->Bmask;
+    temp = temp>>fmt->Bshift;
+    temp = temp<<fmt->Bloss;
+    blue = (Uint8)temp;
+#endif
+    blue  = (Uint8) p[0];
+    green = (Uint8) p[1];
+    red   = (Uint8) p[2];
+	  
+    //printf("tx = %d ty = %d ", tx,ty); 
+    //printf("pixel color =>  R: %d,  G: %d,  B: %d\n", red, green, blue);
+
+    SDL_PixelFormat *pf = NULL;
+    //pf = viewer->screen->format;
+
+    //cout << SDL_MapRGB(pf, red, green, blue) << endl;
+    return SDL_MapRGB(pf, red, green, blue);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/polygon.h	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,62 @@
+#ifndef INCLUDED_POLYGON
+#define INCLUDED_POLYGON
+
+#ifndef INCLUDED_VIEWER
+#  include "viewer.h"
+#endif
+
+#include <libxml/parser.h>
+
+#ifndef INCLUDED_POLYGON_PACK
+#  include "polygon_pack.h"
+#endif
+
+#ifndef INCLUDED_SPAN_PACK
+#  include "SpanPack.h"
+#endif
+
+#ifndef INCLUDED_TEXTURE
+#  include "texture.h"
+#endif
+
+class Polygon {
+public:
+    long long size;
+    const char *name;
+    const char *parent_name;
+
+    //float *data;    //"vertex" and "normal" and "texture"
+    float *coord_xyz; // vertex coordinate array
+    float *coord_tex; // texture coordinate array
+    float *normal;    // normal vector array
+    float xyz[4];     // position
+    float angle[4];   // angle
+    float c_xyz[4];   // center of rotation
+    float matrix[16];
+    float *anim;
+    int texture_id; //texture id number
+    struct texture_list texture_info;
+    
+    static SDL_Surface* texture_image; // pointer of this surface's texture
+
+    Polygon(void);
+
+    void parameter_change(char *name, float x, float y, float z, float ax, float ay, float az);
+    //void load_texture(char *image_name);
+    //void draw(float *stack);
+    //void draw(SceneGraphPack *sgp);
+    //void draw(PolygonPack *pp);
+    //void draw(SpanPack *sp);
+    Uint32 get_rgb(int tx, int ty);
+
+public:
+    void position_init(void);
+
+    void tree_draw();
+    void pickup_coordinate(char *cont);
+    void pickup_normal(char *cont);
+    void pickup_model(char *cont);
+    void pickup_texture(char *cont);
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/polygon_pack.h	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,68 @@
+#ifndef INCLUDED_POLYGON_PACK
+#define INCLUDED_POLYGON_PACK
+
+#ifndef INCLUDED_TYPES
+#  include "types.h"
+#endif
+
+#define MAX_SIZE_TRIANGLE 128
+
+typedef struct VertexPack {
+    float x;
+    float y;
+    float z;
+    float tex_x;
+    float tex_y;
+} VertexPack, *VertexPackPtr; // 20
+
+typedef struct TriTexInfo {
+    uint32 *addr;
+    int width;
+    int height;
+    int scale_max;
+} TriangleTexInfo, *TriangleTexInfoPtr; // 16
+
+typedef struct TrianglePack {
+    TriTexInfo tex_info;
+    VertexPack ver1;
+    VertexPack ver2;
+    VertexPack ver3;
+} TrianglePack, *TrianglePackPtr;
+
+
+typedef struct PolygonPack {
+    struct PORIGON_info {
+	int size;
+	int light_pos[3];
+	int light_rgb[3];
+    }info;
+
+    TrianglePack tri[MAX_SIZE_TRIANGLE];
+
+    PolygonPack* next;
+
+    void init(void) {
+	info.size = 0;
+	next = 0;
+    }
+
+    void clear(void) {
+	PolygonPack *q = 0;
+	PolygonPack *q1 = 0;
+	
+	q = this->next;
+	while (q) {
+	    q1 = q->next;
+	    delete(q);
+	    q = q1;
+	}
+	this->init();
+    }
+} PolygonPack, *PolygonPackPtr; // 4*7 + 76*128 + 4 = 9760
+
+typedef struct PolygonPackList {
+    int size;
+    PolygonPack *list;
+} PolygonPackList;
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/post.cpp	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,15 @@
+#include "viewer.h"
+
+extern Viewer *screen;
+
+void
+post2runLoop(void *arg)
+{
+    screen->run_loop();
+}
+
+void
+post2runDraw(void *arg)
+{
+    screen->run_draw();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/scene.h	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,20 @@
+#ifndef INCLUDED_SCENE
+#define INCLUDED_SCENE
+
+#ifndef INCLUDED_POLYGON
+#include "polygon.h"
+#endif
+
+class Scene{
+ public:
+  Polygon *list;
+  Demonstration *demo;
+  void (Scene::*action_scene)();
+
+  Scene();
+  void title_init();
+  void title();
+  void title_end();
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/scene_graph_pack.h	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,77 @@
+#ifndef INCLUDED_SCENE_GRAPH_PACK
+#define INCLUDED_SCENE_GRAPH_PACK
+
+#ifndef INCLUDED_SCENE_GRAPH
+#  include "SceneGraph.h"
+#endif
+
+#ifndef INCLUDED_TYPES
+#  include "types.h"
+#endif
+
+#define MAX_NODE 16
+#define MAX_POLYGON 36
+
+typedef struct SceneGraphNode {
+    int size; // この Node で使ってるポリゴンの数、でいいのかな
+    float vertex[MAX_POLYGON*3];
+    float texture[MAX_POLYGON*2];
+    float obj_pos[4];
+    float angle[4];
+    float translation[16];
+    uint32 *tex_addr;
+    int tex_width, tex_height;
+    int id;
+    int move, interaction;
+    int pn; // parent number?
+    SceneGraphNode *next;
+    int pad[3];
+    SceneGraphPtr self;
+    SceneGraphPtr tree;
+
+    void init(void) {
+	size = 0;
+	next = 0;
+    }
+
+    void finish(void) {
+	SceneGraphNode *p = this->next, *p1;
+
+	while (p) {
+	    p1 = p->next;
+	    free(p);
+	    p = p1;
+	}
+    }
+}SceneGraphNode, *SceneGraphNodePtr;
+
+typedef struct SceneGraphInfo {
+    int size;
+    int pad[2];
+}SceneGraphInfo;
+
+typedef struct SceneGraphPack {
+    SceneGraphInfo info;
+    SceneGraphNode node[MAX_NODE];
+    SceneGraphPack *next;
+
+    void init(void){
+	next = 0;
+	info.size = 0;
+
+	for (int i = 0; i < MAX_NODE; i++) {
+	    node[i].size = 0;
+	}
+    }
+
+    void finish(void) {
+	for (int i = 0; i < info.size; i++) {
+	    node[i].finish();
+	}
+
+	next = 0;
+	info.size = 0;
+    }
+} SceneGraphPack, *SceneGraphPackPtr;
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/spe/CreatePolygon.cpp	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,191 @@
+/**
+ * SceneGraph が増えてくると動かなくなるかもしれない。
+ * 一応 mainMem とかで動くようになるとは思うけど。
+ * だめだったら、そこら辺が怪しいと思うべき
+ */
+
+#include "CreatePolygon.h"
+#include "polygon_pack.h"
+#include "scene_graph_pack.h"
+
+SchedDefineTask(CreatePolygon);
+
+#define SG_PACK_LOAD 10
+#define SG_NODE_LOAD 11
+#define PP_LOAD 12
+#define PP_STORE 13
+
+/**
+ * あとで直す
+ */
+static void
+rotate(float *xyz, float *matrix)
+{
+    float abc[4];
+
+    abc[0] = xyz[0];
+    abc[1] = xyz[1];
+    abc[2] = xyz[2];
+    abc[3] = xyz[3];
+
+    for(int i=0; i<4; i++)
+    {
+	xyz[i] = abc[0]*matrix[i] + abc[1]*matrix[i+4] + abc[2]*matrix[i+8] + abc[3]*matrix[i+12];
+    }
+}
+
+int 
+CreatePolygon::run(void *rbuf, void *wbuf)
+{
+    float xyz1[4],xyz2[4],xyz3[4];
+
+    SceneGraphPackPtr sgp = (SceneGraphPack*)smanager->get_input(0);
+    SceneGraphPackPtr next_sgp = 
+	(SceneGraphPackPtr)smanager->allocate(sizeof(SceneGraphPack));
+    SceneGraphPackPtr free_sgp = next_sgp;
+    SceneGraphPackPtr tmp_sgp;
+
+    SceneGraphNodePtr node;
+    SceneGraphNodePtr next_node
+	= (SceneGraphNodePtr)smanager->allocate(sizeof(SceneGraphNode));
+    SceneGraphNodePtr free_node = next_node;
+    SceneGraphNodePtr tmp_node;
+
+    PolygonPackPtr pp
+	= (PolygonPackPtr)smanager->allocate(sizeof(PolygonPack));
+    PolygonPackPtr send_pp
+	= (PolygonPackPtr)smanager->allocate(sizeof(PolygonPack));
+    PolygonPackPtr pp_addr = (PolygonPackPtr)smanager->get_param(0);
+    PolygonPackPtr tmp_pp;
+    
+    pp->init();
+    send_pp->init();
+
+    do {
+	if (sgp->next != NULL) {
+	    smanager->dma_load(next_sgp, (uint32)sgp->next,
+			       sizeof(SceneGraphPack), SG_PACK_LOAD);
+	} else {
+	    next_sgp = NULL;
+	}
+
+	for (int i = 0; i < sgp->info.size; i++) {
+	    node = &sgp->node[i];
+
+	    do {
+		if (node->next != NULL) {
+		    smanager->dma_load(next_node, (uint32)node->next,
+				       sizeof(SceneGraphNode), SG_NODE_LOAD);
+		} else {
+		    next_node = NULL;
+		}
+    
+		for (int n = 0, nt = 0; n < node->size*3; n+=9, nt+=6) {
+
+		    if (pp->info.size >= MAX_SIZE_TRIANGLE) {
+			PolygonPackPtr next;
+
+			// smanager から Task を作る、0 ではなく PolygonPack->task_id が良い
+			smanager->mainMem_alloc(0, sizeof(PolygonPack));
+			smanager->mainMem_wait();
+			next = (PolygonPackPtr)smanager->mainMem_get(0);
+
+			pp->next = next; // この部分は TaskManager 側でやるべき
+
+			tmp_pp = pp;
+			pp = send_pp;
+			send_pp = tmp_pp;
+
+			smanager->dma_wait(PP_STORE);
+			smanager->dma_store(send_pp, (uint32)pp_addr,
+					    sizeof(PolygonPack), PP_STORE);
+			
+			pp_addr = next;
+
+			smanager->dma_wait(PP_LOAD); // 多分不要
+			smanager->dma_load(pp, (uint32)pp_addr,
+					   sizeof(PolygonPack), PP_LOAD);
+			// 次の dma_wait のコストが高いのでパイプラインで隠す必要がある
+			
+			smanager->dma_wait(PP_LOAD);
+			pp->init();
+
+		    }
+
+		    TrianglePack *triangle = &pp->tri[pp->info.size++];
+
+		    xyz1[0] = node->vertex[n];
+		    xyz1[1] = node->vertex[n+1];
+		    xyz1[2] = node->vertex[n+2]*-1;
+		    xyz1[3] = 1;
+		    xyz2[0] = node->vertex[n+3];
+		    xyz2[1] = node->vertex[n+3+1];
+		    xyz2[2] = node->vertex[n+3+2]*-1;
+		    xyz2[3] = 1;
+		    xyz3[0] = node->vertex[n+6];
+		    xyz3[1] = node->vertex[n+6+1];
+		    xyz3[2] = node->vertex[n+6+2]*-1;
+		    xyz3[3] = 1;
+		
+		    rotate(xyz1, node->translation);
+		    rotate(xyz2, node->translation);
+		    rotate(xyz3, node->translation);
+		
+		    triangle->ver1.x = xyz1[0];
+		    triangle->ver1.y = xyz1[1];
+		    triangle->ver1.z = xyz1[2];
+		    triangle->ver1.tex_x = node->texture[nt];
+		    triangle->ver1.tex_y = node->texture[nt+1];
+		
+		    triangle->ver2.x = xyz2[0];
+		    triangle->ver2.y = xyz2[1];
+		    triangle->ver2.z = xyz2[2];
+		    triangle->ver2.tex_x = node->texture[nt+2];
+		    triangle->ver2.tex_y = node->texture[nt+2+1];
+		
+		    triangle->ver3.x = xyz3[0];
+		    triangle->ver3.y = xyz3[1];
+		    triangle->ver3.z = xyz3[2];
+		    triangle->ver3.tex_x = node->texture[nt+4];
+		    triangle->ver3.tex_y = node->texture[nt+4+1];
+		
+#if 1
+		    triangle->tex_info.addr = node->tex_addr;
+		    triangle->tex_info.width = node->tex_width;
+		    triangle->tex_info.height = node->tex_height;
+#else
+		    triangle->tex_info.addr = node->texture_info.pixels;
+		    triangle->tex_info.width = node->texture_info.t_w;
+		    triangle->tex_info.height = node->texture_info.t_h;
+#endif
+		}
+
+		smanager->dma_wait(SG_NODE_LOAD);
+
+		tmp_node = node;
+		node = next_node;
+		next_node = tmp_node;
+	    } while (node);
+
+	    next_node = free_node;
+	}
+
+	smanager->dma_wait(SG_PACK_LOAD);
+
+	tmp_sgp = sgp;
+	sgp = next_sgp;
+	next_sgp = tmp_sgp;
+    } while (sgp);
+    
+    smanager->dma_wait(PP_STORE);
+    smanager->dma_store(pp, (uint32)pp_addr,
+			sizeof(PolygonPack), PP_STORE);
+    smanager->dma_wait(PP_STORE);
+
+    free(pp);
+    free(send_pp);
+    free(free_node);
+    free(free_sgp);
+
+    return 0;
+}    
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/spe/CreatePolygon.h	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,15 @@
+#ifndef INCLUDED_CREATE_POLYGON
+#define INCLUDED_CREATE_POLYGON
+
+#ifndef INCLUDED_SCHED_TASK
+#  include "SchedTask.h"
+#endif
+
+class CreatePolygon : public SchedTask {
+public:
+    SchedConstructor(CreatePolygon);
+
+    int run(void *rbuf, void *wbuf);
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/spe/CreateSpan.cpp	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,496 @@
+#include "CreateSpan.h"
+#include "viewer_types.h"
+
+// DMA channel
+static const int SPAN_PACK_LOAD    =  5;
+static const int SPAN_PACK_STORE   =  6;
+static const int POLYGON_PACK_LOAD =  7;
+static const int TILE_ALLOCATE     =  8;
+static const int TILE_LOAD         =  9;
+static const int TILE_STORE        = 10;
+
+static SpanPackPtr spack = NULL;
+static SpanPackPtr send_spack = NULL;
+static int prev_index = 0;
+
+SchedDefineTask(CreateSpan);
+
+static float
+calc(float f1, float f2,int i, float base)
+{
+    float ans;
+    ans = f1/f2*i + base;
+    return ans;
+}
+
+
+/**
+ * TrianglePack から、vMin, vMid, vMax を求める
+ *
+ * @param [triPack] TrianglePack
+ * @param [vMin] [vMid] [vMax]
+ */
+static void
+make_vertex(TrianglePack *triPack,
+	    VertexPackPtr *vMin, VertexPackPtr *vMid, VertexPackPtr *vMax)
+{
+    if (triPack->ver1.y <= triPack->ver2.y) {
+	if (triPack->ver2.y <= triPack->ver3.y) {
+	    *vMin = &triPack->ver1;
+	    *vMid = &triPack->ver2;
+	    *vMax = &triPack->ver3;
+	} else if (triPack->ver3.y <= triPack->ver1.y) {
+	    *vMin = &triPack->ver3;
+	    *vMid = &triPack->ver1;
+	    *vMax = &triPack->ver2;
+	} else {
+	    *vMin = &triPack->ver1;
+	    *vMid = &triPack->ver3;
+	    *vMax = &triPack->ver2;
+	}
+    } else {
+	if (triPack->ver1.y <= triPack->ver3.y) {
+	    *vMin = &triPack->ver2;
+	    *vMid = &triPack->ver1;
+	    *vMax = &triPack->ver3;
+	} else if (triPack->ver3.y <= triPack->ver2.y) {
+	    *vMin = &triPack->ver3;
+	    *vMid = &triPack->ver2;
+	    *vMax = &triPack->ver1;
+	} else {
+	    *vMin = &triPack->ver2;
+	    *vMid = &triPack->ver3;
+	    *vMax = &triPack->ver1;
+	}
+    }
+}
+
+static void
+make_vMid10(VertexPack *v, VertexPack *vMin,
+	    VertexPack *vMid, VertexPack *vMax)
+{
+    //int d, d1;
+    float d;
+    int d1;
+    
+    d  = vMax->y - vMin->y;
+    d1 = (int)(vMid->y - vMin->y);
+
+    v->tex_x  = calc(vMax->tex_x - vMin->tex_x, d, d1, vMin->tex_x);
+    v->tex_y  = calc(vMax->tex_y - vMin->tex_y, d, d1, vMin->tex_y);
+    v->x      = calc(vMax->x - vMin->x, d, d1, vMin->x);
+    v->y      = vMid->y;
+    v->z      = calc(vMax->z - vMin->z, d, d1, vMin->z);
+}
+
+/**
+ * 与えられた scale から、実際に使うテクスチャの Tapestry を選択する
+ *
+ * テクスチャは、オリジナルのサイズから、可能なかぎり 1/2 で縮小していき、
+ * 下の図の様に連続した領域に入れられる
+ *
+ *   Tapestry (1)
+ * +---+---+---+---+
+ * | 0 | 1 | 2 | 3 |
+ * +---+---+---+---+
+ * | 4 | 5 | 6 | 7 |     (2)
+ * +---+---+---+---+  +---+---+
+ * | 8 | 9 | 10| 11|  | 16| 17|   (3)
+ * +---+---+---+---+  +---+---+  +---+
+ * | 12| 13| 14| 15|  | 18| 19|  | 20|
+ * +---+---+---+---+  +---+---+  +---|
+ *
+ * (1)                                                 (2)             (3)
+ *  +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
+ *  | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * | * | * | 14| 15| 16| 17| 18| 19| 20|
+ *  +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
+ *
+ * scale の値から、各 Tapestry の先頭アドレスを返す
+ *
+ * @param[in] tw       Width of texture
+ * @param[in] th       Height of texture
+ * @param[in] scale    テクスチャの縮小率 (= 2^n)
+ * @param[in] addr_top テクスチャの先頭アドレス (上の図での (1)
+ * @return scale に対応する Tapestry のアドレス (上の図での (1) or (2) or(3)
+ */
+static uint32*
+getTapestry(int tw, int th, int scale, uint32 *addr_top)
+{
+    int index = 0;
+
+    for (int s = 1; s < scale; s <<= 1) {
+	index += tw*th;
+	tw >>= 1; /* tw /= 2 */
+	th >>= 1;
+    }
+
+    return addr_top + index;
+}
+
+
+/**
+ * span の width,height と texture の width,height を比べて
+ * span を描画する際に使う texture の比率を求める
+ *
+ * @param[in] width      Width of span
+ * @param[in] height     Height of span
+ * @param[in] tex_width  Width of 1/1 texture that span use
+ * @param[in] tex_height Height of 1/1 texture that span use
+ * @param[in] scale_max  この Span で使う texture の最大縮小率
+ *                   計算結果が scale_max 以上になるのを防ぐ
+ * @return 描画に使う texture の比率
+ *         width と height は 1/scale の画像を使う
+ *
+ */
+static int
+getScale(int width, int height, int tex_width, int tex_height, int scale_max)
+{
+    int base, tex_base;
+    int scale = 1;
+
+    /**
+     * width と height で、長い方を基準に、
+     * texture の scale を決める
+     */
+    if (width > height) {
+	base = width;
+	tex_base = tex_width;
+    } else {
+	base = height;
+	tex_base = tex_height;
+    }
+
+    if (tex_base > base) {
+	int t_scale = tex_base/base;
+	while (t_scale >>= 1) {
+	    scale <<= 1;
+	}
+    }
+
+    return (scale > scale_max) ? scale_max : scale;
+    //return scale_max;
+}
+
+/**
+ * x軸に水平な辺を持つ三角形ポリゴンから、
+ * Span を抜き出す
+ *
+ * @param[in] spackList    triangle から生成された span を格納する List
+ * @param[in] charge_y_top 担当する y の範囲開始地点
+ * @param[in] charge_y_end 担当する y の範囲終了地点
+ * @param[in] tex_addr     triangle が参照するテクスチャの先頭アドレス
+ * @param[in] tex_width    テクスチャの width
+ * @param[in] tex_height   テクスチャの height
+ * @param[in] tex_scale_max  テクスチャの最大縮小率 (2^n)
+ * @param[in] vMin     triangle の座標
+ * @param[in] vMid     triangle の座標。triangle を二つに分けて出来た新しい座標
+ * @param[in] vMid10   triangle の座標
+ * @param[in] length_y  分割する前の Triangle の y の長さ
+ * @param[in] tex_y_len 分割する前の Triangle に貼られている Texture の
+ *                      長さの割合 (0 ... 1)
+ */
+void
+CreateSpan::half_triangle(SpanPackPtr *spackList,
+			  int charge_y_top, int charge_y_end,
+			  TriangleTexInfoPtr tex_info,
+			  VertexPack *vMin,VertexPack *vMid,VertexPack *vMid10,
+			  int length_y, float tex_y_len)
+{
+    float tmp_z,tmp_tex1, tmp_tex2 ,tmp_tey1,tmp_tey2;
+    float tmp_xpos,tmp_end,tmp_zpos;
+    float start_z, end_z;
+    float start_tex_x, end_tex_x, start_tex_y, end_tex_y;
+    int x, y, length;
+
+#if 1
+    // これじゃないと
+    // テクスチャの貼りに微妙に隙間が。謎だ
+    int start_y = (int)vMid->y;
+    int end_y   = (int)vMin->y;
+#else
+    float start_y = vMid->y;
+    float end_y   = vMin->y;
+#endif
+    float div_y = start_y - end_y;
+    int k = 0;
+    int l = 1;
+
+    SpanPackPtr tmp_spack;
+
+    /**
+     * 三角形ポリゴンをx軸に水平に二つに分けようとして
+     * ある一辺がすでに水平だった場合、つまり
+     *
+     * |\
+     * | \
+     * |  \
+     * -----
+     *
+     *
+     * 上のようなポリゴンだった場合は、本来なら上の部分の三角形にだけ
+     * half_triangle の処理をするべきだが、現在の処理だと
+     * この half_triangle に「上の部分の三角形」と、
+     * 「『下の部分の三角形と判断してしまった』直線」が来てしまう。
+     * 直線の部分が来ると、calc() で 0 除算とかで、値不定で暴走するので
+     * 現在はこれで代用。
+     * half_triangle 呼ぶ前にこれを判断できれば良いかもしれない。
+     * てかこんなんでいいのかよ。。。
+     */
+#if 1
+    if ((int)div_y == 0) {
+	return;
+    }
+#else
+    if (vMid10->x == vMin->x && vMid10->y == vMin->y) {
+	return;
+    }
+#endif
+
+    if (div_y < 0) {
+	div_y = -div_y;
+	k = 1;
+	l = -1;
+    }
+
+    for (int i = k; i < (int)div_y+1; i++) {
+	y = (int)vMin->y + i*l;
+#if 1
+
+	/**
+	 * 担当 y 範囲内
+	 */
+	if (charge_y_top <= y && y <= charge_y_end) {
+	    // 1..8 を index0, 9..16 を index1 にするために y を -1
+	    int index = (y-1) / split_screen_h;
+
+	    /**
+	     * 違う SpanPack を扱う場合、
+	     * 現在の SpanPack をメインメモリに送り、
+	     * 新しい SpanPack を取ってくる
+	     */
+	    if (index != prev_index) {
+		tmp_spack = spack;
+		spack = send_spack;
+		send_spack = tmp_spack;
+
+		smanager->dma_wait(SPAN_PACK_STORE);
+		smanager->dma_store(send_spack, (uint32)spackList[prev_index],
+				    sizeof(SpanPack), SPAN_PACK_STORE);
+		
+		smanager->dma_load(spack, (uint32)spackList[index],
+				   sizeof(SpanPack), SPAN_PACK_LOAD);
+		prev_index = index;
+		smanager->dma_wait(SPAN_PACK_LOAD);
+	    }
+
+	    /**
+	     * 書き込む SpanPack が満杯だったら
+	     * メインメモリで allocate した領域 (next) を持ってきて
+	     * 現在の spack->next につなぎ、next を次の spack とする。
+	     */
+	    if (spack->info.size >= MAX_SIZE_SPAN) {
+		SpanPackPtr next;
+		
+		smanager->mainMem_alloc(0, sizeof(SpanPack));
+		smanager->mainMem_wait();
+		next = (SpanPackPtr)smanager->mainMem_get(0);
+		
+		spack->next = next; // この部分は TaskManager でやる
+
+		tmp_spack = spack;
+		spack = send_spack;
+		send_spack = tmp_spack;
+
+		smanager->dma_wait(SPAN_PACK_STORE);
+		smanager->dma_store(send_spack, (uint32)spackList[index],
+				    sizeof(SpanPack), SPAN_PACK_STORE);
+
+		spackList[index] = next;
+		
+		smanager->dma_load(spack, (uint32)spackList[index],
+				   sizeof(SpanPack), SPAN_PACK_LOAD);
+		smanager->dma_wait(SPAN_PACK_LOAD);
+		spack->init((index+1)*split_screen_h);
+	    }
+	} else {
+	    /**
+	     * 担当範囲外だったら無視
+	     */
+	    continue;
+	}
+	
+	tmp_xpos = calc(vMid10->x - vMin->x ,div_y, i, vMin->x);
+	tmp_end  = calc(vMid->x  - vMin->x ,div_y, i, vMin->x);
+	tmp_z    = calc(vMid10->z - vMin->z ,div_y, i, vMin->z);
+	tmp_zpos = calc(vMid->z  - vMin->z ,div_y, i, vMin->z);
+
+	length = (tmp_xpos > tmp_end)
+	    ? (int)tmp_xpos - (int)tmp_end : (int)tmp_end - (int)tmp_xpos;
+	if (length == 0) {
+	    continue;
+	}
+
+	tmp_tex1 =((i/(div_y)) * vMid10->tex_x) +
+	    ( ((div_y - i)/(div_y)) * vMin->tex_x);
+	tmp_tex2 =( (i/(div_y)) * vMid->tex_x) +
+	    ( ((div_y - i)/(div_y)) * vMin->tex_x);
+
+	tmp_tey1 =( (i/(div_y)) * vMid10->tex_y) +
+	    ( ((div_y - i)/(div_y)) * vMin->tex_y);
+	tmp_tey2 =( (i/(div_y)) * vMid->tex_y) +
+	    ( ((div_y - i)/(div_y)) * vMin->tex_y);
+
+	if (tmp_xpos > tmp_end) {
+	    x = (int)tmp_end;
+	    length = (int)(tmp_xpos)-(int)(tmp_end)+1;
+	    start_z = tmp_zpos;
+	    end_z = tmp_z;
+	    start_tex_x = tmp_tex2;
+	    end_tex_x = tmp_tex1;
+	    start_tex_y = tmp_tey2;
+	    end_tex_y = tmp_tey1;
+	} else {
+	    x = (int)tmp_xpos;
+	    length = (int)(tmp_end)-(int)(tmp_xpos)+1;
+	    start_z = tmp_z;
+	    end_z = tmp_zpos;
+	    start_tex_x = tmp_tex1;
+	    end_tex_x = tmp_tex2;
+	    start_tex_y = tmp_tey1;
+	    end_tex_y = tmp_tey2;
+	}
+
+	smanager->dma_wait(SPAN_PACK_LOAD);
+
+	Span *span = &spack->span[spack->info.size++];
+
+	span->x          = x;
+	span->y          = y;
+	span->length_x   = length;
+	span->start_z    = start_z;
+	span->end_z      = end_z;
+	span->tex_x1     = start_tex_x;
+	span->tex_x2     = end_tex_x;
+	span->tex_y1     = start_tex_y;
+	span->tex_y2     = end_tex_y;
+
+
+	float tex_x_len = span->tex_x2 - span->tex_x1;
+
+	/**
+	 * tex_x_len, tex_y_len を掛ける理由は
+	 * Changelog の 2008-12-16 を参照
+	 */
+	int scale = getScale(span->length_x, length_y,
+			     (int)(span->tex_width*tex_x_len),
+			     (int)(span->tex_height*tex_y_len),
+			     tex_info->scale_max);
+	//scale = tex_info->scale_max;
+	
+	uint32 *tapestry = getTapestry(tex_info->width,
+				       tex_info->height, scale,
+				       tex_info->addr);
+	span->tex_addr   = tapestry;
+	span->tex_width  = tex_info->width/scale;
+	span->tex_height = tex_info->height/scale;
+    }
+#else
+    
+    /**
+     * ここに SIMD 化した記述をしようとして断念
+     */
+
+#endif
+
+}
+
+
+int
+CreateSpan::run(void *rbuf, void *wbuf)
+{
+    PolygonPack *pp = (PolygonPack*)smanager->get_input(0);
+    PolygonPack *next_pp = 
+	(PolygonPack*)smanager->allocate(sizeof(PolygonPack));
+    PolygonPack *free_pp = next_pp;
+    PolygonPack *tmp_pp;
+
+    TrianglePackPtr triPack;
+    VertexPackPtr vMin, vMid, vMax;
+    VertexPackPtr vMid10
+	= (VertexPackPtr)smanager->allocate(sizeof(VertexPack));
+    
+    SpanPackPtr *spackList = (SpanPackPtr*)smanager->get_input(1);
+    spack = (SpanPackPtr)smanager->get_input(2);
+    send_spack = (SpanPackPtr)smanager->allocate(sizeof(SpanPack));
+    prev_index = get_param(0);
+
+    // spack と send_spack は swap しながら DMA を繰り返すので
+    // 自分で allocate した send_spack を覚えてないといけない
+    SpanPackPtr free_spack = send_spack;
+
+    int charge_y_top = get_param(1);
+    int charge_y_end = get_param(2);
+
+    do {
+	if (pp->next != NULL) {
+	    smanager->dma_load(next_pp, (uint32)pp->next,
+			       sizeof(PolygonPack), POLYGON_PACK_LOAD);
+	} else {
+	    next_pp = NULL;
+	}
+
+	for (int i = 0; i < pp->info.size; i++) {
+	    triPack = &pp->tri[i];
+
+	    TriangleTexInfoPtr tri_tex_info = &triPack->tex_info;
+
+	    make_vertex(triPack, &vMin, &vMid, &vMax);
+	    make_vMid10(vMid10, vMin, vMid, vMax);
+
+	    /**
+	     * ポリゴンを、x軸に水平に分割して二つの三角形を作り、
+	     * それぞれから Span を求める
+	     *
+	     *      vMax
+	     *        |\
+	     *        | \
+	     *        |  \
+	     *        |   \
+	     * vMid10 ------ vMid
+	     *        |   /
+	     *        |  /
+	     *        | /
+	     *        |/
+	     *      vMin
+	     *
+	     * (vMax, vMid, vMin) という triangle を
+	     * (vMax, vMid, vMid10) (vMin, vMid, vMid10) という
+	     * 二つの Triangle に分けている
+	     */
+	    half_triangle(spackList, charge_y_top, charge_y_end,
+			  tri_tex_info, vMin, vMid, vMid10,
+			  (int)(vMax->y - vMin->y), vMax->tex_y - vMin->tex_y);
+	    half_triangle(spackList, charge_y_top, charge_y_end,
+			  tri_tex_info, vMax, vMid, vMid10,
+			  (int)(vMax->y - vMin->y), vMax->tex_y - vMin->tex_y);
+	}
+
+	smanager->dma_wait(POLYGON_PACK_LOAD);	
+
+	tmp_pp = pp;
+	pp = next_pp;
+	next_pp = tmp_pp;
+    } while (pp);
+
+    smanager->dma_wait(SPAN_PACK_STORE);
+    smanager->dma_store(spack, (uint32)spackList[prev_index],
+			sizeof(SpanPack), SPAN_PACK_STORE);
+    smanager->dma_wait(SPAN_PACK_STORE);
+
+    // smanager で allocate したのだから free も smanager でやるべき
+    free(free_pp);
+    free(free_spack);
+    free(vMid10);
+
+    return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/spe/CreateSpan.h	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,28 @@
+#ifndef INCLUDED_CREATE_SPAN
+#define INCLUDED_CREATE_SPAN
+
+#ifndef INCLUDED_SCHED_TASK
+#  include "SchedTask.h"
+#endif
+
+#ifndef INCLUDED_POLYGON_PACK
+#  include "polygon_pack.h"
+#endif
+
+#ifndef INCLUDED_SPAN_PACK
+#  include "SpanPack.h"
+#endif
+
+class CreateSpan : public SchedTask {
+public:
+    SchedConstructor(CreateSpan);
+    
+    int run(void *rbuf, void *wbuf);
+    void half_triangle(SpanPackPtr *spackList,
+		       int charge_y_top, int charge_y_end,
+		       TriangleTexInfoPtr tex_info,
+		       VertexPack *vMin,VertexPack *vMid,VertexPack *vMid1,
+		       int length_y, float tex_y_len);
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/spe/DrawBack.cpp	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,32 @@
+#include <stdlib.h>
+#include <string.h>
+#include "DrawBack.h"
+#include "viewer_types.h"
+
+SchedDefineTask(DrawBack);
+
+void
+DrawBack::linebuf_init(int *buf, int x, int rgb)
+{
+    for (int i = 0; i < x; i++) {
+	buf[i] = rgb;
+    }
+}
+
+int
+DrawBack::run(void *rbuf, void *wbuf)
+{
+    int rgb          = smanager->get_param(0);
+    int rangex_start = smanager->get_param(1);
+    int rangex_end   = smanager->get_param(2);
+    int rangey       = smanager->get_param(3);
+    int rangex       = rangex_end - rangex_start + 1;
+    int *linebuf;
+
+    for (int i = 0; i < rangey; i++) {
+	linebuf = (int*)smanager->get_output(i);
+	linebuf_init(linebuf, rangex, rgb);
+    }
+
+    return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/spe/DrawBack.h	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,17 @@
+#ifndef INCLUDED_TASK_DRAW_BACK
+#define INCLUDED_TASK_DRAW_BACK
+
+#ifndef INCLUDED_SCHED_TASK
+#  include "SchedTask.h"
+#endif
+
+class DrawBack : public SchedTask {
+public:
+    SchedConstructor(DrawBack);
+
+    int run(void *rbuf, void *wbuf);
+
+    void linebuf_init(int *buf, int width, int rgb);
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/spe/DrawSpan.cpp	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,670 @@
+#include <stdlib.h>
+#include <string.h>
+#include <spu_intrinsics.h>
+#include "DrawSpan.h"
+#include "polygon_pack.h"
+#include "texture.h"
+#include "viewer_types.h"
+#include "Func.h"
+
+SchedDefineTask(DrawSpan);
+
+#define TEX_LOAD1      0
+#define TEX_LOAD2      1
+#define SPAN_PACK_LOAD 2
+#define FB_STORE       3
+
+DrawSpan::~DrawSpan(void)
+{
+    smanager->dma_wait(FB_STORE);
+    free((void*)((int)linebuf*doneWrite));
+}
+
+inline vector float
+spu_re_nrm(vector float a)
+{
+    vector float unit = (vector float){1.0, 1.0, 1.0, 1.0};
+    vector float approximation;
+
+    approximation = spu_re(a);
+    return spu_madd(spu_nmsub(approximation, a, unit),
+                    approximation, approximation);
+}
+
+
+vector signed int
+getLocalPositionVec(vector signed int d, signed int offset)
+{
+    return spu_and(d, spu_splats(offset-1));
+}
+
+vector signed int
+getLocalXVec(vector signed int x)
+{
+    return getLocalPositionVec(x, split_screen_w);
+}
+
+
+/**
+ * テクスチャは、TEXTURE_SPLIT_PIXEL^2 のブロックに分割する
+ *
+ * +---+---+---+---+---+---+
+ * | 0 | 1 | 2 | 3 | 4 | 5 |
+ * +---+---+---+---+---+---+
+ * |   |   |   |   |   |11 |
+ * +---+---+---+---+---+---+
+ * |   |   |   |   |   |17 |
+ * +---+---+---+---+---+---+
+ * |   |   |   |   |   |23 |
+ * +---+---+---+---+---+---+
+ * |   |   |   |   |   |29 |
+ * +---+---+---+---+---+---+
+ * |   |   |   |   |   |35 |
+ * +---+---+---+---+---+---+
+ *
+ * 一辺を TEXTURE_SPLIT とする
+ * 各ブロックの数字がブロックIDとなる。
+ */
+
+/**
+ * テクスチャの座標から、
+ * テクスチャのどのブロックかを求める
+ *
+ * @param[in] tx X coordinates of texture
+ * @param[in] tx Y coordinates of texture
+ * @param[in] twidth  Width of texture
+ * @return block ID
+ */
+int
+DrawSpan::getTexBlock(int tx, int ty, int twidth)
+{
+     int blockX, blockY;
+
+     blockX = tx / TEXTURE_SPLIT_PIXEL;
+     blockY = ty / TEXTURE_SPLIT_PIXEL;
+
+     return blockX + (twidth/TEXTURE_SPLIT_PIXEL)*blockY;
+}
+
+/**
+ * block ID と、テクスチャの TOP address から
+ * (tx,ty) で使われるテクスチャの Tile addres を求める
+ *
+ * @param[in] tx X coordinates of texture
+ * @param[in] tx Y coordinates of texture
+ * @param[in] tw Width of texture
+ * @param[in] tex_addr_top (tx,ty) で使うテクスチャの先頭address
+ * @return block ID
+ */
+uint32*
+DrawSpan::getTile(int tx, int ty, int tw, uint32 *tex_addr_top)
+{
+    int block = getTexBlock(tx, ty, tw);
+    return tex_addr_top + block*TEXTURE_BLOCK_SIZE;
+}
+
+/**
+ * FrameBuffer に書き込む rgb の領域初期化
+ *
+ * @param width  Width of Buffer
+ * @param height Height of Buffer
+ * @param rgb    Initial value of RGB at Buffer
+ * @return Buffer
+ */
+int*
+DrawSpan::linebuf_init(int width, int height, int rgb)
+{
+    int *buf = (int*)smanager->allocate(sizeof(int)*width*height);
+
+    for (int i = 0; i < width*height; i++) {
+	buf[i] = rgb;
+    }
+
+    return buf;
+}
+
+/**
+ * Z-Buffer の初期化
+ *
+ * @param width  Width of Z-Buffer
+ * @param height Height of Z-Buffer
+ * @return Z-Buffer
+ */
+float*
+DrawSpan::zRow_init(int width, int height)
+{
+    float *buf = (float*)smanager->allocate(sizeof(float)*width*height);
+    float def = 65535.0f;
+
+#if 0
+    for (int i = 0; i < width*height; i++) {
+	buf[i] = def;
+    }
+#else 
+    vector float init = spu_splats(0.0f);
+    vector float defi = spu_splats(def);
+
+    for (int i = 0; i < width*height; i += 4) {
+	vector float *out = (vector float *)&buf[i];
+
+	*out = spu_add(init, defi);
+    }
+#endif
+
+    return buf;
+}
+
+
+/**
+ * Span が使う Texture Tile があるか
+ *
+ * @retval != NULL 存在する
+ * @retval NULL    存在しない
+ */
+TilePtr
+DrawSpan::isAvailableTile(uint32 *addr)
+{
+    return hash->get(addr);
+}
+
+void
+DrawSpan::set_rgb(uint32 *addr, int tag)
+{
+    TilePtr tile;
+
+    if (isAvailableTile(addr)) {
+	return;
+    }
+
+    tile = tileList->nextTile();
+    /**
+     * FIFO なので、もし前のが残っていれば削除
+     */
+    hash->remove(tile->texture_addr);
+    
+    tile->texture_addr = addr;
+    
+    hash->put(tile->texture_addr, tile);
+    smanager->dma_load(tile->pixel, (uint32)addr,
+		       sizeof(uint32)*TEXTURE_BLOCK_SIZE, tag);
+}
+
+/**
+ * 
+ */
+void
+DrawSpan::set_rgbs(uint32 *cur_addr, uint32 *max_addr, int wait_tag)
+{
+    uint32 curp   = (uint32)cur_addr;
+    uint32 maxp   = (uint32)max_addr;
+    uint32 startp = curp;
+    uint32 diff   = sizeof(int)*TEXTURE_BLOCK_SIZE;
+    int length = (int)maxp-(int)curp;
+
+    int cmp = (length < 0);
+
+#if 1
+    length += cmp*(-1)*length*2;
+    startp = cmp*maxp + !cmp*curp;
+#else
+    if (length < 0) {
+	length = -length;
+	startp = maxp;
+    }
+#endif
+
+    for (int i = 0; i <= length; i += diff) {
+	set_rgb((uint32*)(startp + i), wait_tag);
+    }
+}
+
+uint32
+DrawSpan::get_rgb(int tx, int ty, uint32 *addr)
+{
+    TilePtr tile;
+
+    tile = hash->get(addr);
+    return tile->pixel[(TEXTURE_SPLIT_PIXEL)*ty+tx];
+}
+
+/**
+ * DrawSpan の再起動 (DrawSpanRenew 生成)
+ *
+ * @param[in] spack 現在処理している SpanPack
+ * @param[in] cur_span_x span->length_x != 1 の時の Span の処理で
+ *                       どこまで進んでいるか
+ */
+void
+DrawSpan::reboot(SpanPackPtr spack, int cur_span_x)
+{
+    DrawSpanArgPtr args =
+	(DrawSpanArgPtr)smanager->allocate(sizeof(DrawSpanArg));
+    TaskPtr renew_task = smanager->create_task(TASK_DRAW_SPAN2);
+
+    // 数が多いので構造体で渡す
+    args->display      = smanager->get_param(0);
+    args->screen_width = smanager->get_param(1);
+    args->rangex_start = smanager->get_param(2);
+    args->rangex_end   = smanager->get_param(3);
+    args->rangey       = smanager->get_param(4);
+    renew_task->add_param((int)args);
+
+    /**
+     * SpanPack は続きから開始するので、
+     * 現在の状態をコピーしておく。
+     * spack は rbuf から取得してる可能性があり
+     * rbuf はシステムが自動的に free() するため
+     * アドレスだけ渡すのはNG
+     */ 
+    SpanPackPtr curr = (SpanPackPtr)smanager->allocate(sizeof(SpanPack));
+    memcpy(curr, spack, sizeof(SpanPack));
+    renew_task->add_param((int)curr);
+    renew_task->add_param(cur_span_x);
+
+    // linebuf と zRow も引き継がせる
+    renew_task->add_param((int)linebuf);
+    renew_task->add_param((int)zRow);
+
+    /**
+     * 再起動したタスクを待つ
+     */ 
+    smanager->wait_task(renew_task);
+
+    // next_spack は free() するので wait する
+    smanager->dma_wait(SPAN_PACK_LOAD);
+}
+
+void
+DrawSpan::writebuffer(unsigned int display, int buf_width, int height,
+		      int screen_width)
+{
+    for (int i = 0; i < height; i++) {
+	smanager->dma_store(&linebuf[i*buf_width],
+			    display + (sizeof(int)*screen_width*i),
+			    sizeof(int)*buf_width, FB_STORE);
+    }
+
+    doneWrite = 1;
+}
+
+/**
+ * zRow と Linebuf を更新する
+ *
+ * @param zpos     更新する pixel のZ座標
+ * @param rangex   このタスクが処理する描画領域の x の長さ
+ * @param x        pixel の、描画領域内での x 座標
+ * @param y        〃 の、y 座標
+ * @param tex_x    pixel が使用するテクスチャの、Tile (8x8) 内での x 座標
+ * @param tex_y    〃 の y 座標
+ * @param tex_addr テクスチャのアドレス(MainMemory)
+ */
+void
+DrawSpan::updateBuffer(float zpos, int rangex, int x, int y,
+		       int tex_x, int tex_y, uint32 *tex_addr)
+{
+    int rgb = get_rgb(tex_x, tex_y, tex_addr);
+		    
+    zRow[x + (rangex*y)] = zpos;
+    linebuf[x + (rangex*y)] = rgb;
+}
+
+/**
+ * 長さが 1 の Span の描画 (要するに 1 pixel)
+ *
+ * @param span Span
+ * @param startx 描画開始範囲
+ * @param endx 描画終了範囲
+ */
+int
+DrawSpan::drawDot1(SpanPtr span, int startx, int endx, int wait_tag)
+{
+    int rangex = endx - startx + 1;
+
+    /* span->x に対応する Texture の座標 (tex_xpos, tex_ypos) */
+    int tex_xpos, tex_ypos;
+
+    // span の始点に対応する Texture の座標 (tex1, tey1)
+    float tex = span->tex_x1;
+    float tey = span->tex_y1;
+
+    // span の始点に対応する z 座標
+    float zpos = span->start_z;
+
+    /* Tile 内での座標 */
+    int localx = getLocalX(span->x-1);
+    int localy = getLocalY(span->y-1);
+
+    /**
+     * (tex_xpos, tex_ypos) の、Tile 内(上の図参照)での座標と
+     * そのブロックのアドレス(MainMemory)
+     */
+    int tex_localx;
+    int tex_localy;
+    uint32 *tex_addr;
+
+    if (span->x < startx || endx < span->x) {
+	return -1;
+    }
+
+    tex_xpos = (int)((span->tex_width-1) * tex);
+    tex_ypos = (int)((span->tex_height-1) * tey);
+
+    if (zpos < zRow[localx + (rangex*localy)]) {
+	tex_addr = getTile(tex_xpos, tex_ypos,
+			   span->tex_width, span->tex_addr);
+	tex_localx = tex_xpos % TEXTURE_SPLIT_PIXEL;
+	tex_localy = tex_ypos % TEXTURE_SPLIT_PIXEL;
+
+	if (!isAvailableTile(tex_addr)) {
+	    set_rgb(tex_addr, wait_tag);
+	    smanager->dma_wait(wait_tag);
+	    //return startx;
+	}
+
+	updateBuffer(zpos, rangex, localx, localy,
+		     tex_localx, tex_localy, tex_addr);
+    }
+
+    return -1;
+}
+
+void
+DrawSpan::drawDot2(SpanPtr span, int startx, int end, int js, int wait_tag)
+{
+    //printf("%d\n", js);
+}
+
+/**
+ * 長さが 1 より大きい Span の描画
+ *
+ * 本来の目的として、この関数(drawLine1) では
+ *   : 既に SPE 上に Tile のある pixel だけ描画
+ *   : それ以外は、ここで予め DMA load しておき、
+ *   : drawLine2 で一気に描画する
+ * ってものだったんだけど、どうも上手く行かなかったので
+ * 今は drawLine1 で load -> wait -> rendering を全部やってます
+ * (rendering といっても、rendering buffer に書き込むだけで
+ *  まだ main memory (frame buffer) に dma store してるわけではない)
+ *      
+ * @param span Span
+ * @param startx 描画開始範囲
+ * @param endx 描画終了範囲
+ * @return 「span のどの位置まで rendering が終わったか」の x 座標
+ */
+int
+DrawSpan::drawLine1(SpanPtr span, int startx, int endx, int wait_tag)
+{
+    int x = span->x;
+    int rangex = endx - startx + 1;
+    int x_len = span->length_x;
+
+    int js = (x < startx) ? startx - x : 0;
+    int je = (x + x_len > endx) ? endx - x : x_len;
+
+    /* span->x に対応する Texture の座標 (tex_xpos, tex_ypos) */
+    int tex_xpos, tex_ypos;
+
+    // span の始点に対応する座標 (tex1, tey1)
+    float tex1 = span->tex_x1;
+    float tey1 = span->tex_y1;
+
+    // span の終点に対応する座標 (tex2, tey2)
+    float tex2 = span->tex_x2;
+    float tey2 = span->tex_y2;
+
+    // span の始点、終点に対応する z 座標
+    float zpos1 = span->start_z;
+    float zpos2 = span->end_z;
+
+    // Tile 内での座標
+    int localx, localy = getLocalY(span->y-1);
+
+    int ret = je+1;
+
+    //for (int j = js; j <= je; j++) {
+    for (int j = je; j >= js; j--) {
+	float tex_x, tex_y, tex_z;
+
+	localx = getLocalX(x-1+j);
+
+	tex_z = zpos1*(x_len-1-j)/(x_len-1) + zpos2*j/(x_len-1);
+
+	tex_x = tex1*(x_len-1-j)/(x_len-1) + tex2*j/(x_len-1);
+	tex_y = tey1*(x_len-1-j)/(x_len-1) + tey2*j/(x_len-1);
+	if (tex_x > 1) tex_x = 1;
+	if (tex_x < 0) tex_x = 0;
+	if (tex_y > 1) tex_y = 1;
+	if (tex_y < 0) tex_y = 0;
+	tex_xpos = (int)((span->tex_width-1) * tex_x);
+	tex_ypos = (int)((span->tex_height-1) * tex_y);
+		    
+	if (tex_z < zRow[localx + (rangex*localy)]) {
+	    // (tex_xpos, tex_ypos) の、Tile 内(上の図参照)での座標と
+	    // そのブロックのアドレス(MainMemory)
+	    uint32 *tex_addr;
+	    int tex_localx;
+	    int tex_localy;
+
+	    tex_addr = getTile(tex_xpos, tex_ypos,
+			       span->tex_width, span->tex_addr);
+	    tex_localx = tex_xpos % TEXTURE_SPLIT_PIXEL;
+	    tex_localy = tex_ypos % TEXTURE_SPLIT_PIXEL;
+
+	    if (!isAvailableTile(tex_addr)) {
+#if 0
+		// span が必要とするであろう tile を予想紙
+		// set_rgbs で複数同時に load しようとしている図
+		// まあ上手くいかなかったんだけど。。
+		tex_x = tex1*(x_len-1-js)/(x_len-1) + tex2*js/(x_len-1);
+		if (tex_x > 1) tex_x = 1;
+		if (tex_x < 0) tex_x = 0;
+		tex_xpos = (int)((span->tex_width-1) * tex_x);
+
+		uint32 *max_addr = getTile(tex_xpos, tex_ypos,
+					   span->tex_width, span->tex_addr);
+
+		set_rgbs(tex_addr, max_addr, wait_tag);
+		return js;
+#else
+		set_rgb(tex_addr, wait_tag);
+		smanager->dma_wait(wait_tag);
+#endif
+	    }
+
+	    updateBuffer(tex_z, rangex, localx, localy,
+			 tex_localx, tex_localy, tex_addr);
+	}
+    }
+
+    return ret;
+}
+
+/**
+ * 長さが 1 より大きい Span の描画 (2段階目)
+ *
+ * 上にあるように、drawLine2 は今は動いてないです
+ * 正確には、js が startx ~ endx 範囲外にあり開始されないってところ
+ *
+ * @param span Span
+ * @param startx 描画開始範囲
+ * @param endx 描画終了範囲
+ * @param js 前回(drawLine1) で span のどこまで終わっているか
+ */
+void
+DrawSpan::drawLine2(SpanPtr span, int startx, int endx, int js, int wait_tag)
+{
+    int x = span->x;
+    int rangex = endx - startx + 1;
+    int x_len = span->length_x;
+
+    //int js = startx;
+    int je = (x + x_len > endx) ? endx - x : x_len;
+
+    /* span->x に対応する Texture の座標 (tex_xpos, tex_ypos) */
+    int tex_xpos, tex_ypos;
+
+    // span の始点に対応する座標 (tex1, tey1)
+    float tex1 = span->tex_x1;
+    float tey1 = span->tex_y1;
+
+    // span の終点に対応する座標 (tex2, tey2)
+    float tex2 = span->tex_x2;
+    float tey2 = span->tex_y2;
+
+    // span の始点、終点に対応する z 座標
+    float zpos1 = span->start_z;
+    float zpos2 = span->end_z;
+
+    // Tile 内での座標
+    int localx, localy = getLocalY(span->y-1);
+
+    // (tex_xpos, tex_ypos) の、Tile 内(上の図参照)での座標と
+    // そのブロックのアドレス(MainMemory)
+    int tex_localx;
+    int tex_localy;
+    uint32 *tex_addr;
+
+    float tex_x, tex_y, tex_z;
+
+    smanager->dma_wait(wait_tag);
+
+    for (int j = js; j <= je; j++) {
+	localx = getLocalX(x-1+j);
+
+	tex_z = zpos1*(x_len-1-j)/(x_len-1) + zpos2*j/(x_len-1);
+
+	tex_x = tex1*(x_len-1-j)/(x_len-1) + tex2*j/(x_len-1);
+	tex_y = tey1*(x_len-1-j)/(x_len-1) + tey2*j/(x_len-1);
+	if (tex_x > 1) tex_x = 1;
+	if (tex_x < 0) tex_x = 0;
+	if (tex_y > 1) tex_y = 1;
+	if (tex_y < 0) tex_y = 0;
+	tex_xpos = (int)((span->tex_width-1) * tex_x);
+	tex_ypos = (int)((span->tex_height-1) * tex_y);
+
+	if (tex_z < zRow[localx + (rangex*localy)]) {
+	    tex_addr = getTile(tex_xpos, tex_ypos,
+			       span->tex_width, span->tex_addr);
+	    tex_localx = tex_xpos % TEXTURE_SPLIT_PIXEL;
+	    tex_localy = tex_ypos % TEXTURE_SPLIT_PIXEL;
+
+	    updateBuffer(tex_z, rangex, localx, localy,
+			 tex_localx, tex_localy, tex_addr);
+	}
+    }    
+}
+
+int
+DrawSpan::run(void *rbuf, void *wbuf)
+{
+    SpanPackPtr spack = (SpanPackPtr)smanager->get_input(0);
+    SpanPackPtr next_spack = (SpanPackPtr)smanager->allocate(sizeof(SpanPack));
+    SpanPackPtr free_spack = next_spack; // next_spack の free() 用
+    Span *span;
+
+    Span nop_span;
+    nop_span.length_x = 1;
+
+    int (DrawSpan::*drawFunc1[2])(SpanPtr, int, int, int) = {
+	&DrawSpan::drawDot1, &DrawSpan::drawLine1
+    };
+
+    void (DrawSpan::*drawFunc2[2])(SpanPtr, int, int, int, int) = {
+	&DrawSpan::drawDot2, &DrawSpan::drawLine2
+    };
+
+    uint32 display   = smanager->get_param(0);
+    int screen_width = smanager->get_param(1);
+    int rangex_start = smanager->get_param(2);
+    int rangex_end   = smanager->get_param(3); 
+    
+    // このタスクが担当する x の範囲
+    int rangex = rangex_end - rangex_start + 1;
+
+    // y の範囲
+    int rangey = smanager->get_param(4);
+
+    hash = (TileHashPtr)smanager->global_get(GLOBAL_TEXTURE_HASH);
+    tileList = (TileListPtr)smanager->global_get(GLOBAL_TILE_LIST);
+
+    zRow = zRow_init(rangex, rangey);
+    //linebuf = linebuf_init(rangex, rangey, 0x00ffffff);
+    linebuf = linebuf_init(rangex, rangey, 0);
+
+    doneWrite = 0;
+
+    int tl_tag[2] = {TEX_LOAD1, TEX_LOAD2};
+    int tl_tag_flg1 = 0;
+    int tl_tag_flg2 = 1;
+    
+    do {
+	/**
+	 * SpanPack->next が存在する場合、
+	 * 現在の SpanPack を処理してる間に
+	 * 次の SpanPack の DMA 転送を行う
+	 */
+	if (spack->next != NULL) {
+	    smanager->dma_load(next_spack, (uint32)spack->next,
+			       sizeof(SpanPack), SPAN_PACK_LOAD);
+	} else {
+	    next_spack = NULL;
+	}
+
+	SpanPtr resume_span = &nop_span;
+	int resume_span_x = 0;
+
+	for (int t = 0; t < spack->info.size; t++) {	  
+	    SpanPtr next_span;
+	    int next_span_x;
+
+	    span = &spack->span[t];
+
+	    /**
+	     * span の長さによって、drawLine か drawDot を選択している
+	     */ 
+	    next_span_x
+		= (this->*drawFunc1[(span->length_x != 1)])(
+		    span, rangex_start, rangex_end, tl_tag[tl_tag_flg1]);
+	    next_span = span;
+
+	    (this->*drawFunc2[(resume_span->length_x != 1)])(
+		resume_span, rangex_start, rangex_end, resume_span_x,
+		tl_tag[tl_tag_flg2]);
+
+	    resume_span = next_span;
+	    resume_span_x = next_span_x;
+	    
+	    //smanager->dma_wait(tl_tag[tl_tag_flg1]);
+
+	    tl_tag_flg1 ^= 1;
+	    tl_tag_flg2 ^= 1;
+	}
+	
+	// 現在 drawLine2、drawDot2 は機能してないので
+	//(this->*drawFunc2[(resume_span->length_x != 1)])(
+	//resume_span, rangex_start, rangex_end, resume_span_x,
+	//tl_tag[tl_tag_flg1]);
+
+	smanager->dma_wait(SPAN_PACK_LOAD);
+
+	SpanPackPtr tmp_spack = spack;
+	spack = next_spack;
+	next_spack = tmp_spack;
+    } while (spack);
+
+    writebuffer(display, rangex, rangey, screen_width);
+
+    // linebuf は、writebuffer() の dma_store を wait する
+    // DrawSpan::~DrawSpan() 内で free する。
+    //free(linebuf);
+    free(zRow);
+
+//FINISH:
+    /**
+     * goto FINISH; の時は reboot なので
+     * linebuf, zRow は free() しない
+     */
+
+    free(free_spack);
+    return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/spe/DrawSpan.h	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,64 @@
+#ifndef INCLUDED_TASK_DRAW_SPAN
+#define INCLUDED_TASK_DRAW_SPAN
+
+#ifndef INCLUDED_SCHED_TASK
+#  include "SchedTask.h"
+#endif
+
+#ifndef INCLUDED_TAPESTRY
+#  include "Tapestry.h"
+#endif
+
+#ifndef INCLUDED_SPAN_PACK
+#  include "SpanPack.h"
+#endif
+
+#ifndef INCLUDED_TEXTURE_HASH
+#  include "TileHash.h"
+#endif
+
+class DrawSpan : public SchedTask {
+public:
+    SchedConstructor(DrawSpan);
+
+    int *linebuf;
+    float *zRow;
+    TileHashPtr hash;
+    TileListPtr tileList;
+    int doneWrite;
+
+    ~DrawSpan(void);
+
+    int run(void *rbuf, void *wbuf);
+
+    int* linebuf_init(int width, int height, int rgb);
+    float* zRow_init(int width, int height);
+    void set_rgb(uint32 *addr, int wait_tag);
+    void set_rgbs(uint32 *addr, uint32 *max_addr, int wait_tag);
+    uint32 get_rgb(int tx, int ty, uint32 *addr);
+    TilePtr isAvailableTile(uint32 *addr);
+    uint32* getTile(int tx, int ty, int tw, uint32 *tex_addr_top);
+    int getTexBlock(int tx, int ty, int twidth);
+    void writebuffer(unsigned int display, int width, int height,
+		     int screen_width);
+    void updateBuffer(float zpos, int rangex, int x, int y,
+		      int tex_x, int tex_y, uint32 *tex_addr);
+
+
+    void reboot(SpanPackPtr spack, int cur_span_x);
+
+    int drawDot1(SpanPtr span, int startx, int endx, int wait_tag);
+    void drawDot2(SpanPtr span, int startx, int endx, int js, int wait_tag);
+    int drawLine1(SpanPtr span, int startx, int endx, int wait_tag);
+    void drawLine2(SpanPtr span, int startx, int endx, int js, int wait_tag);
+};
+
+typedef struct {
+    uint32 display;
+    int screen_width;
+    int rangex_start;
+    int rangex_end;
+    int rangey;
+} DrawSpanArg, *DrawSpanArgPtr;
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/spe/DrawSpanRenew.cpp	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,226 @@
+#include <stdlib.h>
+#include <string.h>
+#include <spu_mfcio.h>
+#include "DrawSpanRenew.h"
+#include "polygon_pack.h"
+#include "SpanPack.h"
+#include "texture.h"
+#include "viewer_types.h"
+#include "Func.h"
+
+#define SPAN_PACK_LOAD 0
+#define TEX_LOAD 1
+#define FB_STORE 2
+
+SchedDefineTask(DrawSpanRenew);
+
+void
+DrawSpanRenew::reboot(SpanPackPtr spack, int cur_span_x)
+{
+    TaskPtr renew_task = smanager->create_task(TASK_DRAW_SPAN2);
+
+    renew_task->add_param((int)args);
+
+    SpanPackPtr curr = (SpanPackPtr)smanager->allocate(sizeof(SpanPack));
+    memcpy(curr, spack, sizeof(SpanPack));
+    renew_task->add_param((int)curr);
+    renew_task->add_param(cur_span_x);
+
+    // linebuf  zRow Ѥ
+    renew_task->add_param((int)linebuf);
+    renew_task->add_param((int)zRow);
+
+    //fprintf(stderr, "[%p] start %u\n", curr, spu_readch(SPU_RdDec));
+
+    /**
+     * ƵưԤ
+     */ 
+    smanager->wait_task(renew_task);
+
+    // next_spack  free() Τ wait 
+    smanager->dma_wait(SPAN_PACK_LOAD);
+}
+
+int
+DrawSpanRenew::run(void *rbuf, void *wbuf)
+{
+    SpanPackPtr spack = (SpanPackPtr)smanager->get_param(1);
+    SpanPackPtr next_spack = (SpanPackPtr)smanager->allocate(sizeof(SpanPack));
+    SpanPackPtr free_spack1 = spack;
+    SpanPackPtr free_spack2 = next_spack;
+    Span *span;
+
+    args = (DrawSpanArgPtr)smanager->get_param(0);
+    uint32 display   = args->display;
+    int screen_width = args->screen_width;
+    int rangex_start = args->rangex_start;
+    int rangex_end   = args->rangex_end;
+
+    // Υô x ϰ
+    int rangex = rangex_end - rangex_start + 1;
+
+    // y ϰ (render_y + rangey - 1)
+    int rangey = args->rangey;
+
+    hash = (TileHashPtr)smanager->global_get(GLOBAL_TEXTURE_HASH);
+    tileList = (TileListPtr)smanager->global_get(GLOBAL_TILE_LIST);
+    
+    linebuf = (int*)smanager->get_param(3);
+    zRow = (float*)smanager->get_param(4);
+
+    doneWrite = 0;
+
+    // span->length_x νǤκƵư
+    int js_cont = smanager->get_param(2);
+
+    //fprintf(stderr, "[%p] end   %u\n", spack, spu_readch(SPU_RdDec));
+
+    smanager->dma_wait(TEX_LOAD);
+
+    do {
+	/**
+	 * SpanPack->next ¸ߤ硢
+	 * ߤ SpanPack Ƥ֤
+	 *  SpanPack  DMA žԤ
+	 */
+	if (spack->next != NULL) {
+	    smanager->dma_load(next_spack, (uint32)spack->next,
+			       sizeof(SpanPack), SPAN_PACK_LOAD);
+	} else {
+	    next_spack = NULL;
+	}
+
+	for (int t = spack->info.start; t < spack->info.size; t++) {	  
+	    span = &spack->span[t];
+
+	    uint32 rgb = 0x00ff0000;
+	    float tex1 = span->tex_x1;
+	    float tex2 = span->tex_x2;
+	    float tey1 = span->tex_y1;
+	    float tey2 = span->tex_y2;
+
+	    /**
+	     * Span  1 pixel 
+	     * ƥκɸ
+	     */
+	    int tex_xpos;
+	    int tex_ypos;
+
+	    /**
+	     * (tex_xpos, tex_ypos) Ρ֥å(ο޻)Ǥκɸ
+	     * Υ֥åΥɥ쥹(MainMemory)
+	     */
+	    int tex_localx;
+	    int tex_localy;
+	    uint32 *tex_addr;
+
+	    int x = span->x;
+	    int y = span->y;
+	    int x_len = span->length_x;
+	    float z = span->start_z;
+	    float zpos = span->end_z;
+
+	    // ɸ [0 .. split_screen_w-1] 褦 x,y  -1
+	    int localx = getLocalX(x-1);
+	    int localy = getLocalY(y-1);
+
+	    if (x_len == 1) {
+		if (x < rangex_start || rangex_end < x) {
+		    continue;
+		}
+
+		tex_xpos = (int)((span->tex_width-1) * tex1);
+		tex_ypos = (int)((span->tex_height-1) * tey1);
+
+		if (zpos < zRow[localx + (rangex * localy)]) {
+		    tex_addr = getTile(tex_xpos, tex_ypos,
+				       span->tex_width, span->tex_addr);
+		    tex_localx = tex_xpos % TEXTURE_SPLIT_PIXEL;
+		    tex_localy = tex_ypos % TEXTURE_SPLIT_PIXEL;
+
+		    if (!isAvailableTile(tex_addr)) {
+			set_rgb(tex_addr, 0);
+			smanager->dma_wait(0);
+		    }
+		    
+		    rgb = get_rgb(tex_localx, tex_localy, tex_addr);
+
+		    zRow[localx + (rangex*localy)] = zpos;
+		    linebuf[localx + (rangex*localy)] = rgb;
+		}
+	    } else {
+		int js = (x < rangex_start) ? rangex_start - x : 0;
+		int je = (x + x_len > rangex_end) ? rangex_end - x : x_len;
+		float tex_x, tex_y, tex_z;
+		
+		/**
+		 * ӤСʸƵưޤǤ
+		 * js_cont ϻȤʤ 0 ˤƤ櫓ɡ
+		 * ǽΰΤˤϤɤΡ
+		 */
+		js = (js < js_cont) ? js_cont : js;
+		js_cont = 0;
+
+		for (int j = js; j <= je; j++) {
+		    localx = getLocalX(x-1+j);
+
+		    tex_z = z*(x_len-1-j)/(x_len-1) + zpos*j/(x_len-1);
+
+		    tex_x = tex1*(x_len-1-j)/(x_len-1) + tex2*j/(x_len-1);
+		    tex_y = tey1*(x_len-1-j)/(x_len-1) + tey2*j/(x_len-1);
+		    if (tex_x > 1) tex_x = 1;
+		    if (tex_x < 0) tex_x = 0;
+		    if (tex_y > 1) tex_y = 1;
+		    if (tex_y < 0) tex_y = 0;
+		    tex_xpos = (int)((span->tex_width-1) * tex_x);
+		    tex_ypos = (int)((span->tex_height-1) * tex_y);
+		    
+		    if (tex_z < zRow[localx + (rangex*localy)]) {
+			tex_addr = getTile(tex_xpos, tex_ypos,
+					   span->tex_width, span->tex_addr);
+			tex_localx = tex_xpos % TEXTURE_SPLIT_PIXEL;
+			tex_localy = tex_ypos % TEXTURE_SPLIT_PIXEL;
+
+			if (!isAvailableTile(tex_addr)) {
+			    spack->info.start = t;
+#if 0
+			    set_rgbs(tex_addr,
+				     getTile(span->tex_width-1, tex_ypos,
+					     span->tex_width, span->tex_addr));
+			    reboot(spack, j);
+			    goto FINISH;
+#else
+			    set_rgb(tex_addr, TEX_LOAD);
+			    smanager->dma_wait(TEX_LOAD);
+#endif
+			}
+			
+			rgb = get_rgb(tex_localx, tex_localy, tex_addr);
+		    
+			zRow[localx + (rangex*localy)] = tex_z;
+			linebuf[localx + (rangex*localy)] = rgb;
+		    }
+		}
+	    }
+	}
+
+	smanager->dma_wait(SPAN_PACK_LOAD);
+
+	SpanPackPtr tmp_spack = spack;
+	spack = next_spack;
+	next_spack = tmp_spack;
+    } while (spack);
+
+    writebuffer(display, rangex, rangey, screen_width);
+
+    free(zRow);
+    free(args);
+
+    /**
+     * linebuf, zRow, args  RenewTask Ѥ
+     */
+    free(free_spack1);
+    free(free_spack2);
+
+    return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/spe/DrawSpanRenew.h	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,20 @@
+#ifndef INCLUDED_TASK_DRAW_SPAN2
+#define INCLUDED_TASK_DRAW_SPAN2
+
+#ifndef INCLUDED_TASK_DRAW_SPAN
+#  include "DrawSpan.h"
+#endif
+
+class DrawSpanRenew : public DrawSpan {
+public:
+    SchedConstructor(DrawSpanRenew);
+
+    DrawSpanArgPtr args;
+
+    int run(void *rbuf, void *wbuf);
+
+    // override
+    void reboot(SpanPackPtr spack, int cur_span_x);
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/spe/Load_Texture.cpp	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,30 @@
+#include <stdlib.h>
+#include <string.h>
+#include "Load_Texture.h"
+#include "texture.h"
+#include "TileHash.h"
+#include "Func.h"
+
+SchedDefineTask(LoadTexture);
+
+/**
+ * 「Load」といいながら、結局 DrawSpan で使う
+ * Hash の準備だけなので、名前変えないとなー
+ */
+int 
+LoadTexture::run(void *rbuf , void *wbuf) 
+{
+    /**
+     * 現在 global_alloc() では new をサポートしてないので
+     * コンストラクタ呼ぶために placement new してます。
+     */
+    void *hash_tmp
+	= smanager->global_alloc(GLOBAL_TEXTURE_HASH, sizeof(TileHash));
+    new(hash_tmp) TileHash;
+
+    void *tileList_tmp
+	= smanager->global_alloc(GLOBAL_TILE_LIST, sizeof(TileList));
+    new(tileList_tmp) TileList;
+
+    return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/spe/Load_Texture.h	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,19 @@
+#ifndef INCLUDED_TASK_LOAD_TEXTURE
+#define INCLUDED_TASK_LOAD_TEXTURE
+
+#ifndef INCLUDED_SCHED_TASK
+#include  "SchedTask.h"
+#endif
+
+#ifndef INCLUDED_TAPESTRY
+#  include "Tapestry.h"
+#endif
+
+class LoadTexture : public SchedTask {
+public:
+    SchedConstructor(LoadTexture);
+
+    int run(void *rbuf, void *wbuf);
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/spe/Set_Texture.cpp	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,31 @@
+#include <string.h>
+#include "Set_Texture.h"
+#include "texture.h"
+
+SchedDefineTask(SetTexture);
+
+//texture をglobal 領域にコピーするタスク
+int 
+SetTexture::run(void *rbuf, void *wbuf)
+{
+    void *src[4];
+    
+    src[0] = get_input(rbuf, 0);
+    src[1] = get_input(rbuf, 1);
+    src[2] = get_input(rbuf, 2);
+    src[3] = get_input(rbuf, 3);
+    
+    if (global_get(TEXTURE_ID)) {
+	return 0;
+    } else {
+	//タスクが共有できる領域確保
+	void *data = global_alloc(TEXTURE_ID, MAX_LOAD_SIZE*4);
+
+	memcpy(data, src[0], MAX_LOAD_SIZE);
+	memcpy((void*)((int)data + MAX_LOAD_SIZE), src[1], MAX_LOAD_SIZE);
+	memcpy((void*)((int)data + MAX_LOAD_SIZE*2), src[2], MAX_LOAD_SIZE);
+	memcpy((void*)((int)data + MAX_LOAD_SIZE*3), src[3], MAX_LOAD_SIZE);
+    }
+
+    return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/spe/Set_Texture.h	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,16 @@
+#ifndef INCLUDED_TASK_LOAD_TEXTURE
+#define INCLUDED_TASK_LOAD_TEXTURE
+
+#ifndef INCLUDED_SCHED_TASK
+#  include  "SchedTask.h"
+#endif
+
+class SetTexture : public SchedTask {
+public:
+    SchedConstructor(SetTexture);
+
+    int run(void *rbuf, void *wbuf);
+};
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/spe/TileHash.cpp	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,88 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "TileHash.h"
+
+static unsigned short PRIME[8] = {
+    0x002, 0x065, 0x0c7, 0x133, 0x191, 0x1f3, 0x259, 0x2bd,
+};
+
+int
+TileHash::hash(uint32 data)
+{
+    int value = 0;
+    int n = 0;
+    int key;
+
+    for (int i = 0; i < 8; i ++) {
+	key = data & 0xf;
+	value += key * PRIME[n++];
+	data >>= 4;
+    }
+
+    return value % hashSize;
+}
+
+TileHash::TileHash(void)
+{
+    hashSize = 263;
+    tableSize = sizeof(TilePtr)*hashSize;
+
+    table = (TilePtr*)malloc(tableSize);
+    clear();
+}
+
+int
+TileHash::put(uint32 *key, TilePtr data)
+{
+    int hashval = hash((uint32)key);
+
+    for (int i = 0; i < hashSize/2; i++) {
+	int index = (hashval + i*i)%hashSize;
+
+	if (table[index] == 0) { // 空の table に入れる
+	    table[index] = data;
+	    return index;
+	}
+    }
+
+    return -1;
+}
+
+TilePtr
+TileHash::get(uint32 *key)
+{
+    int hashval = hash((uint32)key);
+
+    for (int i = 0; i < hashSize/2; i++) {
+	int index = (hashval + i*i)%hashSize;
+	
+	if (table[index] != NULL &&
+	    table[index]->texture_addr == key) {
+	    return table[index];
+	}
+    }
+
+    return NULL;
+}
+
+void
+TileHash::remove(uint32 *key)
+{
+    int hashval = hash((uint32)key);
+
+    for (int i = 0; i < hashSize/2; i++) {
+	int index = (hashval + i*i)%hashSize;
+	
+	if (table[index] != NULL &&
+	    table[index]->texture_addr == key) {
+	    table[index] = NULL;
+	}
+    }
+}
+
+void
+TileHash::clear(void)
+{
+    bzero(table, tableSize);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/spe/TileHash.h	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,30 @@
+#ifndef INCLUDED_TEXTURE_HASH
+#define INCLUDED_TEXTURE_HASH
+
+#ifndef INCLUDED_TAPESTRY
+#  include "Tapestry.h"
+#endif
+
+class TileHash {
+public:
+    TileHash(void);
+
+private:
+    TilePtr *table;
+    int hashSize;
+    int tableSize;
+
+public:
+    void clear(void);
+    int hash(uint32 data);
+    int put(uint32 *addr, TilePtr tile);
+    TilePtr get(uint32 *addr);
+    void remove(uint32 *addr);
+};
+
+typedef TileHash* TileHashPtr;
+
+#endif
+
+const int GLOBAL_TEXTURE_HASH = 0;
+const int GLOBAL_TILE_LIST    = 1;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/spe/spe-main.cpp	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,24 @@
+#include "../Func.h"
+#include "SchedTask.h"
+
+SchedExternTask(LoadTexture);
+SchedExternTask(SetTexture);
+SchedExternTask(DrawSpan);
+SchedExternTask(DrawSpanRenew);
+SchedExternTask(DrawBack);
+
+SchedExternTask(CreateSpan);
+//SchedExternTask(CreatePolygon);
+
+void
+task_init(void)
+{
+    SchedRegisterTask(TASK_INIT_TEXTURE, LoadTexture);
+    SchedRegisterTask(TASK_SET_TEXTURE, SetTexture);
+    SchedRegisterTask(TASK_DRAW_SPAN, DrawSpan);
+    SchedRegisterTask(TASK_DRAW_SPAN2, DrawSpanRenew);
+    SchedRegisterTask(TASK_DRAW_BACK, DrawBack);
+
+    SchedRegisterTask(TASK_CREATE_SPAN, CreateSpan);
+    //SchedRegisterTask(TASK_CREATE_PP, CreatePolygon);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/spe/texture.h	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,3 @@
+#define MAX_LOAD_SIZE 16384
+#define TEXTURE_ID 0
+#define TEXTURE2_ID 13
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/spe/viewer_types.cpp	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,30 @@
+#include "viewer_types.h"
+
+int
+getLocalPosition(int d, int offset)
+{
+    return d & (offset-1);
+}
+
+/**
+ * ワールド座標における x の値を
+ * split_screen_w で分割した領域(1 〜 split_screen_w)での座標に変換する
+ * (ex. split_screen_w が 256 の場合、
+ *      x =   1 -> 1
+ *      x = 256 -> 256
+ *      x = 257 -> 1
+ */
+int
+getLocalX(int x)
+{
+    return getLocalPosition(x, split_screen_w);
+}
+
+/**
+ * getLocalX に同じ
+ */
+int
+getLocalY(int y)
+{
+    return getLocalPosition(y, split_screen_h);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/sys.cpp	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,243 @@
+#include <stdlib.h>
+#include <iostream>
+#include <string.h>
+#include <math.h>
+#include "sys.h"
+using namespace std;
+
+void noMoreMemory()
+{
+  cout << "can't allocate memory\n";
+  exit(1);
+}
+
+void
+transMatrix(float *m0, float *m1, float *v)
+{
+    memcpy(m0, m1, sizeof(float)*16);
+
+    m0[12] = m1[12] + v[0];
+    m0[13] = m1[13] + v[1];
+    m0[14] = m1[14] + v[2];
+    m0[15] = m1[15] + v[3];
+}
+
+void
+unitMatrix(float *m)
+{
+    bzero(m, sizeof(float)*16);
+
+    m[0] = 1.0f;
+    m[5] = 1.0f;
+    m[10] = 1.0f;
+    m[15] = 1.0f;
+}
+
+void
+inversMatrix(float *m0, float *m1)
+{
+    float m[16];
+
+    for (int i = 0; i < 4; i++) {
+	for (int j = 0; j < 4; j++) {
+	    m[i*4+j] = m1[j*4+i];
+	}
+    }
+
+    m[12] = -(m1[12]*m[0] + m1[13]*m[1] + m1[14]*m[2]);
+    m[13] = -(m1[12]*m[4] + m1[13]*m[5] + m1[14]*m[6]);
+    m[14] = -(m1[12]*m[8] + m1[13]*m[9] + m1[14]*m[10]);
+    m[3] = m[7] = m[11] = 0.0f;
+    m[15] = 1.0f;
+
+    memcpy(m0, m, sizeof(float)*16);
+}
+
+/**
+ * マトリックス m にベクトル v1 を右から乗算して、v0に与える
+ * @param[out] v0 output vector (float[4])
+ * @param[in] v1 input vector (float[4])
+ * @param[in] m matrix (float[16])
+ */
+void
+applyMatrix(float *v0, float *m, float *v1)
+{
+    for (int i = 0; i < 4; i++) {
+	v0[i] = v1[0]*m[i] + v1[1]*m[i+4] + v1[2]*m[i+8] + v1[3]*m[i+12];
+    }
+}
+
+/**
+ * ベクトルの正規化
+ *
+ * @param[out] v0 output vector
+ * @param[in]  v1 input vector
+ */
+void
+normalize(float *v0, float *v1)
+{
+    float norm, dnorm;
+
+    norm = sqrt(v1[0]*v1[0] + v1[1]*v1[1] + v1[2]*v1[2]);
+    if (norm > 0) {
+	dnorm = 1.0/norm;
+	v0[0] = v1[0]*dnorm;
+	v0[1] = v1[1]*dnorm;
+	v0[2] = v1[2]*dnorm;
+	v0[3] = v1[3]*dnorm;
+    }
+}
+
+/**
+ * ベクトルの減算 v0 = v1 - v2
+ */
+void
+subVector(float *v0, float *v1, float *v2)
+{
+    v0[0] = v1[0] - v2[0];
+    v0[1] = v1[1] - v2[1];
+    v0[2] = v1[2] - v2[2];
+    v0[3] = v1[3] - v2[3];
+}
+
+/**
+ * ベクトルの外積 v0 = v1 x v2
+ */
+void
+outerProduct(float *v0, float *v1, float *v2)
+{
+    v0[0] = v1[1] * v2[2] - v1[2] * v2[1];
+    v0[1] = v1[2] * v2[0] - v1[0] * v2[2];
+    v0[2] = v1[0] * v2[1] - v1[1] * v2[0];
+    v0[3] = 0;
+}
+
+void
+transposeMatrix(float *m0, float *m1)
+{
+    float t[16];
+
+    for (int i = 0; i < 4; i++) {
+	for (int j = 0; j < 4; j++) {
+	    t[i*4+j] = m1[j*4+i];
+	}
+    }
+
+    memcpy(m0, t, sizeof(float)*16);
+}
+
+/**
+ * ベクトルの内積 f = v0 * v1
+ */
+float
+innerProduct(float *v0, float *v1)
+{
+    return (v0[0]*v1[0] + v0[1]*v1[1] + v0[2]*v1[2]);
+}
+
+void matrix4x4(float *xyz, float *xyz1, float *xyz2) //xyz[16]
+{
+  for(int t=0; t<16; t+=4)
+    {
+      for(int i=0; i<4; i++)
+	{
+	  xyz[t+i] = xyz1[t]*xyz2[i] + xyz1[t+1]*xyz2[4+i] + xyz1[t+2]*xyz2[8+i] + xyz1[t+3]*xyz2[12+i];
+	}
+    }
+}
+
+void get_matrix( float *matrix, float *rxyz, float *txyz, float *stack)
+{
+  float radx,rady,radz;
+  radx = rxyz[0]*3.14/180;
+  rady = rxyz[1]*3.14/180;
+  radz = rxyz[2]*3.14/180;
+
+  float sinx = sin(radx);
+  float cosx = cos(radx);
+  float siny = sin(rady);
+  float cosy = cos(rady);
+  float sinz = sin(radz);
+  float cosz = cos(radz);
+
+  /* View Transform */
+  matrix[0] = cosz*cosy+sinz*sinx*siny;
+  matrix[1] = sinz*cosx;
+  matrix[2] = -cosz*siny+sinz*sinx*cosy;
+  matrix[3] = 0;
+  matrix[4] = -sinz*cosy+cosz*sinx*siny;
+  matrix[5] = cosz*cosx;
+  matrix[6] = sinz*siny+cosz*sinx*cosy;
+  matrix[7] = 0;
+  matrix[8] = cosx*siny;
+  matrix[9] = -sinx;
+  matrix[10] = cosx*cosy;
+  matrix[11] = 0;
+  matrix[12] = txyz[0];
+  matrix[13] = txyz[1];
+  matrix[14] = txyz[2];
+  matrix[15] = 1;
+  
+  float m[16];
+
+  for(int i=0; i<16; i++)
+    {
+      m[i] = matrix[i];
+    }
+
+  if(stack)
+    {
+	matrix4x4(matrix, m, stack);
+    }
+
+}
+
+void rotate_x(float *xyz, float r)
+{
+  float rad = r*3.14/180;
+
+  xyz[0] = xyz[0];
+  xyz[1] = xyz[1]*cos(rad) - xyz[2]*sin(rad);
+  xyz[2] = xyz[1]*sin(rad) + xyz[2]*cos(rad);
+}
+
+void rotate_y(float *xyz, float r)
+{
+  float rad = r*3.14/180;
+
+  xyz[0] = xyz[0]*cos(rad) + xyz[2]*sin(rad);
+  xyz[1] = xyz[1];
+  xyz[2] = -xyz[0]*sin(rad) + xyz[2]*cos(rad);
+}
+
+void rotate_z(float *xyz, float r)
+{
+  float rad = r*3.14/180;
+
+  xyz[0] = xyz[0]*cos(rad) - xyz[1]*sin(rad);
+  xyz[1] = xyz[0]*sin(rad) + xyz[1]*cos(rad);
+  xyz[2] = xyz[2];
+}
+
+void rotate(float *xyz, float *matrix)
+{
+  float abc[4];
+  abc[0] = xyz[0];
+  abc[1] = xyz[1];
+  abc[2] = xyz[2];
+  abc[3] = xyz[3];
+
+  for(int i=0; i<4; i++)
+    {
+      //xyz[i] = abc[0]*rot[i] + abc[1]*rot[i+4] + abc[2]*rot[i+8] + abc[3]*rot[i+12];
+      xyz[i] = abc[0]*matrix[i] + abc[1]*matrix[i+4] + abc[2]*matrix[i+8] + abc[3]*matrix[i+12];
+    }
+}
+
+
+void translate(float *xyz, float x, float y, float z)
+{
+  xyz[0] += x;
+  xyz[1] += y;
+  xyz[2] += z;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/sys.h	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,19 @@
+void noMoreMemory();
+void get_matrix(float *matrix, float *rxyz, float *txyz, float *stack);
+void rotate_x(float *xyz, float r);
+void rotate_y(float *xyz, float r);
+void rotate_z(float *xyz, float r);
+//void rotate(float *xyz, float *matrix, float *rxyz, float *txyz, float *stack[]);
+void rotate(float *xyz, float *matrix);
+void translate(float *xyz, float x, float y, float z);
+void matrix4x4(float *, float *, float *);
+
+void normalize(float *v0, float *v1);
+void subVector(float *v0, float *v1, float *v2);
+void outerProduct(float *v0, float *v1, float *v2);
+float innerProduct(float *v0, float *v1);
+void applyMatrix(float *v0, float *m, float *v1);
+void inversMatrix(float *m0, float *m1);
+void transposeMatrix(float *m0, float *m1);
+void unitMatrix(float *m);
+void transMatrix(float *m0, float *m1, float *v);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/task/CreatePolygon.cpp	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,188 @@
+/**
+ * SceneGraph が増えてくると動かなくなるかもしれない。
+ * 一応 mainMem とかで動くようになるとは思うけど。
+ * だめだったら、そこら辺が怪しいと思うべき
+ */
+
+#include "CreatePolygon.h"
+#include "polygon_pack.h"
+#include "scene_graph_pack.h"
+
+SchedDefineTask(CreatePolygon);
+
+#define SG_PACK_LOAD 10
+#define SG_NODE_LOAD 11
+#define PP_LOAD 12
+#define PP_STORE 13
+
+/**
+ * あとで直す
+ */
+static void
+rotate(float *xyz, float *matrix)
+{
+    float abc[4];
+
+    abc[0] = xyz[0];
+    abc[1] = xyz[1];
+    abc[2] = xyz[2];
+    abc[3] = xyz[3];
+
+    for(int i=0; i<4; i++)
+    {
+	xyz[i] = abc[0]*matrix[i] + abc[1]*matrix[i+4] + abc[2]*matrix[i+8] + abc[3]*matrix[i+12];
+    }
+}
+
+int 
+CreatePolygon::run(void *rbuf, void *wbuf)
+{
+    float xyz1[4],xyz2[4],xyz3[4];
+
+    SceneGraphPackPtr sgp = (SceneGraphPack*)smanager->get_input(0);
+    SceneGraphPackPtr next_sgp = 
+	(SceneGraphPackPtr)smanager->allocate(sizeof(SceneGraphPack));
+    SceneGraphPackPtr free_sgp = next_sgp;
+    SceneGraphPackPtr tmp_sgp;
+
+    SceneGraphNodePtr node;
+    SceneGraphNodePtr next_node
+	= (SceneGraphNodePtr)smanager->allocate(sizeof(SceneGraphNode));
+    SceneGraphNodePtr free_node = next_node;
+    SceneGraphNodePtr tmp_node;
+
+    PolygonPackPtr pp
+	= (PolygonPackPtr)smanager->allocate(sizeof(PolygonPack));
+    PolygonPackPtr send_pp
+	= (PolygonPackPtr)smanager->allocate(sizeof(PolygonPack));
+    PolygonPackPtr pp_addr = (PolygonPackPtr)smanager->get_param(0);
+    PolygonPackPtr tmp_pp;
+    
+    pp->init();
+    send_pp->init();
+
+    do {
+	if (sgp->next != NULL) {
+	    smanager->dma_load(next_sgp, (uint32)sgp->next,
+			       sizeof(SceneGraphPack), SG_PACK_LOAD);
+	} else {
+	    next_sgp = NULL;
+	}
+
+	for (int i = 0; i < sgp->info.size; i++) {
+	    node = &sgp->node[i];
+
+	    do {
+		if (node->next != NULL) {
+		    smanager->dma_load(next_node, (uint32)node->next,
+				       sizeof(SceneGraphNode), SG_NODE_LOAD);
+		} else {
+		    next_node = NULL;
+		}
+    
+		for (int n = 0, nt = 0; n < node->size*3; n+=9, nt+=6) {
+
+		    if (pp->info.size >= MAX_SIZE_TRIANGLE) {
+			PolygonPackPtr next;
+
+			smanager->mainMem_alloc(0, sizeof(PolygonPack));
+			smanager->mainMem_wait();
+			next = (PolygonPackPtr)smanager->mainMem_get(0);
+
+			pp->next = next;
+
+			tmp_pp = pp;
+			pp = send_pp;
+			send_pp = tmp_pp;
+
+			smanager->dma_wait(PP_STORE);
+			smanager->dma_store(send_pp, (uint32)pp_addr,
+					    sizeof(PolygonPack), PP_STORE);
+			
+			pp_addr = next;
+
+			smanager->dma_wait(PP_LOAD);
+			smanager->dma_load(pp, (uint32)pp_addr,
+					   sizeof(PolygonPack), PP_LOAD);
+			smanager->dma_wait(PP_LOAD);
+			pp->init();
+
+		    }
+
+		    TrianglePack *triangle = &pp->tri[pp->info.size++];
+
+		    xyz1[0] = node->vertex[n];
+		    xyz1[1] = node->vertex[n+1];
+		    xyz1[2] = node->vertex[n+2]*-1;
+		    xyz1[3] = 1;
+		    xyz2[0] = node->vertex[n+3];
+		    xyz2[1] = node->vertex[n+3+1];
+		    xyz2[2] = node->vertex[n+3+2]*-1;
+		    xyz2[3] = 1;
+		    xyz3[0] = node->vertex[n+6];
+		    xyz3[1] = node->vertex[n+6+1];
+		    xyz3[2] = node->vertex[n+6+2]*-1;
+		    xyz3[3] = 1;
+		
+		    rotate(xyz1, node->translation);
+		    rotate(xyz2, node->translation);
+		    rotate(xyz3, node->translation);
+		
+		    triangle->ver1.x = xyz1[0];
+		    triangle->ver1.y = xyz1[1];
+		    triangle->ver1.z = xyz1[2];
+		    triangle->ver1.tex_x = node->texture[nt];
+		    triangle->ver1.tex_y = node->texture[nt+1];
+		
+		    triangle->ver2.x = xyz2[0];
+		    triangle->ver2.y = xyz2[1];
+		    triangle->ver2.z = xyz2[2];
+		    triangle->ver2.tex_x = node->texture[nt+2];
+		    triangle->ver2.tex_y = node->texture[nt+2+1];
+		
+		    triangle->ver3.x = xyz3[0];
+		    triangle->ver3.y = xyz3[1];
+		    triangle->ver3.z = xyz3[2];
+		    triangle->ver3.tex_x = node->texture[nt+4];
+		    triangle->ver3.tex_y = node->texture[nt+4+1];
+		
+#if 1
+		    triangle->tex_info.addr = node->tex_addr;
+		    triangle->tex_info.width = node->tex_width;
+		    triangle->tex_info.height = node->tex_height;
+#else
+		    triangle->tex_info.addr = node->texture_info.pixels;
+		    triangle->tex_info.width = node->texture_info.t_w;
+		    triangle->tex_info.height = node->texture_info.t_h;
+#endif
+		}
+
+		smanager->dma_wait(SG_NODE_LOAD);
+
+		tmp_node = node;
+		node = next_node;
+		next_node = tmp_node;
+	    } while (node);
+
+	    next_node = free_node;
+	}
+
+	smanager->dma_wait(SG_PACK_LOAD);
+
+	tmp_sgp = sgp;
+	sgp = next_sgp;
+	next_sgp = tmp_sgp;
+    } while (sgp);
+    
+    smanager->dma_wait(PP_STORE);
+    smanager->dma_store(pp, (uint32)pp_addr,
+			sizeof(PolygonPack), PP_STORE);
+    smanager->dma_wait(PP_STORE);
+
+    free(pp);
+    free(send_pp);
+    free(free_node);
+    free(free_sgp);
+
+    return 0;
+}    
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/task/CreatePolygon.h	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,15 @@
+#ifndef INCLUDED_CREATE_POLYGON
+#define INCLUDED_CREATE_POLYGON
+
+#ifndef INCLUDED_SCHED_TASK
+#  include "SchedTask.h"
+#endif
+
+class CreatePolygon : public SchedTask {
+public:
+    SchedConstructor(CreatePolygon);
+
+    int run(void *rbuf, void *wbuf);
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/task/CreatePolygonFromSceneGraph.cpp	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,189 @@
+/**
+ * SceneGraph が増えてくると動かなくなるかもしれない。
+ * 一応 mainMem とかで動くようになるとは思うけど。
+ * だめだったら、そこら辺が怪しいと思うべき
+ */
+
+#include "CreatePolygonFromSceneGraph.h"
+#include "polygon_pack.h"
+#include "scene_graph_pack.h"
+
+SchedDefineTask(CreatePolygonFromSceneGraph);
+
+#define SG_PACK_LOAD 10
+#define SG_NODE_LOAD 11
+#define PP_LOAD 12
+#define PP_STORE 13
+
+/**
+ *  ベクトルに行列を乗算する
+ * @param[out] v vector (float[4])
+ * @param[in] m matrix (float[16])
+ */
+static void
+ApplyMatrix(float *v, float *m)
+{
+    float t[4];
+
+    t[0] = v[0];
+    t[1] = v[1];
+    t[2] = v[2];
+    t[3] = v[3];
+
+    for (int i = 0; i < 4; i++) {
+	v[i] = t[0]*m[i] + t[1]*m[i+4] + t[2]*m[i+8] + t[3]*m[i+12];
+    }
+}
+
+/**
+ * 行列の積
+ *
+ * @param[out] m0 output matrix
+ * @param[in] m1 input left matrix
+ * @param[in] m2 input right matrix
+ */
+/*
+static void
+MulMatrix(float *m0, float *m1, float *m2) //xyz[16]
+{
+    for(int t = 0; t < 16; t += 4) {
+	for (int i = 0; i < 4; i++) {
+	    m0[t+i] =
+		m1[t+0]*m2[ i ] + m1[t+1]*m2[i+ 4] +
+		m1[t+2]*m2[i+8] + m1[t+3]*m2[i+12];
+	}
+    }
+}
+*/
+int 
+CreatePolygonFromSceneGraph::run(void *rbuf, void *wbuf)
+{
+    float xyz1[4], xyz2[4], xyz3[4];
+
+    SceneGraphPtr sg_top = (SceneGraphPtr)smanager->get_param(0);
+    SceneGraphPtr sg = sg_top;
+
+    PolygonPackPtr pp
+	= (PolygonPackPtr)smanager->allocate(sizeof(PolygonPack));
+    PolygonPackPtr send_pp
+	= (PolygonPackPtr)smanager->allocate(sizeof(PolygonPack));
+    PolygonPackPtr pp_addr = (PolygonPackPtr)smanager->get_param(1);
+    PolygonPackPtr tmp_pp;
+
+    pp->init();
+    send_pp->init();
+
+    while (sg) {
+	if (sg->flag_drawable) { // sg->isDrawable() とかの方がよくね?
+	    for (int i = 0; i < sg->size; i += 3) {
+		if (pp->info.size >= MAX_SIZE_TRIANGLE) {
+		    PolygonPackPtr next;
+	    
+		    smanager->mainMem_alloc(0, sizeof(PolygonPack));
+		    smanager->mainMem_wait();
+		    next = (PolygonPackPtr)smanager->mainMem_get(0);
+	    
+		    pp->next = next;
+	    
+		    tmp_pp = pp;
+		    pp = send_pp;
+		    send_pp = tmp_pp;
+	    
+		    smanager->dma_wait(PP_STORE);
+		    smanager->dma_store(send_pp, (uint32)pp_addr,
+					sizeof(PolygonPack), PP_STORE);
+	    
+		    pp_addr = next;
+	    
+		    smanager->dma_wait(PP_LOAD);
+		    smanager->dma_load(pp, (uint32)pp_addr,
+				       sizeof(PolygonPack), PP_LOAD);
+		    smanager->dma_wait(PP_LOAD);
+		    pp->init();
+		}
+
+		TrianglePack *triangle = &pp->tri[pp->info.size++];
+
+		xyz1[0] = sg->coord_xyz[(i+0)*3];
+		xyz1[1] = sg->coord_xyz[(i+0)*3+1];
+		xyz1[2] = sg->coord_xyz[(i+0)*3+2]*-1.0f;
+		xyz1[3] = 1.0f;
+
+		xyz2[0] = sg->coord_xyz[(i+1)*3];
+		xyz2[1] = sg->coord_xyz[(i+1)*3+1];
+		xyz2[2] = sg->coord_xyz[(i+1)*3+2]*-1.0f;
+		xyz2[3] = 1.0f;
+
+		xyz3[0] = sg->coord_xyz[(i+2)*3];
+		xyz3[1] = sg->coord_xyz[(i+2)*3+1];
+		xyz3[2] = sg->coord_xyz[(i+2)*3+2]*-1.0f;
+		xyz3[3] = 1.0f;
+
+		// sg->matrix = 回転行列*透視変換行列
+		ApplyMatrix(xyz1, sg->matrix);
+		ApplyMatrix(xyz2, sg->matrix);
+		ApplyMatrix(xyz3, sg->matrix);
+
+		xyz1[0] /= xyz1[2];
+		xyz1[1] /= xyz1[2];
+		xyz2[0] /= xyz2[2];
+		xyz2[1] /= xyz2[2];
+		xyz3[0] /= xyz3[2];
+		xyz3[1] /= xyz3[2];
+
+		triangle->ver1.x = xyz1[0];
+		triangle->ver1.y = xyz1[1];
+		triangle->ver1.z = xyz1[2];
+		triangle->ver1.tex_x = sg->coord_tex[(i+0)*3];
+		triangle->ver1.tex_y = sg->coord_tex[(i+0)*3+1];
+		
+		triangle->ver2.x = xyz2[0];
+		triangle->ver2.y = xyz2[1];
+		triangle->ver2.z = xyz2[2];
+		triangle->ver2.tex_x = sg->coord_tex[(i+1)*3];
+		triangle->ver2.tex_y = sg->coord_tex[(i+1)*3+1];
+		
+		triangle->ver3.x = xyz3[0];
+		triangle->ver3.y = xyz3[1];
+		triangle->ver3.z = xyz3[2];
+		triangle->ver3.tex_x = sg->coord_tex[(i+2)*3];
+		triangle->ver3.tex_y = sg->coord_tex[(i+2)*3+1];
+	
+		triangle->tex_info.addr   = sg->texture_info.pixels;
+		triangle->tex_info.width  = sg->texture_info.t_w;
+		triangle->tex_info.height = sg->texture_info.t_h;
+		triangle->tex_info.scale_max = sg->texture_info.scale_max;
+	    }
+	}
+
+	if (sg->children != NULL) {
+	    sg = sg->children;
+	} else if (sg->brother != NULL) {
+	    sg = sg->brother;
+	} else {
+	    while (sg) {
+		if (sg->brother != NULL) {
+		    sg = sg->brother;
+		    break;
+		} else {
+		    if (sg->parent == NULL) {
+			sg = NULL;
+			break;
+		    } else {
+			sg = sg->parent;
+		    }
+		}
+	    }
+	}
+    }
+    
+    smanager->dma_wait(PP_STORE);
+    smanager->dma_store(pp, (uint32)pp_addr,
+			sizeof(PolygonPack), PP_STORE);
+    smanager->dma_wait(PP_STORE);
+
+    free(pp);
+    free(send_pp);
+
+    return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/task/CreatePolygonFromSceneGraph.h	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,15 @@
+#ifndef INCLUDED_CREATE_POLYGON
+#define INCLUDED_CREATE_POLYGON
+
+#ifndef INCLUDED_SCHED_TASK
+#  include "SchedTask.h"
+#endif
+
+class CreatePolygonFromSceneGraph : public SchedTask {
+public:
+    SchedConstructor(CreatePolygonFromSceneGraph);
+
+    int run(void *rbuf, void *wbuf);
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/task/CreateSpan.cpp	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,494 @@
+#include "CreateSpan.h"
+#include "viewer_types.h"
+
+static const int SPAN_PACK_LOAD    =  5;
+static const int SPAN_PACK_STORE   =  6;
+static const int POLYGON_PACK_LOAD =  7;
+static const int TILE_ALLOCATE     =  8;
+static const int TILE_LOAD         =  9;
+static const int TILE_STORE        = 10;
+
+static SpanPackPtr spack = NULL;
+static SpanPackPtr send_spack = NULL;
+static int prev_index = 0;
+
+SchedDefineTask(CreateSpan);
+
+static float
+calc(float f1, float f2,int i, float base)
+{
+    float ans;
+    ans = f1/f2*i + base;
+    return ans;
+}
+
+
+/**
+ * TrianglePack から、vMin, vMid, vMax を求める
+ *
+ * @param [triPack] TrianglePack
+ * @param [vMin] [vMid] [vMax]
+ */
+static void
+make_vertex(TrianglePack *triPack,
+	    VertexPackPtr *vMin, VertexPackPtr *vMid, VertexPackPtr *vMax)
+{
+    if (triPack->ver1.y <= triPack->ver2.y) {
+	if (triPack->ver2.y <= triPack->ver3.y) {
+	    *vMin = &triPack->ver1;
+	    *vMid = &triPack->ver2;
+	    *vMax = &triPack->ver3;
+	} else if (triPack->ver3.y <= triPack->ver1.y) {
+	    *vMin = &triPack->ver3;
+	    *vMid = &triPack->ver1;
+	    *vMax = &triPack->ver2;
+	} else {
+	    *vMin = &triPack->ver1;
+	    *vMid = &triPack->ver3;
+	    *vMax = &triPack->ver2;
+	}
+    } else {
+	if (triPack->ver1.y <= triPack->ver3.y) {
+	    *vMin = &triPack->ver2;
+	    *vMid = &triPack->ver1;
+	    *vMax = &triPack->ver3;
+	} else if (triPack->ver3.y <= triPack->ver2.y) {
+	    *vMin = &triPack->ver3;
+	    *vMid = &triPack->ver2;
+	    *vMax = &triPack->ver1;
+	} else {
+	    *vMin = &triPack->ver2;
+	    *vMid = &triPack->ver3;
+	    *vMax = &triPack->ver1;
+	}
+    }
+}
+
+static void
+make_vMid10(VertexPack *v, VertexPack *vMin,
+	    VertexPack *vMid, VertexPack *vMax)
+{
+    //int d, d1;
+    float d;
+    int d1;
+    
+    d  = vMax->y - vMin->y;
+    d1 = (int)(vMid->y - vMin->y);
+
+    v->tex_x  = calc(vMax->tex_x - vMin->tex_x, d, d1, vMin->tex_x);
+    v->tex_y  = calc(vMax->tex_y - vMin->tex_y, d, d1, vMin->tex_y);
+    v->x      = calc(vMax->x - vMin->x, d, d1, vMin->x);
+    v->y      = vMid->y;
+    v->z      = calc(vMax->z - vMin->z, d, d1, vMin->z);
+}
+
+/**
+ * 与えられた scale から、実際に使うテクスチャの Tapestry を選択する
+ *
+ * テクスチャは、オリジナルのサイズから、可能なかぎり 1/2 で縮小していき、
+ * 下の図の様に連続した領域に入れられる
+ *
+ *   Tapestry (1)
+ * +---+---+---+---+
+ * | 0 | 1 | 2 | 3 |
+ * +---+---+---+---+
+ * | 4 | 5 | 6 | 7 |     (2)
+ * +---+---+---+---+  +---+---+
+ * | 8 | 9 | 10| 11|  | 16| 17|   (3)
+ * +---+---+---+---+  +---+---+  +---+
+ * | 12| 13| 14| 15|  | 18| 19|  | 20|
+ * +---+---+---+---+  +---+---+  +---|
+ *
+ * (1)                                                 (2)             (3)
+ *  +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
+ *  | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * | * | * | 14| 15| 16| 17| 18| 19| 20|
+ *  +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
+ *
+ * scale の値から、各 Tapestry の先頭アドレスを返す
+ *
+ * @param[in] tw       Width of texture
+ * @param[in] th       Height of texture
+ * @param[in] scale    テクスチャの縮小率 (= 2^n)
+ * @param[in] addr_top テクスチャの先頭アドレス (上の図での (1)
+ * @return scale に対応する Tapestry のアドレス (上の図での (1) or (2) or(3)
+ */
+static uint32*
+getTapestry(int tw, int th, int scale, uint32 *addr_top)
+{
+    int index = 0;
+
+    for (int s = 1; s < scale; s <<= 1) {
+	index += tw*th;
+	tw >>= 1; /* tw /= 2 */
+	th >>= 1;
+    }
+
+    return addr_top + index;
+}
+
+
+/**
+ * span の width,height と texture の width,height を比べて
+ * span を描画する際に使う texture の比率を求める
+ *
+ * @param[in] width      Width of span
+ * @param[in] height     Height of span
+ * @param[in] tex_width  Width of 1/1 texture that span use
+ * @param[in] tex_height Height of 1/1 texture that span use
+ * @param[in] scale_max  この Span で使う texture の最大縮小率
+ *                   計算結果が scale_max 以上になるのを防ぐ
+ * @return 描画に使う texture の比率
+ *         width と height は 1/scale の画像を使う
+ *
+ */
+static int
+getScale(int width, int height, int tex_width, int tex_height, int scale_max)
+{
+    int base, tex_base;
+    int scale = 1;
+
+    /**
+     * width と height で、長い方を基準に、
+     * texture の scale を決める
+     */
+    if (width > height) {
+	base = width;
+	tex_base = tex_width;
+    } else {
+	base = height;
+	tex_base = tex_height;
+    }
+
+    if (tex_base > base) {
+	int t_scale = tex_base/base;
+	while (t_scale >>= 1) {
+	    scale <<= 1;
+	}
+    }
+
+    return (scale > scale_max) ? scale_max : scale;
+    //return scale_max;
+}
+
+/**
+ * x軸に水平な辺を持つ三角形ポリゴンから、
+ * Span を抜き出す
+ *
+ * @param[in] spackList    triangle から生成された span を格納する List
+ * @param[in] charge_y_top 担当する y の範囲開始地点
+ * @param[in] charge_y_end 担当する y の範囲終了地点
+ * @param[in] tex_addr     triangle が参照するテクスチャの先頭アドレス
+ * @param[in] tex_width    テクスチャの width
+ * @param[in] tex_height   テクスチャの height
+ * @param[in] tex_scale_max  テクスチャの最大縮小率 (2^n)
+ * @param[in] vMin     triangle の座標
+ * @param[in] vMid     triangle の座標。triangle を二つに分けて出来た新しい座標
+ * @param[in] vMid10   triangle の座標
+ * @param[in] length_y  分割する前の Triangle の y の長さ
+ * @param[in] tex_y_len 分割する前の Triangle に貼られている Texture の
+ *                      長さの割合 (0 ... 1)
+ */
+void
+CreateSpan::half_triangle(SpanPackPtr *spackList,
+			  int charge_y_top, int charge_y_end,
+			  TriangleTexInfoPtr tex_info,
+			  VertexPack *vMin,VertexPack *vMid,VertexPack *vMid10,
+			  int length_y, float tex_y_len)
+{
+    float tmp_z,tmp_tex1, tmp_tex2 ,tmp_tey1,tmp_tey2;
+    float tmp_xpos,tmp_end,tmp_zpos;
+    float start_z, end_z;
+    float start_tex_x, end_tex_x, start_tex_y, end_tex_y;
+    int x, y, length;
+
+#if 1
+    // これじゃないと
+    // テクスチャの貼りに微妙に隙間が。謎だ
+    int start_y = (int)vMid->y;
+    int end_y   = (int)vMin->y;
+#else
+    float start_y = vMid->y;
+    float end_y   = vMin->y;
+#endif
+    float div_y = start_y - end_y;
+    int k = 0;
+    int l = 1;
+
+    SpanPackPtr tmp_spack;
+
+    /**
+     * 三角形ポリゴンをx軸に水平に二つに分けようとして
+     * ある一辺がすでに水平だった場合、つまり
+     *
+     * |\
+     * | \
+     * |  \
+     * -----
+     *
+     *
+     * 上のようなポリゴンだった場合は、本来なら上の部分の三角形にだけ
+     * half_triangle の処理をするべきだが、現在の処理だと
+     * この half_triangle に「上の部分の三角形」と、
+     * 「『下の部分の三角形と判断してしまった』直線」が来てしまう。
+     * 直線の部分が来ると、calc() で 0 除算とかで、値不定で暴走するので
+     * 現在はこれで代用。
+     * half_triangle 呼ぶ前にこれを判断できれば良いかもしれない。
+     * てかこんなんでいいのかよ。。。
+     */
+#if 1
+    if ((int)div_y == 0) {
+	return;
+    }
+#else
+    if (vMid10->x == vMin->x && vMid10->y == vMin->y) {
+	return;
+    }
+#endif
+
+    if (div_y < 0) {
+	div_y = -div_y;
+	k = 1;
+	l = -1;
+    }
+
+    for (int i = k; i < (int)div_y+1; i++) {
+	y = (int)vMin->y + i*l;
+#if 1
+
+	/**
+	 * 担当 y 範囲内
+	 */
+	if (charge_y_top <= y && y <= charge_y_end) {
+	    // 1..8 を index0, 9..16 を index1 にするために y を -1
+	    int index = (y-1) / split_screen_h;
+
+	    /**
+	     * 違う SpanPack を扱う場合、
+	     * 現在の SpanPack をメインメモリに送り、
+	     * 新しい SpanPack を取ってくる
+	     */
+	    if (index != prev_index) {
+		tmp_spack = spack;
+		spack = send_spack;
+		send_spack = tmp_spack;
+
+		smanager->dma_wait(SPAN_PACK_STORE);
+		smanager->dma_store(send_spack, (uint32)spackList[prev_index],
+				    sizeof(SpanPack), SPAN_PACK_STORE);
+		
+		smanager->dma_load(spack, (uint32)spackList[index],
+				   sizeof(SpanPack), SPAN_PACK_LOAD);
+		prev_index = index;
+		smanager->dma_wait(SPAN_PACK_LOAD);
+	    }
+
+	    /**
+	     * 書き込む SpanPack が満杯だったら
+	     * メインメモリで allocate した領域 (next) を持ってきて
+	     * 現在の spack->next につなぎ、next を次の spack とする。
+	     */
+	    if (spack->info.size >= MAX_SIZE_SPAN) {
+		SpanPackPtr next;
+		
+		smanager->mainMem_alloc(0, sizeof(SpanPack));
+		smanager->mainMem_wait();
+		next = (SpanPackPtr)smanager->mainMem_get(0);
+		
+		spack->next = next;
+
+		tmp_spack = spack;
+		spack = send_spack;
+		send_spack = tmp_spack;
+
+		smanager->dma_wait(SPAN_PACK_STORE);
+		smanager->dma_store(send_spack, (uint32)spackList[index],
+				    sizeof(SpanPack), SPAN_PACK_STORE);
+
+		spackList[index] = next;
+		
+		smanager->dma_load(spack, (uint32)spackList[index],
+				   sizeof(SpanPack), SPAN_PACK_LOAD);
+		smanager->dma_wait(SPAN_PACK_LOAD);
+		spack->init((index+1)*split_screen_h);
+	    }
+	} else {
+	    /**
+	     * 担当範囲外だったら無視
+	     */
+	    continue;
+	}
+	
+	tmp_xpos = calc(vMid10->x - vMin->x ,div_y, i, vMin->x);
+	tmp_end  = calc(vMid->x  - vMin->x ,div_y, i, vMin->x);
+	tmp_z    = calc(vMid10->z - vMin->z ,div_y, i, vMin->z);
+	tmp_zpos = calc(vMid->z  - vMin->z ,div_y, i, vMin->z);
+
+	length = (tmp_xpos > tmp_end)
+	    ? (int)tmp_xpos - (int)tmp_end : (int)tmp_end - (int)tmp_xpos;
+	if (length == 0) {
+	    continue;
+	}
+
+	tmp_tex1 =((i/(div_y)) * vMid10->tex_x) +
+	    ( ((div_y - i)/(div_y)) * vMin->tex_x);
+	tmp_tex2 =( (i/(div_y)) * vMid->tex_x) +
+	    ( ((div_y - i)/(div_y)) * vMin->tex_x);
+
+	tmp_tey1 =( (i/(div_y)) * vMid10->tex_y) +
+	    ( ((div_y - i)/(div_y)) * vMin->tex_y);
+	tmp_tey2 =( (i/(div_y)) * vMid->tex_y) +
+	    ( ((div_y - i)/(div_y)) * vMin->tex_y);
+
+	if (tmp_xpos > tmp_end) {
+	    x = (int)tmp_end;
+	    length = (int)(tmp_xpos)-(int)(tmp_end)+1;
+	    start_z = tmp_zpos;
+	    end_z = tmp_z;
+	    start_tex_x = tmp_tex2;
+	    end_tex_x = tmp_tex1;
+	    start_tex_y = tmp_tey2;
+	    end_tex_y = tmp_tey1;
+	} else {
+	    x = (int)tmp_xpos;
+	    length = (int)(tmp_end)-(int)(tmp_xpos)+1;
+	    start_z = tmp_z;
+	    end_z = tmp_zpos;
+	    start_tex_x = tmp_tex1;
+	    end_tex_x = tmp_tex2;
+	    start_tex_y = tmp_tey1;
+	    end_tex_y = tmp_tey2;
+	}
+
+	smanager->dma_wait(SPAN_PACK_LOAD);
+
+	Span *span = &spack->span[spack->info.size++];
+
+	span->x          = x;
+	span->y          = y;
+	span->length_x   = length;
+	span->start_z    = start_z;
+	span->end_z      = end_z;
+	span->tex_x1     = start_tex_x;
+	span->tex_x2     = end_tex_x;
+	span->tex_y1     = start_tex_y;
+	span->tex_y2     = end_tex_y;
+
+
+	float tex_x_len = span->tex_x2 - span->tex_x1;
+
+	/**
+	 * tex_x_len, tex_y_len を掛ける理由は
+	 * Changelog の 2008-12-16 を参照
+	 */
+	int scale = getScale(span->length_x, length_y,
+			     (int)(span->tex_width*tex_x_len),
+			     (int)(span->tex_height*tex_y_len),
+			     tex_info->scale_max);
+	//scale = tex_info->scale_max;
+	
+	uint32 *tapestry = getTapestry(tex_info->width,
+				       tex_info->height, scale,
+				       tex_info->addr);
+	span->tex_addr   = tapestry;
+	span->tex_width  = tex_info->width/scale;
+	span->tex_height = tex_info->height/scale;
+    }
+#else
+    
+    /**
+     * ここに SIMD 化した記述をしようとして断念
+     */
+
+#endif
+
+}
+
+
+int
+CreateSpan::run(void *rbuf, void *wbuf)
+{
+    PolygonPack *pp = (PolygonPack*)smanager->get_input(0);
+    PolygonPack *next_pp = 
+	(PolygonPack*)smanager->allocate(sizeof(PolygonPack));
+    PolygonPack *free_pp = next_pp;
+    PolygonPack *tmp_pp;
+
+    TrianglePackPtr triPack;
+    VertexPackPtr vMin, vMid, vMax;
+    VertexPackPtr vMid10
+	= (VertexPackPtr)smanager->allocate(sizeof(VertexPack));
+    
+    SpanPackPtr *spackList = (SpanPackPtr*)smanager->get_input(1);
+    spack = (SpanPackPtr)smanager->get_input(2);
+    send_spack = (SpanPackPtr)smanager->allocate(sizeof(SpanPack));
+    prev_index = get_param(0);
+
+    // spack と send_spack は swap しながら DMA を繰り返すので
+    // 自分で allocate した send_spack を覚えてないといけない
+    SpanPackPtr free_spack = send_spack;
+
+    int charge_y_top = get_param(1);
+    int charge_y_end = get_param(2);
+
+    do {
+	if (pp->next != NULL) {
+	    smanager->dma_load(next_pp, (uint32)pp->next,
+			       sizeof(PolygonPack), POLYGON_PACK_LOAD);
+	} else {
+	    next_pp = NULL;
+	}
+
+	for (int i = 0; i < pp->info.size; i++) {
+	    triPack = &pp->tri[i];
+
+	    TriangleTexInfoPtr tri_tex_info = &triPack->tex_info;
+
+	    make_vertex(triPack, &vMin, &vMid, &vMax);
+	    make_vMid10(vMid10, vMin, vMid, vMax);
+
+	    /**
+	     * ポリゴンを、x軸に水平に分割して二つの三角形を作り、
+	     * それぞれから Span を求める
+	     *
+	     *      vMax
+	     *        |\
+	     *        | \
+	     *        |  \
+	     *        |   \
+	     * vMid10 ------ vMid
+	     *        |   /
+	     *        |  /
+	     *        | /
+	     *        |/
+	     *      vMin
+	     *
+	     * (vMax, vMid, vMin) という triangle を
+	     * (vMax, vMid, vMid10) (vMin, vMid, vMid10) という
+	     * 二つの Triangle に分けている
+	     */
+	    half_triangle(spackList, charge_y_top, charge_y_end,
+			  tri_tex_info, vMin, vMid, vMid10,
+			  (int)(vMax->y - vMin->y), vMax->tex_y - vMin->tex_y);
+	    half_triangle(spackList, charge_y_top, charge_y_end,
+			  tri_tex_info, vMax, vMid, vMid10,
+			  (int)(vMax->y - vMin->y), vMax->tex_y - vMin->tex_y);
+	}
+
+	smanager->dma_wait(POLYGON_PACK_LOAD);	
+
+	tmp_pp = pp;
+	pp = next_pp;
+	next_pp = tmp_pp;
+    } while (pp);
+
+    smanager->dma_wait(SPAN_PACK_STORE);
+    smanager->dma_store(spack, (uint32)spackList[prev_index],
+			sizeof(SpanPack), SPAN_PACK_STORE);
+    smanager->dma_wait(SPAN_PACK_STORE);
+
+    free(free_pp);
+    free(free_spack);
+    free(vMid10);
+
+    return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/task/CreateSpan.h	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,28 @@
+#ifndef INCLUDED_CREATE_SPAN
+#define INCLUDED_CREATE_SPAN
+
+#ifndef INCLUDED_SCHED_TASK
+#  include "SchedTask.h"
+#endif
+
+#ifndef INCLUDED_POLYGON_PACK
+#  include "polygon_pack.h"
+#endif
+
+#ifndef INCLUDED_SPAN_PACK
+#  include "SpanPack.h"
+#endif
+
+class CreateSpan : public SchedTask {
+public:
+    SchedConstructor(CreateSpan);
+    
+    int run(void *rbuf, void *wbuf);
+    void half_triangle(SpanPackPtr *spackList,
+		       int charge_y_top, int charge_y_end,
+		       TriangleTexInfoPtr tex_info,
+		       VertexPack *vMin,VertexPack *vMid,VertexPack *vMid1,
+		       int length_y, float tex_y_len);
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/task/DrawBack.cpp	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,32 @@
+#include <stdlib.h>
+#include <string.h>
+#include "DrawBack.h"
+#include "viewer_types.h"
+
+SchedDefineTask(DrawBack);
+
+void
+DrawBack::linebuf_init(int *buf, int x, int rgb)
+{
+    for (int i = 0; i < x; i++) {
+	buf[i] = rgb;
+    }
+}
+
+int
+DrawBack::run(void *rbuf, void *wbuf)
+{
+    int rgb          = smanager->get_param(0);
+    int rangex_start = smanager->get_param(1);
+    int rangex_end   = smanager->get_param(2);
+    int rangey       = smanager->get_param(3);
+    int rangex       = rangex_end - rangex_start + 1;
+    int *linebuf;
+
+    for (int i = 0; i < rangey; i++) {
+	linebuf = (int*)smanager->get_output(i);
+	linebuf_init(linebuf, rangex, rgb);
+    }
+
+    return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/task/DrawBack.h	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,17 @@
+#ifndef INCLUDED_TASK_DRAW_BACK
+#define INCLUDED_TASK_DRAW_BACK
+
+#ifndef INCLUDED_SCHED_TASK
+#  include "SchedTask.h"
+#endif
+
+class DrawBack : public SchedTask {
+public:
+    SchedConstructor(DrawBack);
+
+    int run(void *rbuf, void *wbuf);
+
+    void linebuf_init(int *buf, int width, int rgb);
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/test_render/task/DrawSpan.cpp	Fri Jun 05 16:49:12 2009 +0900
@@ -0,0 +1,640 @@
+#include <stdlib.h>
+#include <string.h>
+#include "DrawSpan.h"
+#include "polygon_pack.h"
+#include "texture.h"
+#include "viewer_types.h"
+#include "Func.h"
+
+SchedDefineTask(DrawSpan);
+
+#define TEX_LOAD1      0
+#define TEX_LOAD2      1
+#define SPAN_PACK_LOAD 2
+#define FB_STORE       3
+
+DrawSpan::~DrawSpan(void)
+{
+    smanager->dma_wait(FB_STORE);
+    free((void*)((int)linebuf*doneWrite));
+}
+
+/**
+ * テクスチャは、TEXTURE_SPLIT_PIXEL^2 のブロックに分割する
+ *
+ * +---+---+---+---+---+---+
+ * | 0 | 1 | 2 | 3 | 4 | 5 |
+ * +---+---+---+---+---+---+
+ * |   |   |   |   |   |11 |
+ * +---+---+---+---+---+---+
+ * |   |   |   |   |   |17 |
+ * +---+---+---+---+---+---+
+ * |   |   |   |   |   |23 |
+ * +---+---+---+---+---+---+
+ * |   |   |   |   |   |29 |
+ * +---+---+---+---+---+---+
+ * |   |   |   |   |   |35 |
+ * +---+---+---+---+---+---+
+ *
+ * 一辺を TEXTURE_SPLIT とする
+ * 各ブロックの数字がブロックIDとなる。
+ */
+
+/**
+ * テクスチャの座標から、
+ * テクスチャのどのブロックかを求める
+ *
+ * @param[in] tx X coordinates of texture
+ * @param[in] tx Y coordinates of texture
+ * @param[in] twidth  Width of texture
+ * @return block ID
+ */
+int
+DrawSpan::getTexBlock(int tx, int ty, int twidth)
+{
+     int blockX, blockY;
+
+     blockX = tx / TEXTURE_SPLIT_PIXEL;
+     blockY = ty / TEXTURE_SPLIT_PIXEL;
+
+     return blockX + (twidth/TEXTURE_SPLIT_PIXEL)*blockY;
+}
+
+/**
+ * block ID と、テクスチャの TOP address から
+ * (tx,ty) で使われるテクスチャの Tile addres を求める
+ *
+ * @param[in] tx X coordinates of texture
+ * @param[in] tx Y coordinates of texture
+ * @param[in] tw Width of texture
+ * @param[in] tex_addr_top (tx,ty) で使うテクスチャの先頭address
+ * @return block ID
+ */
+uint32*
+DrawSpan::getTile(int tx, int ty, int tw, uint32 *tex_addr_top)
+{
+    int block = getTexBlock(tx, ty, tw);
+    return tex_addr_top + block*TEXTURE_BLOCK_SIZE;
+}
+
+/**
+ * FrameBuffer に書き込む rgb の領域初期化
+ *
+ * @param width  Width of Buffer
+ * @param height Height of Buffer
+ * @param rgb    Initial value of RGB at Buffer
+ * @return Buffer
+ */
+int*
+DrawSpan::linebuf_init(int width, int height, int rgb)
+{
+    int *buf = (int*)smanager->allocate(sizeof(int)*width*height);
+
+    for (int i = 0; i < width*height; i++) {
+	buf[i] = rgb;
+    }
+
+    return buf;
+}
+
+/**
+ * Z-Buffer の初期化
+ *
+ * @param width  Width of Z-Buffer
+ * @param height Height of Z-Buffer
+ * @return Z-Buffer
+ */
+float*
+DrawSpan::zRow_init(int width, int height)
+{
+    float *buf = (float*)smanager->allocate(sizeof(float)*width*height);
+    float def = 65535.0f;
+
+    for (int i = 0; i < width*height; i++) {
+	buf[i] = def;
+    }
+
+    return buf;
+}
+
+
+/**
+ * Span が使う Texture Tile があるか
+ *
+ * @retval != NULL 存在する
+ * @retval NULL    存在しない
+ */
+TilePtr
+DrawSpan::isAvailableTile(uint32 *addr)
+{
+    return hash->get(addr);
+}
+
+void
+DrawSpan::set_rgb(uint32 *addr, int tag)
+{
+    TilePtr tile;
+
+    if (isAvailableTile(addr)) {
+	return;
+    }
+
+    tile = tileList->nextTile();
+    /**
+     * FIFO なので、もし前のが残っていれば削除
+     */
+    hash->remove(tile->texture_addr);
+    
+    tile->texture_addr = addr;
+    
+    hash->put(tile->texture_addr, tile);
+    smanager->dma_load(tile->pixel, (uint32)addr,
+		       sizeof(uint32)*TEXTURE_BLOCK_SIZE, tag);
+}
+
+/**
+ * 
+ */
+void
+DrawSpan::set_rgbs(uint32 *cur_addr, uint32 *max_addr, int wait_tag)
+{
+    uint32 curp   = (uint32)cur_addr;
+    uint32 maxp   = (uint32)max_addr;
+    uint32 startp = curp;
+    uint32 diff   = sizeof(int)*TEXTURE_BLOCK_SIZE;
+    int length = (int)maxp-(int)curp;
+
+    int cmp = (length < 0);
+
+#if 1
+    length += cmp*(-1)*length*2;
+    startp = cmp*maxp + !cmp*curp;
+#else
+    if (length < 0) {
+	length = -length;
+	startp = maxp;
+    }
+#endif
+
+    for (int i = 0; i <= length; i += diff) {
+	set_rgb((uint32*)(startp + i), wait_tag);
+    }
+}
+
+uint32
+DrawSpan::get_rgb(int tx, int ty, uint32 *addr)
+{
+    TilePtr tile;
+
+    tile = hash->get(addr);
+    return tile->pixel[(TEXTURE_SPLIT_PIXEL)*ty+tx];
+}
+
+/**
+ * DrawSpan の再起動 (DrawSpanRenew 生成)
+ *
+ * @param[in] spack 現在処理している SpanPack
+ * @param[in] cur_span_x span->length_x != 1 の時の Span の処理で
+ *                       どこまで進んでいるか
+ */
+void
+DrawSpan::reboot(SpanPackPtr spack, int cur_span_x)
+{
+    DrawSpanArgPtr args =
+	(DrawSpanArgPtr)smanager->allocate(sizeof(DrawSpanArg));
+    TaskPtr renew_task = smanager->create_task(TASK_DRAW_SPAN2);
+
+    // 数が多いので構造体で渡す
+    args->display      = smanager->get_param(0);
+    args->screen_width = smanager->get_param(1);
+    args->rangex_start = smanager->get_param(2);
+    args->rangex_end   = smanager->get_param(3);
+    args->rangey       = smanager->get_param(4);
+    renew_task->add_param((int)args);
+
+    /**
+     * SpanPack は続きから開始するので、
+     * 現在の状態をコピーしておく。
+     * spack は rbuf から取得してる可能性があり
+     * rbuf はシステムが自動的に free() するため
+     * アドレスだけ渡すのはNG
+     */ 
+    SpanPackPtr curr = (SpanPackPtr)smanager->allocate(sizeof(SpanPack));
+    memcpy(curr, spack, sizeof(SpanPack));
+    renew_task->add_param((int)curr);
+    renew_task->add_param(cur_span_x);
+
+    // linebuf と zRow も引き継がせる
+    renew_task->add_param((int)linebuf);
+    renew_task->add_param((int)zRow);
+
+    /**
+     * 再起動したタスクを待つ
+     */ 
+    smanager->wait_task(renew_task);
+
+    // next_spack は free() するので wait する
+    smanager->dma_wait(SPAN_PACK_LOAD);
+}
+
+void
+DrawSpan::writebuffer(unsigned int display, int buf_width, int height,
+		      int screen_width)
+{
+    for (int i = 0; i < height; i++) {
+	smanager->dma_store(&linebuf[i*buf_width],
+			    display + (sizeof(int)*screen_width*i),
+			    sizeof(int)*buf_width, FB_STORE);
+    }
+
+    doneWrite = 1;
+}
+
+/**
+ * zRow と Linebuf を更新する
+ *
+ * @param zpos     更新する pixel のZ座標
+ * @param rangex   このタスクが処理する描画領域の x の長さ
+ * @param x        pixel の、描画領域内での x 座標
+ * @param y        〃 の、y 座標
+ * @param tex_x    pixel が使用するテクスチャの、Tile (8x8) 内での x 座標
+ * @param tex_y    〃 の y 座標
+ * @param tex_addr テクスチャのアドレス(MainMemory)
+ */
+void
+DrawSpan::updateBuffer(float zpos, int rangex, int x, int y,
+		       int tex_x, int tex_y, uint32 *tex_addr)
+{
+
+
+    int rgb = get_rgb(tex_x, tex_y, tex_addr);
+    /*下位4bitを抽出*/
+    int alpha = rgb & 0x000F;
+    /*完全に透けているか判断*/
+    int flag = (alpha != 0);
+
+    zRow[x + (rangex*y)] = zpos*flag + zRow[x + (rangex*y)]*(1-flag);
+    linebuf[x + (rangex*y)] = rgb*flag + linebuf[x + (rangex*y)]*(1-flag);
+
+}
+
+/**
+ * 長さが 1 の Span の描画 (要するに 1 pixel)
+ *
+ * @param span Span
+ * @param startx 描画開始範囲
+ * @param endx 描画終了範囲
+ */
+int
+DrawSpan::drawDot1(SpanPtr span, int startx, int endx, int wait_tag)
+{
+    int rangex = endx - startx + 1;
+
+    /* span->x に対応する Texture の座標 (tex_xpos, tex_ypos) */
+    int tex_xpos, tex_ypos;
+
+    // span の始点に対応する Texture の座標 (tex1, tey1)
+    float tex = span->tex_x1;
+    float tey = span->tex_y1;
+
+    // span の始点に対応する z 座標
+    float zpos = span->start_z;
+
+    /* Tile 内での座標 */
+    int localx = getLocalX(span->x-1);
+    int localy = getLocalY(span->y-1);
+
+    /**
+     * (tex_xpos, tex_ypos) の、Tile 内(上の図参照)での座標と
+     * そのブロックのアドレス(MainMemory)
+     */
+    int tex_localx;
+    int tex_localy;
+    uint32 *tex_addr;
+
+    if (span->x < startx || endx < span->x) {
+	return -1;
+    }
+
+    tex_xpos = (int)((span->tex_width-1) * tex);
+    tex_ypos = (int)((span->tex_height-1) * tey);
+
+    if (zpos < zRow[localx + (rangex*localy)]) {
+	tex_addr = getTile(tex_xpos, tex_ypos,
+			   span->tex_width, span->tex_addr);
+	tex_localx = tex_xpos % TEXTURE_SPLIT_PIXEL;
+	tex_localy = tex_ypos % TEXTURE_SPLIT_PIXEL;
+
+	if (!isAvailableTile(tex_addr)) {
+	    set_rgb(tex_addr, wait_tag);
+	    smanager->dma_wait(wait_tag);
+	    //return startx;
+	}
+
+	updateBuffer(zpos, rangex, localx, localy,
+		     tex_localx, tex_localy, tex_addr);
+    }
+
+    return -1;
+}
+
+void
+DrawSpan::drawDot2(SpanPtr span, int startx, int end, int js, int wait_tag)
+{
+    //printf("%d\n", js);
+}
+
+/**
+ * 長さが 1 より大きい Span の描画
+ *
+ * 本来の目的として、この関数(drawLine1) では
+ *   : 既に SPE 上に Tile のある pixel だけ描画
+ *   : それ以外は、ここで予め DMA load しておき、
+ *   : drawLine2 で一気に描画する
+ * ってものだったんだけど、どうも上手く行かなかったので
+ * 今は drawLine1 で load -> wait -> rendering を全部やってます
+ * (rendering といっても、rendering buffer に書き込むだけで
+ *  まだ main memory (frame buffer) に dma store してるわけではない)
+ *      
+ * @param span Span
+ * @param startx 描画開始範囲
+ * @param endx 描画終了範囲
+ * @return 「span のどの位置まで rendering が終わったか」の x 座標
+ */
+int
+DrawSpan::drawLine1(SpanPtr span, int startx, int endx, int wait_tag)
+{
+    int x = span->x;
+    int rangex = endx - startx + 1;
+    int x_len = span->length_x;
+
+    int js = (x < startx) ? startx - x : 0;
+    int je = (x + x_len > endx) ? endx - x : x_len;
+
+    /* span->x に対応する Texture の座標 (tex_xpos, tex_ypos) */
+    int tex_xpos, tex_ypos;
+
+    // span の始点に対応する座標 (tex1, tey1)
+    float tex1 = span->tex_x1;
+    float tey1 = span->tex_y1;
+
+    // span の終点に対応する座標 (tex2, tey2)
+    float tex2 = span->tex_x2;
+    float tey2 = span->tex_y2;
+
+    // span の始点、終点に対応する z 座標
+    float zpos1 = span->start_z;
+    float zpos2 = span->end_z;
+
+    // Tile 内での座標
+    int localx, localy = getLocalY(span->y-1);
+
+    int ret = je+1;
+
+    //for (int j = js; j <= je; j++) {
+    for (int j = je; j >= js; j--) {
+	float tex_x, tex_y, tex_z;
+
+	localx = getLocalX(x-1+j);
+
+	tex_z = zpos1*(x_len-1-j)/(x_len-1) + zpos2*j/(x_len-1);
+
+	tex_x = tex1*(x_len-1-j)/(x_len-1) + tex2*j/(x_len-1);
+	tex_y = tey1*(x_len-1-j)/(x_len-1) + tey2*j/(x_len-1);
+	if (tex_x > 1) tex_x = 1;
+	if (tex_x < 0) tex_x = 0;
+	if (tex_y > 1) tex_y = 1;
+	if (tex_y < 0) tex_y = 0;
+	tex_xpos = (int)((span->tex_width-1) * tex_x);
+	tex_ypos = (int)((span->tex_height-1) * tex_y);
+		    
+	if (tex_z < zRow[localx + (rangex*localy)]) {
+	    // (tex_xpos, tex_ypos) の、Tile 内(上の図参照)での座標と
+	    // そのブロックのアドレス(MainMemory)
+	    uint32 *tex_addr;
+	    int tex_localx;
+	    int tex_localy;
+
+	    tex_addr = getTile(tex_xpos, tex_ypos,
+			       span->tex_width, span->tex_addr);
+	    tex_localx = tex_xpos % TEXTURE_SPLIT_PIXEL;
+	    tex_localy = tex_ypos % TEXTURE_SPLIT_PIXEL;
+
+	    if (!isAvailableTile(tex_addr)) {
+#if 0
+		// span が必要とするであろう tile を予想紙
+		// set_rgbs で複数同時に load しようとしている図
+		// まあ上手くいかなかったんだけど。。
+		tex_x = tex1*(x_len-1-js)/(x_len-1) + tex2*js/(x_len-1);
+		if (tex_x > 1) tex_x = 1;
+		if (tex_x < 0) tex_x = 0;
+		tex_xpos = (int)((span->tex_width-1) * tex_x);
+
+		uint32 *max_addr = getTile(tex_xpos, tex_ypos,
+					   span->tex_width, span->tex_addr);
+
+		set_rgbs(tex_addr, max_addr, wait_tag);
+		return js;
+#else
+		set_rgb(tex_addr, wait_tag);
+		smanager->dma_wait(wait_tag);
+#endif
+	    }
+
+	    updateBuffer(tex_z, rangex, localx, localy,
+			 tex_localx, tex_localy, tex_addr);
+	}
+    }
+
+    return ret;
+}
+
+/**
+ * 長さが 1 より大きい Span の描画 (2段階目)
+ *
+ * 上にあるように、drawLine2 は今は動いてないです
+ * 正確には、js が startx ~ endx 範囲外にあり開始されないってところ
+ *
+ * @param span Span
+ * @param startx 描画開始範囲
+ * @param endx 描画終了範囲
+ * @param js 前回(drawLine1) で span のどこまで終わっているか
+ */
+void
+DrawSpan::drawLine2(SpanPtr span, int startx, int endx, int js, int wait_tag)
+{
+    int x = span->x;
+    int rangex = endx - startx + 1;
+    int x_len = span->length_x;
+
+    //int js = startx;
+    int je = (x + x_len > endx) ? endx - x : x_len;
+
+    /* span->x に対応する Texture の座標 (tex_xpos, tex_ypos) */
+    int tex_xpos, tex_ypos;
+
+    // span の始点に対応する座標 (tex1, tey1)
+    float tex1 = span->tex_x1;
+    float tey1 = span->tex_y1;
+
+    // span の終点に対応する座標 (tex2, tey2)
+    float tex2 = span->tex_x2;
+    float tey2 = span->tex_y2;
+
+    // span の始点、終点に対応する z 座標
+    float zpos1 = span->start_z;
+    float zpos2 = span->end_z;
+
+    // Tile 内での座標
+    int localx, localy = getLocalY(span->y-1);
+
+    // (tex_xpos, tex_ypos) の、Tile 内(上の図参照)での座標と
+    // そのブロックのアドレス(MainMemory)
+    int tex_localx;
+    int tex_localy;
+    uint32 *tex_addr;
+
+    float tex_x, tex_y, tex_z;
+
+    smanager->dma_wait(wait_tag);
+
+    for (int j = js; j <= je; j++) {
+	localx = getLocalX(x-1+j);
+
+	tex_z = zpos1*(x_len-1-j)/(x_len-1) + zpos2*j/(x_len-1);
+
+	tex_x = tex1*(x_len-1-j)/(x_len-1) + tex2*j/(x_len-1);
+	tex_y = tey1*(x_len-1-j)/(x_len-1) + tey2*j/(x_len-1);
+	if (tex_x > 1) tex_x = 1;
+	if (tex_x < 0) tex_x = 0;
+	if (tex_y > 1) tex_y = 1;
+	if (tex_y < 0) tex_y = 0;
+	tex_xpos = (int)((span->tex_width-1) * tex_x);
+	tex_ypos = (int)((span->tex_height-1) * tex_y);
+
+	if (tex_z < zRow[localx + (rangex*localy)]) {
+	    tex_addr = getTile(tex_xpos, tex_ypos,
+			       span->tex_width, span->tex_addr);
+	    tex_localx = tex_xpos % TEXTURE_SPLIT_PIXEL;
+	    tex_localy = tex_ypos % TEXTURE_SPLIT_PIXEL;
+
+	    updateBuffer(tex_z, rangex, localx, localy,
+			 tex_localx, tex_localy, tex_addr);
+	}
+    }    
+}
+
+int
+DrawSpan::run(void *rbuf, void *wbuf)
+{
+    SpanPackPtr spack = (SpanPackPtr)smanager->get_input(0);
+    SpanPackPtr next_spack = (SpanPackPtr)smanager->allocate(sizeof(SpanPack));
+    SpanPackPtr free_spack = next_spack; // next_spack の free() 用
+    Span *span;
+
+    Span nop_span;
+    nop_span.length_x = 1;
+
+    int (DrawSpan::*drawFunc1[2])(SpanPtr, int, int, int) = {
+	&DrawSpan::drawDot1, &DrawSpan::drawLine1
+    };
+
+    void (DrawSpan::*drawFunc2[2])(SpanPtr, int, int, int, int) = {
+	&DrawSpan::drawDot2, &DrawSpan::drawLine2
+    };
+
+    uint32 display   = smanager->get_param(0);
+    int screen_width = smanager->get_param(1);
+    int rangex_start = smanager->get_param(2);
+    int rangex_e