changeset 424:960471b7ee54

merge chain...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Thu, 24 Sep 2009 16:06:01 +0900
parents cd77224d4224 (current diff) afb717c43a3c (diff)
children 799071db126e
files TaskManager/Test/test_render/spe/ChainCal.cpp TaskManager/Test/test_render/spe/ChainInit.cpp TaskManager/Test/test_render/spe/CreatePolygon.cpp TaskManager/Test/test_render/spe/CreateSpan.cpp TaskManager/Test/test_render/spe/DrawBack.cpp TaskManager/Test/test_render/spe/DrawSpan.cpp TaskManager/Test/test_render/spe/DrawSpanRenew.cpp TaskManager/Test/test_render/spe/Load_Texture.cpp TaskManager/Test/test_render/spe/Set_Texture.cpp TaskManager/Test/test_render/spe/ShowTime.cpp TaskManager/Test/test_render/spe/TileHash.cpp TaskManager/Test/test_render/spe/spe-main.cpp TaskManager/Test/test_render/spe/viewer_types.cpp
diffstat 32 files changed, 1841 insertions(+), 1917 deletions(-) [+]
line wrap: on
line diff
--- a/TaskManager/Test/test_render/KeyStat.h	Thu Sep 24 16:04:23 2009 +0900
+++ b/TaskManager/Test/test_render/KeyStat.h	Thu Sep 24 16:06:01 2009 +0900
@@ -7,12 +7,16 @@
     PUSH,
 };
 
+// 可変長の構造体にする。
+// int で1つ送り bit field でやると
 typedef struct key_stat {
+    int length;
     int right;
     int left;
     int up;
     int down;
     int circle;
+    unsigned char data[0];
 };
 
 #endif
--- a/TaskManager/Test/test_render/SceneGraphRoot.cc	Thu Sep 24 16:04:23 2009 +0900
+++ b/TaskManager/Test/test_render/SceneGraphRoot.cc	Thu Sep 24 16:06:01 2009 +0900
@@ -196,40 +196,14 @@
     }
 
     /*removeのflagをもとにtreeを形成*/
-    while (t) {
-	SceneGraphPtr c = NULL;
-	if (!t->isRemoved()) {
-	    c = t->clone();	    
-	    addNext(c);
-	    cur_parent->addChild(c);
-	    c->frame = t->frame;
-            /*親の回転、座標から、子の回転、座標を算出*/
-            get_matrix(c->matrix, c->angle, c->xyz, cur_parent->matrix);
-        } 
-
-	if (t->children != NULL && c != NULL) {
-	    cur_parent = c;
-	    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 {
-                        cur_parent = cur_parent->parent;
-                        t = t->parent;
-			
-		    }
-		}
-	    }	    
-	}
+    /* spe から送り返されてきた property の配列を見て生成する for()*/
+    /*
+    for (Property *t = property[0]; is_end(t); t++){
+	SceneGraphPtr s = application->scenegraph_factory(t); // SceneGraphNode を作る
+	t->scenegraph = s; // property list には SceneGraphへのポインタが入っている
+	application->scenegraph_connector(property[0], s); // add する
     }
+    */
 
       
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TaskManager/Test/test_render/spe/ChainCal.cc	Thu Sep 24 16:06:01 2009 +0900
@@ -0,0 +1,91 @@
+#include <stdio.h>
+#include <string.h>
+#include "ChainCal.h"
+#include "Func.h"
+#include "types.h"
+#include <math.h>
+
+
+/* これは必須 */
+SchedDefineTask(ChainCal);
+
+#define CHAIN_LEN 50
+
+static double m = 100.0;
+static double k = 7000.0;
+static double g = 9.8;
+static double dt = 0.003;
+static double chain_width = 10;
+static double safe = 0.995;
+
+typedef struct {
+    double x, y, next_x, next_y;
+    double vx, vy, next_vx, next_vy;
+    double angle[3];
+    int can_move;
+    uint32 parent;
+    int id;
+    //int parent;
+} CHAIN_VARS;
+
+int
+ChainCal::run(void *rbuf, void *wbuf)
+{
+    CHAIN_VARS* property = (CHAIN_VARS*)rbuf;
+    int id = get_param(0);
+    
+    //CHAIN_VARS* o_property = (CHAIN_VARS*)wbuf;
+    
+    for(int cnt = 0; cnt < 600; cnt++) {
+		for(int i = 0; i < CHAIN_LEN; i++) {
+			if(property[i].can_move) {
+				double dx = property[i-1].x - property[i].x;
+				double dy = property[i-1].y - property[i].y;
+				double l = sqrt(dx * dx + dy * dy);
+				double a = k * (l - chain_width) / m;
+				double ax = a * dx / l;
+				double ay = a * dy / l;
+				if(i < CHAIN_LEN - 1) {
+					dx = property[i+1].x - property[i].x;
+					dy = property[i+1].y - property[i].y;
+					l = sqrt(dx * dx + dy * dy);
+					a = k * (l - chain_width) / m;
+					ax += a * dx / l;
+					ay += a * dy / l;
+				}
+				ay += g;
+				property[i].vx *= safe;
+				property[i].vy *= safe;
+				property[i].next_vx = property[i].vx + ax * dt;
+				property[i].next_vy = property[i].vy + ay * dt;
+				property[i].next_x = property[i].x + property[i].vx * dt;
+				property[i].next_y = property[i].y + property[i].vy * dt;
+			} else {
+				property[i].next_x = property[i].x;
+				property[i].next_y = property[i].y;
+			}
+		}
+		for(int i = 0; i < CHAIN_LEN; i++) {
+			property[i].vx = property[i].next_vx;
+			property[i].vy = property[i].next_vy;
+			property[i].x = property[i].next_x;
+			property[i].y = property[i].next_y;
+		}
+    }
+	
+    for (int j = 0; j < CHAIN_LEN; j++) {
+		int p, n;
+		id = property[j].id;
+		p = n = id;
+		if(p != 0) {
+			p--;
+		}
+		if(n != CHAIN_LEN - 1) {
+			n++;
+		}
+		property[j].angle[2-(id%2)*2]
+			= 90 + atan((property[p].next_y - property[n].next_y) / (property[p].next_x - property[n].next_x)) * 180 / M_PI;
+    }
+    
+    return 0;
+}
--- a/TaskManager/Test/test_render/spe/ChainCal.cpp	Thu Sep 24 16:04:23 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,91 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include "ChainCal.h"
-#include "Func.h"
-#include "types.h"
-#include <math.h>
-
-
-/* これは必須 */
-SchedDefineTask(ChainCal);
-
-#define CHAIN_LEN 50
-
-static double m = 100.0;
-static double k = 7000.0;
-static double g = 9.8;
-static double dt = 0.003;
-static double chain_width = 10;
-static double safe = 0.995;
-
-typedef struct {
-    double x, y, next_x, next_y;
-    double vx, vy, next_vx, next_vy;
-    double angle[3];
-    int can_move;
-    uint32 parent;
-    int id;
-    //int parent;
-} CHAIN_VARS;
-
-int
-ChainCal::run(void *rbuf, void *wbuf)
-{
-    CHAIN_VARS* property = (CHAIN_VARS*)rbuf;
-    int id = get_param(0);
-    
-    //CHAIN_VARS* o_property = (CHAIN_VARS*)wbuf;
-    
-    for(int cnt = 0; cnt < 600; cnt++) {
-		for(int i = 0; i < CHAIN_LEN; i++) {
-			if(property[i].can_move) {
-				double dx = property[i-1].x - property[i].x;
-				double dy = property[i-1].y - property[i].y;
-				double l = sqrt(dx * dx + dy * dy);
-				double a = k * (l - chain_width) / m;
-				double ax = a * dx / l;
-				double ay = a * dy / l;
-				if(i < CHAIN_LEN - 1) {
-					dx = property[i+1].x - property[i].x;
-					dy = property[i+1].y - property[i].y;
-					l = sqrt(dx * dx + dy * dy);
-					a = k * (l - chain_width) / m;
-					ax += a * dx / l;
-					ay += a * dy / l;
-				}
-				ay += g;
-				property[i].vx *= safe;
-				property[i].vy *= safe;
-				property[i].next_vx = property[i].vx + ax * dt;
-				property[i].next_vy = property[i].vy + ay * dt;
-				property[i].next_x = property[i].x + property[i].vx * dt;
-				property[i].next_y = property[i].y + property[i].vy * dt;
-			} else {
-				property[i].next_x = property[i].x;
-				property[i].next_y = property[i].y;
-			}
-		}
-		for(int i = 0; i < CHAIN_LEN; i++) {
-			property[i].vx = property[i].next_vx;
-			property[i].vy = property[i].next_vy;
-			property[i].x = property[i].next_x;
-			property[i].y = property[i].next_y;
-		}
-    }
-	
-    for (int j = 0; j < CHAIN_LEN; j++) {
-		int p, n;
-		id = property[j].id;
-		p = n = id;
-		if(p != 0) {
-			p--;
-		}
-		if(n != CHAIN_LEN - 1) {
-			n++;
-		}
-		property[j].angle[2-(id%2)*2]
-			= 90 + atan((property[p].next_y - property[n].next_y) / (property[p].next_x - property[n].next_x)) * 180 / M_PI;
-    }
-    
-    return 0;
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TaskManager/Test/test_render/spe/ChainInit.cc	Thu Sep 24 16:06:01 2009 +0900
@@ -0,0 +1,33 @@
+#include <stdio.h>
+#include <string.h>
+#include "ChainInit.h"
+#include "Func.h"
+
+/* これは必須 */
+SchedDefineTask(ChainInit);
+
+/*
+  spe の global 領域に MemList を生成する
+ */
+
+typedef struct {
+    double x, y, next_x, next_y;
+    double vx, vy, next_vx, next_vy;
+    int can_move;
+    uint32 parent;
+} CHAIN_VARS;
+
+CHAIN_VARS* property;
+
+int
+ChainInit::run(void *rbuf, void *wbuf)
+{
+    CHAIN_VARS* idata = (CHAIN_VARS*)get_input(rbuf, 0);
+    uint32 chain_len = get_param(0);
+
+    // property は spe 上で allocate している(global)
+    property = (CHAIN_VARS*)global_alloc(DATA_ID, sizeof(CHAIN_VARS)*chain_len);
+    memcpy(property, idata, sizeof(CHAIN_VARS)*chain_len);
+
+    return 0;
+}
--- a/TaskManager/Test/test_render/spe/ChainInit.cpp	Thu Sep 24 16:04:23 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include "ChainInit.h"
-#include "Func.h"
-
-/* これは必須 */
-SchedDefineTask(ChainInit);
-
-/*
-  spe の global 領域に MemList を生成する
- */
-
-typedef struct {
-    double x, y, next_x, next_y;
-    double vx, vy, next_vx, next_vy;
-    int can_move;
-    uint32 parent;
-} CHAIN_VARS;
-
-CHAIN_VARS* property;
-
-int
-ChainInit::run(void *rbuf, void *wbuf)
-{
-    CHAIN_VARS* idata = (CHAIN_VARS*)get_input(rbuf, 0);
-    uint32 chain_len = get_param(0);
-
-    // property は spe 上で allocate している(global)
-    property = (CHAIN_VARS*)global_alloc(DATA_ID, sizeof(CHAIN_VARS)*chain_len);
-    memcpy(property, idata, sizeof(CHAIN_VARS)*chain_len);
-
-    return 0;
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TaskManager/Test/test_render/spe/CreatePolygon.cc	Thu Sep 24 16:06:01 2009 +0900
@@ -0,0 +1,196 @@
+/**
+ * SceneGraph が増えてくると動かなくなるかもしれない。
+ * 一応 mainMem とかで動くようになるとは思うけど。
+ * だめだったら、そこら辺が怪しいと思うべき
+ */
+
+// #define DEBUG
+#include "error.h"
+
+#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)
+{
+    __debug_spe("CreatePolygon\n");
+
+    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;
+}    
--- a/TaskManager/Test/test_render/spe/CreatePolygon.cpp	Thu Sep 24 16:04:23 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,196 +0,0 @@
-/**
- * SceneGraph が増えてくると動かなくなるかもしれない。
- * 一応 mainMem とかで動くようになるとは思うけど。
- * だめだったら、そこら辺が怪しいと思うべき
- */
-
-// #define DEBUG
-#include "error.h"
-
-#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)
-{
-    __debug_spe("CreatePolygon\n");
-
-    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/TaskManager/Test/test_render/spe/CreateSpan.cc	Thu Sep 24 16:06:01 2009 +0900
@@ -0,0 +1,505 @@
+// #define DEBUG
+#include "error.h"
+#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(SchedTask *smanager, 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;
+		
+	__debug_spe("CreateSpan mainMem_alloc 0x%x\n", (unsigned int)sizeof(SpanPack));
+		smanager->mainMem_alloc(0, sizeof(SpanPack));
+		smanager->mainMem_wait();
+		next = (SpanPackPtr)smanager->mainMem_get(0);
+	__debug_spe("CreateSpan mainMem_allocated 0x%x\n", (unsigned int)next);
+		
+		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(SchedTask *smanager, void *rbuf, void *wbuf)
+{
+    __debug_spe("CreateSpan\n");
+
+    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 {
+	__debug_spe("CreateSpan allocated 0x%x\n",(uint32)next_pp);
+
+	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(smanager, 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(smanager, 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);
+	__debug_spe("CreateSpan spack_stored 0x%x\n",(uint32)spackList[prev_index]);
+
+    // smanager で allocate したのだから free も smanager でやるべき
+    free(free_pp);
+    free(free_spack);
+    free(vMid10);
+
+    return 0;
+}
--- a/TaskManager/Test/test_render/spe/CreateSpan.cpp	Thu Sep 24 16:04:23 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,505 +0,0 @@
-// #define DEBUG
-#include "error.h"
-#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(SchedTask *smanager, 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;
-		
-	__debug_spe("CreateSpan mainMem_alloc 0x%x\n", (unsigned int)sizeof(SpanPack));
-		smanager->mainMem_alloc(0, sizeof(SpanPack));
-		smanager->mainMem_wait();
-		next = (SpanPackPtr)smanager->mainMem_get(0);
-	__debug_spe("CreateSpan mainMem_allocated 0x%x\n", (unsigned int)next);
-		
-		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(SchedTask *smanager, void *rbuf, void *wbuf)
-{
-    __debug_spe("CreateSpan\n");
-
-    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 {
-	__debug_spe("CreateSpan allocated 0x%x\n",(uint32)next_pp);
-
-	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(smanager, 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(smanager, 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);
-	__debug_spe("CreateSpan spack_stored 0x%x\n",(uint32)spackList[prev_index]);
-
-    // 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/TaskManager/Test/test_render/spe/DrawBack.cc	Thu Sep 24 16:06:01 2009 +0900
@@ -0,0 +1,36 @@
+// #define DEBUG
+#include "error.h"
+
+#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(SchedTask *smanager, void *rbuf, void *wbuf)
+{
+    __debug_spe("DrawBack\n");
+    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;
+}
--- a/TaskManager/Test/test_render/spe/DrawBack.cpp	Thu Sep 24 16:04:23 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-// #define DEBUG
-#include "error.h"
-
-#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(SchedTask *smanager, void *rbuf, void *wbuf)
-{
-    __debug_spe("DrawBack\n");
-    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/TaskManager/Test/test_render/spe/DrawSpan.cc	Thu Sep 24 16:06:01 2009 +0900
@@ -0,0 +1,497 @@
+// #define DEBUG
+#include "error.h"
+
+#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"
+#include "global_alloc.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
+ */
+memaddr
+DrawSpan::getTile(int tx, int ty, int tw, memaddr tex_addr_top)
+{
+    int block = getTexBlock(tx, ty, tw);
+    return tex_addr_top + block*TEXTURE_BLOCK_SIZE * sizeof(uint32);
+}
+
+/**
+ * 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;
+
+    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);
+    }
+
+    return buf;
+}
+
+
+uint32
+DrawSpan::get_rgb(int tx, int ty, TilePtr tile)
+{
+    uint32 *data = (uint32 *)tile->data;
+    return data[(TEXTURE_SPLIT_PIXEL)*ty+tx];
+}
+
+#if 0
+/**
+ * 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);
+}
+#endif
+
+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, TilePtr tile)
+{
+    int rgb = get_rgb(tex_x, tex_y, tile);
+
+    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;
+    memaddr 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, (memaddr)span->tex_addr);
+        tex_localx = tex_xpos % TEXTURE_SPLIT_PIXEL;
+        tex_localy = tex_ypos % TEXTURE_SPLIT_PIXEL;
+
+        TilePtr tile = smanager->get_segment(tex_addr,tileList);
+        smanager->wait_segment(tile);
+
+        updateBuffer(zpos, rangex, localx, localy,
+                     tex_localx, tex_localy, tile);	
+    }
+
+    return -1;
+}
+
+
+/**
+ * 長さが 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)
+            memaddr tex_addr;
+            int tex_localx;
+            int tex_localy;
+
+            tex_addr = getTile(tex_xpos, tex_ypos,
+                               span->tex_width, (memaddr)span->tex_addr);
+            tex_localx = tex_xpos % TEXTURE_SPLIT_PIXEL;
+            tex_localy = tex_ypos % TEXTURE_SPLIT_PIXEL;
+
+	    TilePtr tile = smanager->get_segment(tex_addr,tileList);
+	    smanager->wait_segment(tile);
+
+            updateBuffer(tex_z, rangex, localx, localy,
+			 tex_localx, tex_localy, tile);
+        }
+    }
+
+    return ret;
+}
+
+int
+DrawSpan::run(SchedTask *smanager, void *rbuf, void *wbuf)
+{
+    __debug_spe("DrawSpan\n");
+    this->smanager = smanager;
+    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
+    };
+
+    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);
+
+    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, (memaddr)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;
+
+            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;
+}
--- a/TaskManager/Test/test_render/spe/DrawSpan.cpp	Thu Sep 24 16:04:23 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,497 +0,0 @@
-// #define DEBUG
-#include "error.h"
-
-#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"
-#include "global_alloc.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
- */
-memaddr
-DrawSpan::getTile(int tx, int ty, int tw, memaddr tex_addr_top)
-{
-    int block = getTexBlock(tx, ty, tw);
-    return tex_addr_top + block*TEXTURE_BLOCK_SIZE * sizeof(uint32);
-}
-
-/**
- * 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;
-
-    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);
-    }
-
-    return buf;
-}
-
-
-uint32
-DrawSpan::get_rgb(int tx, int ty, TilePtr tile)
-{
-    uint32 *data = (uint32 *)tile->data;
-    return data[(TEXTURE_SPLIT_PIXEL)*ty+tx];
-}
-
-#if 0
-/**
- * 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);
-}
-#endif
-
-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, TilePtr tile)
-{
-    int rgb = get_rgb(tex_x, tex_y, tile);
-
-    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;
-    memaddr 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, (memaddr)span->tex_addr);
-        tex_localx = tex_xpos % TEXTURE_SPLIT_PIXEL;
-        tex_localy = tex_ypos % TEXTURE_SPLIT_PIXEL;
-
-        TilePtr tile = smanager->get_segment(tex_addr,tileList);
-        smanager->wait_segment(tile);
-
-        updateBuffer(zpos, rangex, localx, localy,
-                     tex_localx, tex_localy, tile);	
-    }
-
-    return -1;
-}
-
-
-/**
- * 長さが 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)
-            memaddr tex_addr;
-            int tex_localx;
-            int tex_localy;
-
-            tex_addr = getTile(tex_xpos, tex_ypos,
-                               span->tex_width, (memaddr)span->tex_addr);
-            tex_localx = tex_xpos % TEXTURE_SPLIT_PIXEL;
-            tex_localy = tex_ypos % TEXTURE_SPLIT_PIXEL;
-
-	    TilePtr tile = smanager->get_segment(tex_addr,tileList);
-	    smanager->wait_segment(tile);
-
-            updateBuffer(tex_z, rangex, localx, localy,
-			 tex_localx, tex_localy, tile);
-        }
-    }
-
-    return ret;
-}
-
-int
-DrawSpan::run(SchedTask *smanager, void *rbuf, void *wbuf)
-{
-    __debug_spe("DrawSpan\n");
-    this->smanager = smanager;
-    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
-    };
-
-    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);
-
-    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, (memaddr)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;
-
-            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/TaskManager/Test/test_render/spe/DrawSpanRenew.cc	Thu Sep 24 16:06:01 2009 +0900
@@ -0,0 +1,220 @@
+#if 0
+// #define DEBUG
+#include "error.h"
+
+#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"
+#include "global_alloc.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)
+{
+    __debug_spe("DrawSpanRenew\n");
+    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, (memaddr)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;
+            memaddr 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, (memaddr)span->tex_addr);
+                    tex_localx = tex_xpos % TEXTURE_SPLIT_PIXEL;
+                    tex_localy = tex_ypos % TEXTURE_SPLIT_PIXEL;
+
+		    TilePtr tile = smanager->get_segment(tex_addr,tileList);
+		    smanager->wait_segment(tile);
+
+                    rgb = get_rgb(tex_localx, tex_localy, tile);
+
+                    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, (memaddr)span->tex_addr);
+                        tex_localx = tex_xpos % TEXTURE_SPLIT_PIXEL;
+                        tex_localy = tex_ypos % TEXTURE_SPLIT_PIXEL;
+
+			TilePtr tile = smanager->get_segment(tex_addr,tileList);
+			smanager->wait_segment(tile);
+
+                        rgb = get_rgb(tex_localx, tex_localy, tile);
+
+                        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;
+}
+#endif
--- a/TaskManager/Test/test_render/spe/DrawSpanRenew.cpp	Thu Sep 24 16:04:23 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,220 +0,0 @@
-#if 0
-// #define DEBUG
-#include "error.h"
-
-#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"
-#include "global_alloc.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)
-{
-    __debug_spe("DrawSpanRenew\n");
-    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, (memaddr)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;
-            memaddr 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, (memaddr)span->tex_addr);
-                    tex_localx = tex_xpos % TEXTURE_SPLIT_PIXEL;
-                    tex_localy = tex_ypos % TEXTURE_SPLIT_PIXEL;
-
-		    TilePtr tile = smanager->get_segment(tex_addr,tileList);
-		    smanager->wait_segment(tile);
-
-                    rgb = get_rgb(tex_localx, tex_localy, tile);
-
-                    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, (memaddr)span->tex_addr);
-                        tex_localx = tex_xpos % TEXTURE_SPLIT_PIXEL;
-                        tex_localy = tex_ypos % TEXTURE_SPLIT_PIXEL;
-
-			TilePtr tile = smanager->get_segment(tex_addr,tileList);
-			smanager->wait_segment(tile);
-
-                        rgb = get_rgb(tex_localx, tex_localy, tile);
-
-                        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;
-}
-#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TaskManager/Test/test_render/spe/Load_Texture.cc	Thu Sep 24 16:06:01 2009 +0900
@@ -0,0 +1,29 @@
+// #define DEBUG
+#include "error.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include "Load_Texture.h"
+#include "texture.h"
+#if !USE_MEMHASH
+#include "TileHash.h"
+#endif
+#include "Func.h"
+#include "global_alloc.h"
+
+SchedDefineTask(LoadTexture);
+
+/**
+ * 「Load」といいながら、結局 DrawSpan で使う
+ * Hash の準備だけなので、名前変えないとなー
+ */
+int
+LoadTexture::run(SchedTask *smanager, void *rbuf , void *wbuf)
+{
+    __debug_spe("LoadTexture\n");
+
+    MemList *ml = smanager->createMemList(sizeof(uint32) * TEXTURE_BLOCK_SIZE, MAX_TILE);
+    smanager->global_set(GLOBAL_TILE_LIST, (void *)ml);
+
+    return 0;
+}
--- a/TaskManager/Test/test_render/spe/Load_Texture.cpp	Thu Sep 24 16:04:23 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-// #define DEBUG
-#include "error.h"
-
-#include <stdlib.h>
-#include <string.h>
-#include "Load_Texture.h"
-#include "texture.h"
-#if !USE_MEMHASH
-#include "TileHash.h"
-#endif
-#include "Func.h"
-#include "global_alloc.h"
-
-SchedDefineTask(LoadTexture);
-
-/**
- * 「Load」といいながら、結局 DrawSpan で使う
- * Hash の準備だけなので、名前変えないとなー
- */
-int
-LoadTexture::run(SchedTask *smanager, void *rbuf , void *wbuf)
-{
-    __debug_spe("LoadTexture\n");
-
-    MemList *ml = smanager->createMemList(sizeof(uint32) * TEXTURE_BLOCK_SIZE, MAX_TILE);
-    smanager->global_set(GLOBAL_TILE_LIST, (void *)ml);
-
-    return 0;
-}
--- a/TaskManager/Test/test_render/spe/Makefile	Thu Sep 24 16:04:23 2009 +0900
+++ b/TaskManager/Test/test_render/spe/Makefile	Thu Sep 24 16:06:01 2009 +0900
@@ -4,19 +4,19 @@
 
 TOP = ../$(CERIUM)
 
-SRCS_TMP = $(wildcard *.cpp)
-SRCS_EXCLUDE = CreatePolygon.cpp
+SRCS_TMP = $(wildcard *.cc)
+SRCS_EXCLUDE = CreatePolygon.cc
 SRCS = $(filter-out $(SRCS_EXCLUDE),$(SRCS_TMP))
-OBJS = $(SRCS:.cpp=.o)
+OBJS = $(SRCS:.cc=.o)
 
 CC      = spu-g++
 CFLAGS  = -O9 -Wall -g -fno-exceptions -fno-rtti -DUSE_MEMLIST=1 -DUSE_MEMHASH=1 #-DDEBUG
 INCLUDE = -I$(TOP)/include/TaskManager -I. -I..
 LIBS    = -L$(TOP)/TaskManager -lspemanager
 
-.SUFFIXES: .cpp .o
+.SUFFIXES: .cc .o
 
-.cpp.o:
+.cc.o:
 	$(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@
 
 all: $(TARGET)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TaskManager/Test/test_render/spe/Set_Texture.cc	Thu Sep 24 16:06:01 2009 +0900
@@ -0,0 +1,35 @@
+// #define DEBUG
+#include "error.h"
+#include <string.h>
+#include "Set_Texture.h"
+#include "texture.h"
+#include "global_alloc.h"
+
+SchedDefineTask(SetTexture);
+
+//texture をglobal 領域にコピーするタスク
+int
+SetTexture::run(void *rbuf, void *wbuf)
+{
+    __debug_spe("SetTexture\n");
+    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;
+}
--- a/TaskManager/Test/test_render/spe/Set_Texture.cpp	Thu Sep 24 16:04:23 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,35 +0,0 @@
-// #define DEBUG
-#include "error.h"
-#include <string.h>
-#include "Set_Texture.h"
-#include "texture.h"
-#include "global_alloc.h"
-
-SchedDefineTask(SetTexture);
-
-//texture をglobal 領域にコピーするタスク
-int
-SetTexture::run(void *rbuf, void *wbuf)
-{
-    __debug_spe("SetTexture\n");
-    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/TaskManager/Test/test_render/spe/ShowTime.cc	Thu Sep 24 16:06:01 2009 +0900
@@ -0,0 +1,17 @@
+#include "ShowTime.h"
+#include "stdio.h"
+
+SchedDefineTask(ShowTime);
+
+int
+ShowTime::run(SchedTask *smanager, void *rbuf, void *wbuf)
+{
+    /*
+     * ここで show_dma_wait() を呼びたい
+     */
+    smanager->show_dma_wait();
+    //printf("Show Time !\n");
+
+    return 0;
+}
+
--- a/TaskManager/Test/test_render/spe/ShowTime.cpp	Thu Sep 24 16:04:23 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,17 +0,0 @@
-#include "ShowTime.h"
-#include "stdio.h"
-
-SchedDefineTask(ShowTime);
-
-int
-ShowTime::run(SchedTask *smanager, void *rbuf, void *wbuf)
-{
-    /*
-     * ここで show_dma_wait() を呼びたい
-     */
-    smanager->show_dma_wait();
-    //printf("Show Time !\n");
-
-    return 0;
-}
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TaskManager/Test/test_render/spe/TileHash.cc	Thu Sep 24 16:06:01 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(memaddr data)
+{
+    int value = 0;
+    int n = 0;
+    int key;
+
+    for (uint32 i = 0; i < sizeof(memaddr) * 2; i ++) {
+        key = data & 0xf;
+        value += key * PRIME[n++ & 7];
+        data >>= 4;
+    }
+
+    return value % hashSize;
+}
+
+TileHash::TileHash(void)
+{
+  //hashSize = 263;
+  //tableSize = sizeof(TilePtr)*hashSize;
+
+    table = (TilePtr*)malloc(tableSize);
+    clear();
+}
+
+int
+TileHash::put(memaddr key, TilePtr data)
+{
+    int hashval = hash(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(memaddr key)
+{
+    int hashval = hash(key);
+
+    for (int i = 0; i < hashSize/2; i++) {
+        int index = (hashval + i*i)%hashSize;
+
+        if (table[index] != NULL &&
+            table[index]->address == key) {
+            return table[index];
+        }
+    }
+
+    return NULL;
+}
+
+void
+TileHash::remove(memaddr key)
+{
+    int hashval = hash(key);
+
+    for (int i = 0; i < hashSize/2; i++) {
+        int index = (hashval + i*i)%hashSize;
+
+        if (table[index] != NULL &&
+            table[index]->address == key) {
+            table[index] = NULL;
+        }
+    }
+}
+
+void
+TileHash::clear(void)
+{
+    bzero(table, tableSize);
+}
--- a/TaskManager/Test/test_render/spe/TileHash.cpp	Thu Sep 24 16:04:23 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,88 +0,0 @@
-#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(memaddr data)
-{
-    int value = 0;
-    int n = 0;
-    int key;
-
-    for (uint32 i = 0; i < sizeof(memaddr) * 2; i ++) {
-        key = data & 0xf;
-        value += key * PRIME[n++ & 7];
-        data >>= 4;
-    }
-
-    return value % hashSize;
-}
-
-TileHash::TileHash(void)
-{
-  //hashSize = 263;
-  //tableSize = sizeof(TilePtr)*hashSize;
-
-    table = (TilePtr*)malloc(tableSize);
-    clear();
-}
-
-int
-TileHash::put(memaddr key, TilePtr data)
-{
-    int hashval = hash(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(memaddr key)
-{
-    int hashval = hash(key);
-
-    for (int i = 0; i < hashSize/2; i++) {
-        int index = (hashval + i*i)%hashSize;
-
-        if (table[index] != NULL &&
-            table[index]->address == key) {
-            return table[index];
-        }
-    }
-
-    return NULL;
-}
-
-void
-TileHash::remove(memaddr key)
-{
-    int hashval = hash(key);
-
-    for (int i = 0; i < hashSize/2; i++) {
-        int index = (hashval + i*i)%hashSize;
-
-        if (table[index] != NULL &&
-            table[index]->address == key) {
-            table[index] = NULL;
-        }
-    }
-}
-
-void
-TileHash::clear(void)
-{
-    bzero(table, tableSize);
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TaskManager/Test/test_render/spe/spe-main.cc	Thu Sep 24 16:06:01 2009 +0900
@@ -0,0 +1,36 @@
+#include "../Func.h"
+#include "SchedTask.h"
+
+SchedExternTask(LoadTexture);
+SchedExternTask(SetTexture);
+SchedExternTask(DrawSpan);
+SchedExternTask(DrawSpanRenew);
+SchedExternTask(DrawBack);
+
+SchedExternTask(ChainCal);
+SchedExternTask(ChainInit);
+
+SchedExternTask(CreateSpan);
+//SchedExternTask(CreatePolygon);
+
+SchedExternTask(ShowTime);
+
+void
+task_init(void)
+{
+    SchedRegisterTask(TASK_INIT_TEXTURE, LoadTexture);
+    SchedRegisterTask(TASK_SET_TEXTURE, SetTexture);
+    SchedRegisterTask(TASK_DRAW_SPAN, DrawSpan);
+
+    SchedRegisterTask(CHAINCAL_TASK, ChainCal);
+    SchedRegisterTask(CHAININIT_TASK, ChainInit);
+#if 0
+    SchedRegisterTask(TASK_DRAW_SPAN2, DrawSpanRenew);
+#endif
+    SchedRegisterTask(TASK_DRAW_BACK, DrawBack);
+
+    SchedRegisterTask(TASK_CREATE_SPAN, CreateSpan);
+    //SchedRegisterTask(TASK_CREATE_PP, CreatePolygon);
+
+    SchedRegisterTask(SHOW_TIME, ShowTime);
+}
--- a/TaskManager/Test/test_render/spe/spe-main.cpp	Thu Sep 24 16:04:23 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-#include "../Func.h"
-#include "SchedTask.h"
-
-SchedExternTask(LoadTexture);
-SchedExternTask(SetTexture);
-SchedExternTask(DrawSpan);
-SchedExternTask(DrawSpanRenew);
-SchedExternTask(DrawBack);
-
-SchedExternTask(ChainCal);
-SchedExternTask(ChainInit);
-
-SchedExternTask(CreateSpan);
-//SchedExternTask(CreatePolygon);
-
-SchedExternTask(ShowTime);
-
-void
-task_init(void)
-{
-    SchedRegisterTask(TASK_INIT_TEXTURE, LoadTexture);
-    SchedRegisterTask(TASK_SET_TEXTURE, SetTexture);
-    SchedRegisterTask(TASK_DRAW_SPAN, DrawSpan);
-
-    SchedRegisterTask(CHAINCAL_TASK, ChainCal);
-    SchedRegisterTask(CHAININIT_TASK, ChainInit);
-#if 0
-    SchedRegisterTask(TASK_DRAW_SPAN2, DrawSpanRenew);
-#endif
-    SchedRegisterTask(TASK_DRAW_BACK, DrawBack);
-
-    SchedRegisterTask(TASK_CREATE_SPAN, CreateSpan);
-    //SchedRegisterTask(TASK_CREATE_PP, CreatePolygon);
-
-    SchedRegisterTask(SHOW_TIME, ShowTime);
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TaskManager/Test/test_render/spe/viewer_types.cc	Thu Sep 24 16:06:01 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);
+}
--- a/TaskManager/Test/test_render/spe/viewer_types.cpp	Thu Sep 24 16:04:23 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-#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);
-}
--- a/TaskManager/Test/test_render/task/Switch.cc	Thu Sep 24 16:04:23 2009 +0900
+++ b/TaskManager/Test/test_render/task/Switch.cc	Thu Sep 24 16:06:01 2009 +0900
@@ -9,6 +9,7 @@
 int
 Switch::run(void *rbuf, void *wbuf)
 {
+// 配列にする
     SceneGraphRootPtr tmp = sgroot;
     sgroot = sgroot_2;
     sgroot_2 = tmp;
--- a/TaskManager/Test/test_render/viewer.cc	Thu Sep 24 16:04:23 2009 +0900
+++ b/TaskManager/Test/test_render/viewer.cc	Thu Sep 24 16:06:01 2009 +0900
@@ -117,7 +117,7 @@
     sgroot = new SceneGraphRoot(this->width, this->height);
     sgroot_2 = new SceneGraphRoot(this->width, this->height);
     //sgroot->createFromXMLFile(xml);
-
+    // ここの switch は application->init(this, manager, sg_no); になるべき
     switch (sg_number) {
     case 0:
     case 1:
@@ -243,8 +243,8 @@
     this->keyPtr = key;
 
     // post2runLoop は旧バージョン用なので post2speRunLoop の様なものを別につくるべき
-    task_next->set_post(post2speRunLoop, (void*)this); // set_post(function(this->run_loop()), NULL)
-    task_next->spawn();
+    //task_next->set_post(post2speRunLoop, (void*)this); // set_post(function(this->run_loop()), NULL)
+    //task_next->spawn();
     // TASK_INIT_TEXTURE が全て終わったら DUMMY_TASK が Viewer::run_loop() を呼ぶ
 
     /* test */
@@ -314,12 +314,15 @@
     update_key->add_inData(viewer->keyPtr, sizeof(key_stat));
     update_key->spawn();
 
-    HTaskPtr move_task = viewer->manager->create_task(TASK_MOVE);    
+    /* TASK_MOVE は外から引数で取ってくるべき */
+    //HTaskPtr move_task = viewer->manager->create_task(viewer->move_taskid);    
+    HTaskPtr move_task = viewer->manager->create_task(TASK_MOVE);
     //move_task->add_param(sgroot);
 
     HTaskPtr draw_task = viewer->manager->create_task(TASK_DRAW);
 
     HTaskPtr switch_task = viewer->manager->create_task(TASK_SWITCH);
+
     switch_task->wait_for(move_task);
     switch_task->wait_for(draw_task);
     move_task->spawn();
@@ -338,36 +341,6 @@
     viewer->run_move(task_next);
 }
 
-/*
-void
-Viewer::spe_run_loop()
-{
-
-    bool quit_flg;
-    quit_flg = quit_check();
-    if (quit_flg == true) {
-        this_time = get_ticks();
-        run_finish();
-        return;
-    }
-
-    clean_pixels();
-
-    for (int i = 1; i <= spackList_length; i++) {
-        spackList[i-1].reinit(i*split_screen_h);
-    }
-        
-    //run_move(task_next);
-    sgroot->updateControllerState();
-    sgroot->speExecute(width, height);
-    //sgroot->checkRemove();
-
-    // ここから下は Rendering という関数にする
-    rendering(task_next);
-
-}
-
-*/
 void
 Viewer::mainLoop()
 {
@@ -375,40 +348,8 @@
 
     task_next->set_post(&post2runLoop, (void *)this); // set_post(function(this->run_loop()), NULL)
     task_next->spawn();
-    // TASK_INIT_TEXTURE が全て終わったら DUMMY_TASK が Viewer::run_loop() を呼ぶ
 }
 
-
-/*
-static void
-post2exchange_sgroot(void *viewer_)
-{
-    Viewer *viewer = (Viewer*)viewer_;
-    HTaskPtr task_next = viewer->manager->create_task(TASK_DUMMY);
-    viewer->exchange_sgroot(task_next);
-}
-
-void
-Viewer::exchange_sgroot(TaskManager *manager)
-{
-
-    SceneGraphRootPtr tmp = sgroot;
-    sgroot = sgroot_2;
-    sgroot_2 = tmp;
-    
-}
-*/
-
-/*
-void
-Viewer::spe_run_move(HTaskPtr task_next)
-{
-    HTaskPtr move_task = manager->create_task(MOVE_TASK);
-    move_task->add_param(sgroot);
-    task_next->wait_for(move_task);
-}
-*/
-
 static void
 post2runMove(void *viewer_)
 {
@@ -600,3 +541,5 @@
     delete sgroot_2;
     quit();
 }
+
+/* end */
--- a/TaskManager/Test/test_render/viewer.h	Thu Sep 24 16:04:23 2009 +0900
+++ b/TaskManager/Test/test_render/viewer.h	Thu Sep 24 16:06:01 2009 +0900
@@ -14,6 +14,8 @@
 
     virtual ~Viewer(void) {}
 
+    //Application *application;
+
     TaskManager *manager;
     key_stat *keyPtr;