changeset 987:5eb651827ae3 akira

merge
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Sat, 02 Oct 2010 03:19:33 +0900
parents ac437c3cf766 (diff) eb704fa22d05 (current diff)
children 0b6f8c82625a
files
diffstat 31 files changed, 1631 insertions(+), 166 deletions(-) [+]
line wrap: on
line diff
--- a/Renderer/Engine/Makefile.cell	Fri Oct 01 22:01:53 2010 +0900
+++ b/Renderer/Engine/Makefile.cell	Sat Oct 02 03:19:33 2010 +0900
@@ -1,6 +1,6 @@
 include ./Makefile.def
 
-SRCS_TMP = $(wildcard *.cc) $(wildcard Application/*.cc)
+SRCS_TMP = $(wildcard *.cc) $(wildcard Application/*.cc) $(wildcard ps3fb/*.cc)
 SRCS_EXCLUDE =   # 
 SRCS = $(filter-out $(SRCS_EXCLUDE),$(SRCS_TMP))
 OBJS = $(SRCS:.cc=.o)
@@ -13,7 +13,7 @@
 
 LIBS += -lCellManager -lspe2 -lpthread
 
-CFLAGS += `sdl-config --cflags` `xml2-config --cflags`
+CFLAGS += -D__CERIUM_CELL__ -Drestrict=__restrict__ `sdl-config --cflags` `xml2-config --cflags`
 LIBS   += `sdl-config --libs` -lSDL_image -lGL `xml2-config --libs`
 
 .SUFFIXES: .cc .o
--- a/Renderer/Engine/SgChange.cc	Fri Oct 01 22:01:53 2010 +0900
+++ b/Renderer/Engine/SgChange.cc	Sat Oct 02 03:19:33 2010 +0900
@@ -24,12 +24,7 @@
 extern int frames;
 
 /* Data Pack sent to Other CPUs (ex. SPE) */
-extern SceneGraphPack *sgpack;
-extern SpanPackPtr spackList;
-extern SpanPackPtr *spackList_ptr;
-
-extern int spackList_length;
-extern int spackList_length_align;
+extern RederingData r[2];
 
 void
 SgChange::run_init()
@@ -95,15 +90,15 @@
     bool quit_flg;
     quit_flg = viewer->quit_check();
     if (quit_flg == true) {
-        this_time = viewer->get_ticks();
+        // this_time = viewer->get_ticks();
         viewer->run_finish();
         return;
     }
 
     viewer->dev->clean_pixels();
 
-    for (int i = 1; i <= spackList_length; i++) {
-        spackList[i-1].reinit(i*split_screen_h);
+    for (int i = 1; i <= r[spi].spackList_length; i++) {
+        r[spi].spackList[i-1].reinit(i*split_screen_h);
     }
 
     sgroot_A->updateControllerState();
--- a/Renderer/Engine/ViewerDevice.h	Fri Oct 01 22:01:53 2010 +0900
+++ b/Renderer/Engine/ViewerDevice.h	Sat Oct 02 03:19:33 2010 +0900
@@ -17,6 +17,7 @@
 
     /* override function */
     virtual Uint32 *video_init(TaskManager *manager, int bpp, int width, int height) = 0;
+    virtual Uint32 * flip_screen(Uint32 *v) { return v; }
     virtual void clean_pixels() = 0;
     virtual void clear_screen() = 0;
     virtual void free_device() = 0;    
--- a/Renderer/Engine/fb.h	Fri Oct 01 22:01:53 2010 +0900
+++ b/Renderer/Engine/fb.h	Sat Oct 02 03:19:33 2010 +0900
@@ -12,6 +12,7 @@
 #include <sys/ioctl.h>
 #include <stdlib.h>
 #include <iostream>
+#include "types.h"
 using namespace std;
 
 
@@ -23,7 +24,7 @@
 
 typedef struct screen_info {
 	int xres,yres,vbpp,line_len;
-	char *fbptr;
+	uint32_t *fbptr[2];
 } ScreenInfo , *ScreenInfoPtr;
 
 
--- a/Renderer/Engine/main.cc	Fri Oct 01 22:01:53 2010 +0900
+++ b/Renderer/Engine/main.cc	Sat Oct 02 03:19:33 2010 +0900
@@ -3,6 +3,7 @@
 #include "viewerSDL.h"
 #include "viewerFB.h"
 #include "viewerGL.h"
+#include "viewerPS3.h"
 #include "Application.h"
 
 /* prototype */
@@ -59,6 +60,10 @@
 		vtype = VTYPE_FB;
 	    } else if  (strcmp(argv[i+1], "gl") == 0) {
 	      vtype = VTYPE_GL;
+	    } else if  (strcmp(argv[i+1], "ps3") == 0) {
+	      vtype = VTYPE_PS3;
+	    } else if  (strcmp(argv[i+1], "sdl") == 0) {
+	      vtype = VTYPE_SDL;
 	    }
 	    i++;
 	}
@@ -76,6 +81,9 @@
 	screen = new Viewer(manager, dev, bpp, width, height, spenum);
     } else if (vtype == VTYPE_GL) {
         screen = new ViewerGL(manager, bpp, width, height, spenum);
+    } else if (vtype == VTYPE_PS3) {
+        ViewerDevice *dev = new ViewerPS3();
+	screen = new Viewer(manager, dev, bpp, width, height, spenum);
     } else {
 	ViewerDevice *dev = new ViewerSDL(manager);
 	screen = new Viewer(manager, dev, bpp, width, height, spenum);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/Engine/ps3fb/cp_fb.cc	Sat Oct 02 03:19:33 2010 +0900
@@ -0,0 +1,205 @@
+// cp_fb.c 
+//
+// Copyright (c) 2006, Mike Acton <macton@cellperformance.com>
+// 
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
+// documentation files (the "Software"), to deal in the Software without restriction, including without
+// limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial
+// portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
+// LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
+// EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+// AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
+// OR OTHER DEALINGS IN THE SOFTWARE.
+
+// NOTES:
+// From Geert Uytterhoeven 2007-01-26 04:50:44, 
+//      http://patchwork.ozlabs.org/linuxppc/patch?id=9143
+//
+//     "As the actual graphics hardware cannot be accessed directly by Linux,
+//     ps3fb uses a virtual frame buffer in main memory. The actual screen image is
+//     copied to graphics memory by the GPU on every vertical blank, by making a
+//     hypervisor call."
+//
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include <string.h>
+#include <errno.h>
+#include <stdint.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <linux/fb.h>
+#include <sys/time.h>
+#include <asm/ps3fb.h>
+#include <linux/vt.h>
+#include <linux/kd.h>
+#include "cp_fb.h"
+
+static inline const char*
+select_error_str( int existing_error, const char* const existing_error_str, int new_error, const char* const new_error_str )
+{
+  // Only report the first error found - any error that follows is probably just a cascading effect.
+  const char* error_str = (char*)( (~(intptr_t)existing_error & (intptr_t)new_error & (intptr_t)new_error_str)
+                                 |  ((intptr_t)existing_error & (intptr_t)existing_error_str) );
+
+  return (error_str);
+}
+
+int
+cp_fb_open( cp_fb* const restrict fb )
+{
+    const char*    error_str      = NULL;
+    int            error          = 0;
+
+    // Open framebuffer device
+
+    const int   fb_fd             = open( "/dev/fb0", O_RDWR );
+    const int   open_fb_error     = (fb_fd >> ((sizeof(int)<<3)-1));
+    const char* open_fb_error_str = "Could not open /dev/fb0. Check permissions.";
+  
+    error_str = select_error_str( error, error_str, open_fb_error, open_fb_error_str );
+    error     = error | open_fb_error;
+
+    // Check for vsync
+
+    struct fb_vblank vblank;
+
+    const int   get_vblank_error     = ioctl(fb_fd, FBIOGET_VBLANK, (unsigned long)&vblank);
+    const char* get_vblank_error_str = "Could not get vblank info (FBIOGET_VBLANK)";
+
+    error_str = select_error_str( error, error_str, get_vblank_error, get_vblank_error_str );
+    error     = error | get_vblank_error;
+
+    const int   has_vsync            = vblank.flags & FB_VBLANK_HAVE_VSYNC;
+    const int   has_vsync_error      = (~(-has_vsync|has_vsync))>>((sizeof(int)<<3)-1);
+    const char* has_vsync_error_str  = "No vsync available (FB_VBLANK_HAVE_VSYNC)";
+
+    error_str = select_error_str( error, error_str, has_vsync_error, has_vsync_error_str );
+    error     = error | has_vsync_error;
+
+    // Get screen resolution and frame count
+
+    struct ps3fb_ioctl_res res;
+
+    const int   screeninfo_error     = ioctl(fb_fd, PS3FB_IOCTL_SCREENINFO, (unsigned long)&res);
+    const char* screeninfo_error_str = "Could not get screen info (PS3_IOCTL_SCREENINFO)";
+
+    error_str = select_error_str( error, error_str, screeninfo_error, screeninfo_error_str );
+    error     = error | screeninfo_error;
+
+    const int   has_at_least_double_buffer           = (res.num_frames - 2) >> ((sizeof(res.num_frames)<<3)-1);
+    const int   has_at_least_double_buffer_error     = ~has_at_least_double_buffer;
+    const char* has_at_least_double_buffer_error_str = "Could not get screen info (PS3_IOCTL_SCREENINFO)";
+
+    error_str = select_error_str( error, error_str, has_at_least_double_buffer_error, has_at_least_double_buffer_error_str );
+    error     = error | has_at_least_double_buffer_error;
+
+    const uint32_t bpp                      = 4; // This is fixed for PS3 fb, and there's not a test for it.
+    const uint32_t frame_size               = res.xres * res.yres * bpp;
+    const uint32_t double_buffer_frame_size = frame_size * 2;
+
+    // const uint32_t frame_top_margin_size    = res.xres * res.yoff * bpp;
+    // const uint32_t frame_bottom_margin_size = frame_top_margin_size;
+    // const uint32_t frame_size               = frame_full_size; /* - ( frame_top_margin_size + frame_bottom_margin_size ); */
+    // const uint32_t double_buffer_frame_size = frame_size * 2;
+
+    const uintptr_t fb_addr           = (uintptr_t)mmap(NULL, double_buffer_frame_size, PROT_READ|PROT_WRITE, MAP_SHARED, fb_fd, 0);
+    const int       fb_mmap_error     = fb_addr >> ((sizeof(uintptr_t)<<3)-1);
+    const char*     fb_mmap_error_str = "Could not get mmap frame buffer";
+
+    error_str = select_error_str( error, error_str, fb_mmap_error, fb_mmap_error_str );
+    error     = error | fb_mmap_error;
+
+    // Take control of frame buffer from kernel
+    ioctl(fb_fd, PS3FB_IOCTL_ON, 0);
+
+    // yoff is the number of lines that cannot be copied to the CRT before the vblank. For the most part this represents
+    // unusable frame buffer space. While it is possible to draw to the area if you draw in the opposite frame buffer's
+    // offset space, which will (due to poor draw timing by ps3fb) be the thing that is actually drawn, it's very 
+    // difficult to work with in practice. So:
+    //
+    //     (1)  The y offset area will be treated as "off limits".
+    //     (2)  An equivalent border will be created at the bottom, so the frame looks balanced even though it is
+    //          not entirely full screen. 
+
+    // xoff is the number of lines that cannot be copied to the CRT before the hblank.
+    // Similar to the y offset space, the x offset space is displayed on the wrong (previous) line. So:
+    //
+    //     (1)  The x offset area will be treated as "off limits".
+    //     (2)  An equivalent border will be created at the right, so the frame looks balanced even though it is
+    //          not entirely full screen. 
+
+    uintptr_t draw_start_addr = fb_addr;
+    uintptr_t draw_next_addr  = draw_start_addr + ( res.yres * res.xres * bpp );
+    uintptr_t drawable_h      = res.yres - ( 2 * res.yoff );
+    uintptr_t drawable_w      = res.xres - ( 2 * res.xoff );
+
+    // xoff is the number of lines that cannot be copied to the CRT before the hblank. This area is much easier to use. 
+    // Similar to the y offset space, the x offset space is displayed on the wrong (previous) line. So:
+    // In principle, it is possible to steal back the x offset space by shifting back the line address to the 
+    // start of the border of the previous line. Like so:
+    //
+    //     (1)  One additional line will be taken from the height so the a complete horizontal line can be started
+    //          early.
+    //     (2)  The frame buffer address returned in cp_fb will be offset by (xres-xoff) in order for the remaining
+    //          space to represent a rectangular area of drawable memory.
+    //
+    //     i.e. 
+    //     uintptr_t draw_start_addr = fb_addr + ( ( res.xres - res.xoff ) * bpp );
+    //     uintptr_t draw_next_addr  = draw_start_addr + ( res.yres * res.xres * bpp );
+    //     uintptr_t drawable_h      = res.yres - 1 - ( 2 * res.yoff );
+    //     uintptr_t drawable_w      = res.xres;
+    //
+    //     But I wouldn't recommend it, since on some CRTs the effect of this would be that the frame does not appear
+    //     square.
+
+    fb->stride        = res.xres;
+    fb->w             = drawable_w;
+    fb->h             = drawable_h;
+    fb->fd            = fb_fd;
+    fb->start_addr    = fb_addr;
+    fb->size          = double_buffer_frame_size;
+    fb->draw_addr[0]  = draw_start_addr;
+    fb->draw_addr[1]  = draw_next_addr;
+
+    // Clear out the whole buffer. Any unused space is black. It's also convinient to start with a cleared frame
+    // buffer for the user.
+
+    memset((void*)fb_addr, 0x00, double_buffer_frame_size );
+
+    return (error);
+}
+
+void
+cp_fb_close( const cp_fb* const restrict fb )
+{
+    // Give frame buffer control back to the kernel
+    ioctl(fb->fd, PS3FB_IOCTL_OFF, 0);
+
+    munmap( (void*)fb->start_addr, fb->size );
+
+    close(fb->fd);
+}
+
+void
+cp_fb_wait_vsync( cp_fb* const restrict fb )
+{
+    unsigned long crt = 0;
+
+    ioctl(fb->fd, FBIO_WAITFORVSYNC, &crt );
+}
+
+void
+cp_fb_flip( cp_fb* const restrict fb, unsigned long field_ndx )
+{
+    ioctl(fb->fd, PS3FB_IOCTL_FSEL,  &field_ndx );
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/Engine/ps3fb/cp_fb.h	Sat Oct 02 03:19:33 2010 +0900
@@ -0,0 +1,51 @@
+// cp_fb.h 
+//
+// Copyright (c) 2006, Mike Acton <macton@cellperformance.com>
+// 
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
+// documentation files (the "Software"), to deal in the Software without restriction, including without
+// limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial
+// portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
+// LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
+// EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+// AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
+// OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef CP_FB_H
+#define CP_FB_H
+
+#if defined(__cplusplus)
+extern "C" 
+{
+#endif
+
+typedef struct cp_fb cp_fb;
+
+struct cp_fb
+{
+    uint32_t  w;
+    uint32_t  h;
+    uint32_t  stride;
+    uintptr_t start_addr;
+    uintptr_t draw_addr[2];
+    uint32_t  size;
+    int       fd;
+};
+
+int  cp_fb_open( cp_fb* const restrict fb );
+void cp_fb_close( const cp_fb* const restrict fb );
+void cp_fb_wait_vsync( cp_fb* const restrict fb );
+void cp_fb_flip( cp_fb* const restrict fb, unsigned long field_ndx );
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* CP_FB_H */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/Engine/ps3fb/cp_vt.cc	Sat Oct 02 03:19:33 2010 +0900
@@ -0,0 +1,287 @@
+// cp_vt.c 
+//
+// Copyright (c) 2006, Mike Acton <macton@cellperformance.com>
+// 
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
+// documentation files (the "Software"), to deal in the Software without restriction, including without
+// limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial
+// portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
+// LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
+// EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+// AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
+// OR OTHER DEALINGS IN THE SOFTWARE.
+
+// NOTES:
+// From http://www.linuxjournal.com/article/2597
+//
+//     "Console ttys are used when the keyboard and monitor are directly connected to the system without running
+//     the X Window System. Since you can have several virtual consoles, the devices are tty0 through tty63. In
+//     theory you can have 64 virtual consoles, but most people use only a few. The device /dev/console is
+//     identical to tty0 and is needed for historical reasons. If your system lets you log in on consoles 1
+//     through 6, then when you run X Windows System, X uses console 7, so you'll need /dev/tty1 through /dev/
+//     tty7 on your system. I recommend having files up through /dev/tty12. For more information on using
+//     virtual consoles, see the article Keyboards, Consoles and VT Cruising by John Fisk in the November 1996
+//     issue of Linux Journal"
+
+#include <stdio.h>
+#include <stdint.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <linux/vt.h>
+#include <linux/kd.h>
+#include "cp_vt.h"
+
+
+static inline const char*
+select_error_str( int existing_error, const char* const existing_error_str, int new_error, const char* const new_error_str )
+{
+  // Only report the first error found - any error that follows is probably just a cascading effect.
+  const char* error_str = (char*)( (~(intptr_t)existing_error & (intptr_t)new_error & (intptr_t)new_error_str)
+                                 |  ((intptr_t)existing_error & (intptr_t)existing_error_str) );
+
+  return (error_str);
+}
+
+
+int
+cp_vt_open_graphics(cp_vt* restrict vt)
+{
+  const char*    error_str      = NULL;
+  int            error          = 0;
+
+  // Open the current tty
+ 
+  // From http://tldp.org/HOWTO/Text-Terminal-HOWTO-6.html#ss6.3
+  // (An excellent overview by David S. Lawyer)
+  //
+  //     "In Linux the PC monitor is usually called the console and has several device special files associated
+  //     with it: vc/0 (tty0), vc/1 (tty1), vc/2 (tty2), etc. When you log in you are on vc/1. To go to vc/2
+  //     (on the same screen) press down the 2 keys Alt(left)-F3. For vc/3 use Left Alt-F3, etc. These (vc/1,
+  //     vc/2, vc/3, etc.) are called "virtual terminals". vc/0 (tty0) is just an alias for the current virtual
+  //     terminal and it's where messages from the system are sent. Thus messages from the system will be seen
+  //     on the console (monitor) regardless of which virtual terminal it is displaying."
+
+  const int   cur_tty                = open( "/dev/tty0", O_RDWR );
+  const int   open_cur_tty_error     = (cur_tty >> ((sizeof(int)*8)-1));
+  const char* open_cur_tty_error_str = "Could not open /dev/tty0. Check permissions.";
+  
+  error_str = select_error_str( error, error_str, open_cur_tty_error, open_cur_tty_error_str );
+  error     = error | open_cur_tty_error;
+
+  // From: http://www.linuxjournal.com/article/2783
+  // (A little out of date, but a nice primer.)
+  //
+  //     "VT_GETSTATE returns the state of all VT's in the kernel in the structure:
+  //
+  //         struct vt_stat {
+  //               ushort v_active; 
+  //               ushort v_signal; 
+  //               ushort v_state;
+  //          };
+  //
+  //      v_active        the currently active VT 
+  //      v_state         mask of all the opened VT's
+  //
+  //      v_active holds the number of the active VT (starting from 1), while v_state 
+  //      holds a mask where there is a 1 for each VT that has been opened by some process. 
+  //      Note that VT 0 is always opened in this scenario, since it refers to the current VT.
+  //
+  //      Bugs:
+  //      The v_signal member is unsupported."
+
+  struct vt_stat  vts;
+
+  const int   get_state_error     = ioctl( cur_tty, VT_GETSTATE, &vts );
+  const char* get_state_error_str = "VT_GETSTATE failed on /dev/tty0";
+
+  error_str = select_error_str( error, error_str, get_state_error, get_state_error_str );
+  error     = error | get_state_error;
+
+  vt->prev_tty_ndx = vts.v_active;
+
+  // From: http://opensolaris.org/os/project/vconsole/vt.7i.txt
+  // (Close enough to Linux and a pretty good source of documentation.)
+  //
+  // "VT_OPENQRY
+  //     This call is used to find an available VT.    The argu-
+  //     ment to the    ioctl is a pointer to an integer.  The integer
+  //     will be filled in with the number of the first avail-
+  //     able VT that no other process has open (and    hence, is
+  //     available to be opened).  If there are no available
+  //     VTs, then -1 will be filled in."
+
+  const int   open_query_error     = ioctl( cur_tty, VT_OPENQRY, &vt->tty_ndx);
+  const char* open_query_error_str = "No open ttys available";
+
+  error_str = select_error_str( error, error_str, open_query_error, open_query_error_str );
+  error     = error | open_query_error;
+
+  const int   close_cur_tty_error     = close( cur_tty );
+  const char* close_cur_tty_error_str = "Could not close parent tty";
+
+  error_str = select_error_str( error, error_str, close_cur_tty_error, close_cur_tty_error_str );
+  error     = error | close_cur_tty_error;
+
+  char tty_file_name[11];
+
+  (void)snprintf( tty_file_name, 11, "/dev/tty%d", vt->tty_ndx );
+
+  const int   tty                = open( tty_file_name, O_RDWR );
+  const int   open_tty_error     = (cur_tty >> ((sizeof(int)*8)-1));
+  const char* open_tty_error_str = "Could not open tty";
+
+  error_str = select_error_str( error, error_str, open_tty_error, open_tty_error_str );
+  error     = error | open_tty_error;
+
+  vt->tty = tty;
+
+  // From: http://opensolaris.org/os/project/vconsole/vt.7i.txt
+  // (Close enough to Linux and a pretty good source of documentation.)
+  //
+  // "VT_ACTIVATE
+  //    This call has the effect of making the VT specified in
+  //    the argument the active VT. The VT manager will cause
+  //    a switch to occur in the same manner as if a hotkey had
+  //    initiated the switch.  If the specified VT is not open
+  //    or does not exist the call will fail and errno will be
+  //    set to ENXIO."
+  //
+  // "VT_WAITACTIVE
+  //    If the specified VT is already active, this call
+  //    returns immediately. Otherwise, it will sleep until
+  //    the specified VT becomes active, at which point it will
+  //    return."
+
+
+  const int   activate_tty_error     = ioctl( vt->tty, VT_ACTIVATE, vt->tty_ndx );
+  const char* activate_tty_error_str = "Could not activate tty";
+
+  error_str = select_error_str( error, error_str, activate_tty_error, activate_tty_error_str );
+  error     = error | activate_tty_error;
+
+#if 0
+  const int   waitactive_tty_error     = ioctl( vt->tty, VT_WAITACTIVE, vt->tty_ndx );
+  const char* waitactive_tty_error_str = "Could not switch to tty";
+
+  error_str = select_error_str( error, error_str, waitactive_tty_error, waitactive_tty_error_str );
+  error     = error | waitactive_tty_error;
+#endif
+
+  // From: http://opensolaris.org/os/project/vconsole/vt.7i.txt
+  // (Close enough to Linux and a pretty good source of documentation.)
+  //
+  //  "KDSETMODE
+  //   This call is used to set the text/graphics mode to the VT.
+  //
+  //      KD_TEXT indicates that console text will be displayed on the screen
+  //      with this VT. Normally KD_TEXT is combined with VT_AUTO mode for
+  //      text console terminals, so that the console text display will
+  //      automatically be saved and restored on the hot key screen switches.
+  //
+  //      KD_GRAPHICS indicates that the user/application, usually Xserver,
+  //      will have direct control of the display for this VT in graphics
+  //      mode. Normally KD_GRAPHICS is combined with VT_PROCESS mode for
+  //      this VT indicating direct control of the display in graphics mode.
+  //      In this mode, all writes to this VT using the write system call are
+  //      ignored, and the user is responsible for saving and restoring the
+  //      display on the hot key screen switches."
+
+  // Save the current VT mode. This is most likely KD_TEXT.
+
+  const int   kdgetmode_error     = ioctl( vt->tty, KDGETMODE, &vt->prev_kdmode );
+  const char* kdgetmode_error_str = "Could not get mode for tty";
+
+  error_str = select_error_str( error, error_str, kdgetmode_error, kdgetmode_error_str );
+  error     = error | kdgetmode_error;
+  
+  // Set VT to GRAPHICS (user draw) mode
+
+  const int   kdsetmode_graphics_error     = ioctl( vt->tty, KDSETMODE, KD_GRAPHICS );
+  const char* kdsetmode_graphics_error_str = "Could not set graphics mode for tty";
+
+  error_str = select_error_str( error, error_str, kdsetmode_graphics_error, kdsetmode_graphics_error_str );
+  error     = error | kdsetmode_graphics_error;
+
+  //
+  // Not bothering with VT_PROCESS, VT_AUTO is fine for our purposes.
+  //
+ 
+  // If vt blanking is active, for example when running this program from a remote terminal, 
+  // setting KD_GRAPHICS will not disable the blanking. Reset to KD_TEXT from KD_GRAPHICS will
+  // force disable blanking. Then return to KD_GRAPHICS for drawing.
+  //
+  // Note: KD_TEXT (default) to KD_TEXT will do nothing, so blanking will not be disable unless
+  // the mode is changing. i.e. the initial set to KD_GRAPHICS above is useful.
+
+  const int   kdsetmode_text_error     = ioctl( vt->tty, KDSETMODE, KD_TEXT );
+  const char* kdsetmode_text_error_str = "Could not set text mode for tty";
+
+  error_str = select_error_str( error, error_str, kdsetmode_text_error, kdsetmode_text_error_str );
+  error     = error | kdsetmode_text_error;
+
+  const int   kdsetmode_graphics_reset_error     = ioctl( vt->tty, KDSETMODE, KD_GRAPHICS );
+  const char* kdsetmode_graphics_reset_error_str = "Could not reset graphics mode for tty";
+
+  error_str = select_error_str( error, error_str, kdsetmode_graphics_reset_error, kdsetmode_graphics_reset_error_str );
+  error     = error | kdsetmode_graphics_reset_error;
+
+  if ( error == -1 )
+  {
+      printf("ERROR: vt_graphics_open: %s\n",error_str);
+      return (-1);
+  }
+
+  return (0);
+}
+
+int
+cp_vt_close(cp_vt* restrict vt)
+{
+  const char*    error_str      = NULL;
+  int            error          = 0;
+
+  // Reset previous mode on tty (likely KD_TEXT)
+
+  const int   kdsetmode_error     = ioctl( vt->tty, KDSETMODE, vt->prev_kdmode );
+  const char* kdsetmode_error_str = "Could not reset previous mode for tty";
+
+  error_str = select_error_str( error, error_str, kdsetmode_error, kdsetmode_error_str );
+  error     = error | kdsetmode_error;
+
+  // Restore previous tty
+
+  const int   activate_tty_error     = ioctl( vt->tty, VT_ACTIVATE, vt->prev_tty_ndx );
+  const char* activate_tty_error_str = "Could not activate previous tty";
+
+  error_str = select_error_str( error, error_str, activate_tty_error, activate_tty_error_str );
+  error     = error | activate_tty_error;
+
+  const int   waitactive_tty_error     = ioctl( vt->tty, VT_WAITACTIVE, vt->prev_tty_ndx );
+  const char* waitactive_tty_error_str = "Could not switch to previous tty";
+
+  error_str = select_error_str( error, error_str, waitactive_tty_error, waitactive_tty_error_str );
+  error     = error | waitactive_tty_error;
+
+  // Close tty
+
+  const int   close_tty_error     = close( vt->tty );
+  const char* close_tty_error_str = "Could not close tty";
+
+  error_str = select_error_str( error, error_str, close_tty_error, close_tty_error_str );
+  error     = error | close_tty_error;
+
+  if ( error == -1 )
+  {
+      printf("ERROR: vt_close: %s\n",error_str);
+      return (-1);
+  }
+
+  return (0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/Engine/ps3fb/cp_vt.h	Sat Oct 02 03:19:33 2010 +0900
@@ -0,0 +1,45 @@
+// cp_vt.h 
+//
+// Copyright (c) 2006, Mike Acton <macton@cellperformance.com>
+// 
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
+// documentation files (the "Software"), to deal in the Software without restriction, including without
+// limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial
+// portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
+// LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
+// EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+// AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
+// OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef CP_VT_H
+#define CP_VT_H
+
+#if defined(__cplusplus)
+extern "C" 
+{
+#endif
+
+typedef struct cp_vt cp_vt;
+
+struct cp_vt
+{
+    int prev_tty_ndx;
+    int prev_kdmode;
+    int tty;
+    int tty_ndx;
+};
+
+int cp_vt_open_graphics(cp_vt* restrict vt);
+int cp_vt_close(cp_vt* restrict vt);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
--- a/Renderer/Engine/spe/DataAllocate.cc	Fri Oct 01 22:01:53 2010 +0900
+++ b/Renderer/Engine/spe/DataAllocate.cc	Sat Oct 02 03:19:33 2010 +0900
@@ -10,14 +10,16 @@
 run(SchedTask *s, void *rbuf, void *wbuf)
 {
 
-  void *idata = s->get_input(rbuf, 0);
-  long size = (long)s->get_param(0);
-  long load_id = (long)s->get_param(1);
+  int count = (int)s->get_input(rbuf, 0);
+  for(int i=0;i<count;i++) {
+      void *idata = s->get_input(rbuf, i);
+      long size = (long)s->get_param(i*2+1);
+      long load_id = (long)s->get_param(i*2+2);
 
-  void *buff = s->global_alloc(load_id, size);
-
-  if (idata != NULL) {
-    memcpy(buff,idata,size);
+      void *buff = s->global_alloc(load_id, size);
+      if (idata != NULL) {
+	memcpy(buff,idata,size);
+      }
   }
 
   return 0;
--- a/Renderer/Engine/spe/DataUpdate.cc	Fri Oct 01 22:01:53 2010 +0900
+++ b/Renderer/Engine/spe/DataUpdate.cc	Sat Oct 02 03:19:33 2010 +0900
@@ -10,12 +10,14 @@
 run(SchedTask *s, void *rbuf, void *wbuf)
 {
 
-  void *idata = (void*)s->get_input(rbuf, 0);
-  long size = (long)s->get_param(0);
-  long load_id = (long)s->get_param(1);
-  void *global_data = (void*)s->global_get(load_id);
-
-  memcpy(global_data,idata,size);
+  long count = (long)s->get_param(0);
+  long id_base = (long)s->get_param(1);
+  for(int i=0; i<count; i++) {
+      void *idata = (void*)s->get_input(rbuf, i);
+      long size = (long)s->get_inputSize(i);
+      void *global_data = (void*)s->global_get(id_base+i);
+      memcpy(global_data,idata,size);
+  }
 
   return 0;
 }
--- a/Renderer/Engine/spe/Load_Texture.cc	Fri Oct 01 22:01:53 2010 +0900
+++ b/Renderer/Engine/spe/Load_Texture.cc	Sat Oct 02 03:19:33 2010 +0900
@@ -21,7 +21,7 @@
     MemList *ml = smanager->createMemList(sizeof(uint32) * TEXTURE_BLOCK_SIZE, MAX_TILE);
     smanager->global_set(GLOBAL_TILE_LIST, (void *)ml);
 
-    smanager->printf("%d\n",GLOBAL_TILE_LIST);
+    // smanager->printf("%d\n",GLOBAL_TILE_LIST);
 
     return 0;
 }
--- a/Renderer/Engine/task/DataAllocate.cc	Fri Oct 01 22:01:53 2010 +0900
+++ b/Renderer/Engine/task/DataAllocate.cc	Sat Oct 02 03:19:33 2010 +0900
@@ -10,15 +10,17 @@
 run(SchedTask *s, void *rbuf, void *wbuf)
 {
 
-  long size = (long)s->get_param(0);
-  long load_id = (long)s->get_param(1);
-
-  //printf("size %d",sizeof(float)*length);
+  int count = (int)s->get_input(rbuf, 0);
+  for(int i=0;i<count;i++) {
+      void *idata = s->get_input(rbuf, i);
+      long size = (long)s->get_param(i*2+1);
+      long load_id = (long)s->get_param(i*2+2);
 
-  s->global_alloc(load_id, size);
-
-  //MemList *ml = s->createMemList(length,length);
-  //s->global_set(load_id, (void *)ml);
+      void *buff = s->global_alloc(load_id, size);
+      if (idata != NULL) {
+	memcpy(buff,idata,size);
+      }
+  }
 
   return 0;
 }
--- a/Renderer/Engine/task/DataUpdate.cc	Fri Oct 01 22:01:53 2010 +0900
+++ b/Renderer/Engine/task/DataUpdate.cc	Sat Oct 02 03:19:33 2010 +0900
@@ -9,12 +9,15 @@
 static int
 run(SchedTask *s, void *rbuf, void *wbuf)
 {
-  void *idata = (void*)s->get_input(rbuf, 0);
-  long size = (long)s->get_param(0);
-  long load_id = (long)s->get_param(1);
-  void *global_data = (void*)s->global_get(load_id);
-  
-  memcpy(global_data,idata,size);
+
+  long count = (long)s->get_param(0);
+  long id_base = (long)s->get_param(1);
+  for(int i=0; i<count; i++) {
+      void *idata = (void*)s->get_input(rbuf, i);
+      long size = (long)s->get_inputSize(i);
+      void *global_data = (void*)s->global_get(id_base+i);
+      memcpy(global_data,idata,size);
+  }
 
   return 0;
 }
--- a/Renderer/Engine/viewer.cc	Fri Oct 01 22:01:53 2010 +0900
+++ b/Renderer/Engine/viewer.cc	Sat Oct 02 03:19:33 2010 +0900
@@ -20,8 +20,8 @@
 static void post2runMoveDrawLoop(SchedTask *s,void *viewer,void *s1);
 
 /* measure for FPS (Frame Per Second) */
-int start_time;
-int this_time;
+static int start_time;
+static int this_time;
 int frames;
 // static void post2speRunLoop(void *viewer);
 //static void post2runMove(void *viewer);
@@ -31,14 +31,10 @@
 //SceneGraphRootPtr sgroot_2;
 
 /* Data Pack sent to Other CPUs (ex. SPE) */
-SceneGraphPack *sgpack;
-PolygonPack *ppack;
-SpanPackPtr spackList;
-SpanPackPtr *spackList_ptr;
 
-int spackList_length;
-int spackList_length_align;
+RederingData r[2];
 
+int  ppi, spi;
 
 /**
  *
@@ -98,10 +94,6 @@
 {
     this->manager = manager;
 
-    start_time = get_ticks();
-    this_time  = 0;
-    frames     = 0;
-
     if (spe_num == 0) spe_num = 1;
 
     sgroot = new SceneGraphRoot(this->width, this->height);
@@ -121,29 +113,24 @@
 
 
     for(int i = 0; i < spe_num; i++) {
-
-      HTaskPtr data_load = manager->create_task(DataAllocate);
-	data_load->set_param(0,(memaddr)size);
-	data_load->set_param(1,(memaddr)Light);
+        HTaskPtr data_load = manager->create_task(DataAllocate);
+	data_load->set_param(0,(memaddr)3);                         // num of allocate block
+	data_load->set_param(0,(memaddr)(sizeof(float)*4*light_num)); // 1st allocate size
+	data_load->set_param(1,(memaddr)Light);                     // 1st id
+	data_load->set_param(0,(memaddr)(light_num * sizeof(int)));   // 2nd size
+	data_load->set_param(1,(memaddr)LightSwitch);               // 2nd id
+	data_load->set_param(0,(memaddr)16);                        // 3rd size
+	data_load->set_param(1,(memaddr)LightSysSwitch);            // 3rd id
 	data_load->set_cpu((CPU_TYPE)((int)SPE_0 + i));
 	data_load->spawn();
     }
 
-    size = light_num * sizeof(int);
     light_switch = (int*)manager->allocate(size);
 
     for (int i = 0; i < light_num; i++) {
         light_switch[i] = 0;
     }
 
-    for(int i = 0; i < spe_num; i++) {
-	HTaskPtr data_load = manager->create_task(DataAllocate);
-	data_load->set_param(0,(memaddr)size);
-	data_load->set_param(1,(memaddr)LightSwitch);
-	data_load->set_cpu((CPU_TYPE)((int)SPE_0 + i));
-	data_load->spawn();
-    }
-
     size = 16; // LightSysSwitch は 4byte. 残り 12byte は DMA転送の為のパディング
 
     light_sysswitch = (int*)manager->allocate(size);
@@ -152,14 +139,10 @@
       light_sysswitch[i] = 0;
     }
 
-    for(int i = 0; i < spe_num; i++) {
-	HTaskPtr data_load = manager->create_task(DataAllocate);
-	data_load->set_param(0,(memaddr)size);
-	data_load->set_param(1,(memaddr)LightSysSwitch);
-	data_load->set_cpu((CPU_TYPE)((int)SPE_0 + i));
-	data_load->spawn();
-    }
-    
+    start_time = get_ticks();
+    this_time  = 0;
+    frames     = 0;
+
     MainLoop *mainloop = app->init(this, this->width, this->height);
     mainloop->mainLoop();
 }
@@ -171,43 +154,43 @@
     HTaskPtr task_next;
     HTaskPtr task_tex;
 
-    sgpack = (SceneGraphPack*)manager->allocate(sizeof(SceneGraphPack));
-    sgpack->init();
-    ppack  = (PolygonPack*)manager->allocate(sizeof(PolygonPack));
+    for(int i=0;i<2;i++) {
+	r[i].ppack  = (PolygonPack*)manager->allocate(sizeof(PolygonPack));
 
-    spackList_length = (this->height + split_screen_h - 1) / split_screen_h;
-    spackList = (SpanPack*)manager->allocate(sizeof(SpanPack)*spackList_length);
-    // printf("spackList %0lx height %d\n",(unsigned long)spackList, this->height);
+	r[i].spackList_length = (this->height + split_screen_h - 1) / split_screen_h;
+	r[i].spackList = (SpanPack*)manager->allocate(sizeof(SpanPack)*r[i].spackList_length);
+	// printf("spackList %0lx height %d\n",(unsigned long)r[i].spackList, this->height);
 
-    /**
-     * SPU に送る address list は 16 バイト倍数でないといけない。
-     * spackList_length*sizeof(SpanPack*) が 16 バイト倍数になるような
-     * length_align を求めている。はみ出した部分は使われない
-     * (ex) spackList_length が 13 の場合
-     *   spackList_length_align = 16;
-     *     実際に送るデータは64バイトになるのでOK
-     *     14,15,16 の部分は何も入らない。
-     */
-    spackList_length_align = (spackList_length + 3)&(~3);
+	/**
+	 * SPU に送る address list は 16 バイト倍数でないといけない。
+	 * spackList_length*sizeof(SpanPack*) が 16 バイト倍数になるような
+	 * length_align を求めている。はみ出した部分は使われない
+	 * (ex) spackList_length が 13 の場合
+	 *   spackList_length_align = 16;
+	 *     実際に送るデータは64バイトになるのでOK
+	 *     14,15,16 の部分は何も入らない。
+	 */
+	r[i].spackList_length_align = (r[i].spackList_length + 3)&(~3);
 
-    /* 各 SPU が持つ、SpanPack の address list */
-    spackList_ptr =
-        (SpanPack**)manager->allocate(sizeof(SpanPack*)*spackList_length_align);
+	/* 各 SPU が持つ、SpanPack の address list */
+	r[i].spackList_ptr =
+	    (SpanPack**)manager->allocate(sizeof(SpanPack*)*r[i].spackList_length_align);
 
-    for (int i = 0; i < spackList_length; i++) {
-        spackList_ptr[i] = &spackList[i];
-    }
+	for (int j = 0; i < r[i].spackList_length; i++) {
+	    r[i].spackList_ptr[j] = &r[i].spackList[j];
+	}
 
-    for (int i = 1; i <= spackList_length; i++) {
-        spackList[i-1].init(i*split_screen_h);
+	for (int j = 1; j <= r[i].spackList_length; i++) {
+	    r[i].spackList[j-1].init(j*split_screen_h);
+	}
     }
 
     task_next = manager->create_task(Dummy,0,0,0,0);
     
     // ここは、Iterator を用意するべきだよね
-    for (int i = 0; i < spe_num; i++) {
+    for (int j = 0; j < spe_num; j++) {
         task_tex = manager->create_task(LoadTexture,0,0,0,0);
-        task_tex->set_cpu((CPU_TYPE)((int)SPE_0 + i));
+        task_tex->set_cpu((CPU_TYPE)((int)SPE_0 + j));
         task_next->wait_for(task_tex);
 	task_tex->spawn();	
     }
@@ -327,10 +310,7 @@
     }
 
     dev->clean_pixels();
-
-    for (int i = 1; i <= spackList_length; i++) {
-        spackList[i-1].reinit(i*split_screen_h);
-    }
+    pixels = dev->flip_screen(pixels);
 
     /* ここでGameTaskの終了を待つTaskを生成しておく */
     sgroot->wait_game_task = manager->create_task(Dummy,0,0,0,0);
@@ -710,7 +690,7 @@
     // SceneGraph(木構造) -> PolygonPack
 
     task_create_pp->set_param(0,(memaddr)sgroot->getDrawSceneGraph());
-    task_create_pp->set_param(1,(memaddr)ppack);
+    task_create_pp->set_param(1,(memaddr)r[ppi].ppack);
     /* GameTaskの終了を待ってからポリゴンを作る */
     task_create_pp->wait_for(game_task);
 
@@ -721,12 +701,12 @@
     int  range_base = spe_num;
 
     // 切り上げのつもり
-    int range = (spackList_length + range_base - 1) / range_base;
+    int range = (r[spi].spackList_length + range_base - 1) / range_base;
 
     for (int i = 0; i < range_base; i++) {
         int index_start = range*i;
-        int index_end = (index_start + range >= spackList_length)
-            ? spackList_length : index_start + range;
+        int index_end = (index_start + range >= r[spi].spackList_length)
+            ? r[spi].spackList_length : index_start + range;
 
 	HTaskPtr task_create_sp = manager->create_task(CreateSpan);
 
@@ -745,10 +725,10 @@
         task_create_sp->set_param(1,index_start*split_screen_h + 1);
         task_create_sp->set_param(2,index_end*split_screen_h);
 
-        task_create_sp->add_inData(ppack, sizeof(PolygonPack));
-        task_create_sp->add_inData(spackList_ptr,
-                                   sizeof(SpanPack*)*spackList_length_align);
-        task_create_sp->add_inData(&spackList[index_start], sizeof(SpanPack));
+        task_create_sp->add_inData(r[ppi].ppack, sizeof(PolygonPack));
+        task_create_sp->add_inData(r[spi].spackList_ptr,
+                                   sizeof(SpanPack*)*r[spi].spackList_length_align);
+        task_create_sp->add_inData(&r[spi].spackList[index_start], sizeof(SpanPack));
 
         task_next->wait_for(task_create_sp);
         task_create_sp->wait_for(task_create_pp);
@@ -761,24 +741,6 @@
     game_task->spawn();
 }
 
-HTaskPtr
-Viewer::update_task_create(void *data, int size, 
-			   int load_id, int spe_id, HTaskPtr wait)
-{
-
-	HTaskPtr data_update = manager->create_task(DataUpdate);
-	data_update->add_inData(data,size);
-	data_update->set_param(0,size);
-	data_update->set_param(1,load_id);
-	data_update->set_cpu((CPU_TYPE)(spe_id));
-	if (wait != NULL) {
-	  wait->wait_for(data_update);
-	}
-	data_update->spawn();
-
-	return data_update;
-
-}
 
 void
 Viewer::common_draw(HTaskPtr task_next)
@@ -789,8 +751,6 @@
 
     //Light info update
                                                                    
-    //HTaskPtr data_update;
-    HTaskPtr data_update_wait;
     int light_num = 4;
     int size = sizeof(float)*4*light_num; //xyz+alpha(4) * light_num(4) 
     int light_size = size / sizeof(float);
@@ -804,33 +764,25 @@
     }
 
     light_sysswitch[0] = light_sysswitch_stock;
- 
-    data_update_wait = manager->create_task(DataUpdate);
-    data_update_wait->add_inData(light_xyz,size);
-    data_update_wait->set_param(0,size);
-    data_update_wait->set_param(1,Light);
-    data_update_wait->set_cpu((CPU_TYPE)((int)SPE_0));
-      
-    for (int i = 1; i < spe_num; i++) {
-      update_task_create(light_xyz,size,Light,(int)SPE_0+i,data_update_wait);
+
+
+    HTask *data_update_wait = 0;
+    for (int i = 0; i < spe_num; i++) {
+	data_update_wait = manager->create_task(DataUpdate);
+	data_update_wait->set_param(0,3);
+	data_update_wait->set_param(1,Light);              // GlobalSet ID base
+	data_update_wait->set_inData(0,light_xyz,size);                           // Light
+	data_update_wait->set_inData(1,light_switch,light_num * sizeof(int));     // LightSwitch = Light+1
+	data_update_wait->set_inData(2,light_sysswitch,16);                       // LightSysSwitch = Light+2
+        data_update_wait->set_cpu((CPU_TYPE)(SPE_0+i));
+	data_update_wait->spawn();
     }
 
-    size = light_num * sizeof(int);
-
-    for (int i = 0; i < spe_num; i++) {
-      update_task_create(light_switch,size,LightSwitch,(int)SPE_0+i,data_update_wait);
-    }
-
-    size = 16; // LightSysSwitch は 4byte. 残り 12byte は DMA転送の為のパディング
+    ppi ^= 1; 
+    r[ppi].ppack->clear();
 
-    for (int i = 0; i < spe_num; i++) {
-      update_task_create(light_sysswitch,size,LightSysSwitch,(int)SPE_0+i,data_update_wait);
-    }
-    
-    ppack->clear();
-
-    for (int i = 0; i < spackList_length; i++) {
-        SpanPack *spack = &spackList[i];
+    for (int i = 0; i < r[spi].spackList_length; i++) {
+        SpanPack *spack = &r[spi].spackList[i];
         int startx = 1;
         int endx = split_screen_w;
 
@@ -880,7 +832,6 @@
 	  task_draw_array->spawn_task_array(task_draw->next());
 	  task_draw_array->set_cpu(SPE_ANY);
 	  task_next->wait_for(task_draw_array);
-	  task_draw_array->wait_for(data_update_wait);
 	  task_draw_array->spawn();
 
 	  
@@ -929,7 +880,6 @@
 
 	    task_draw->set_cpu(SPE_ANY);
             task_next->wait_for(task_draw);
-	    task_draw->wait_for(data_update_wait);
             task_draw->spawn();
 
             startx += split_screen_w;
@@ -942,14 +892,22 @@
 #endif
 
     } 
+    spi ^= 1; 
+    for (int i = 1; i <= r[spi].spackList_length; i++) {
+        r[spi].spackList[i-1].reinit(i*split_screen_h);
+    }
 
-    data_update_wait->spawn();  
+
     if (profile) {
-	if (frames % 1000 == 999) {
-	    manager->show_profile();
+	if (frames % 50 == 49) {
+	   manager->show_profile();
+           this_time = get_ticks();
+           if (this_time != start_time) {
+              printf("\n%f FPS\n", ((((float)frames)*1000.0)/(this_time-start_time)));
+              start_time = this_time; frames = 0;
+           }
         }
     }
-
 }
 
 void
--- a/Renderer/Engine/viewer.h	Fri Oct 01 22:01:53 2010 +0900
+++ b/Renderer/Engine/viewer.h	Sat Oct 02 03:19:33 2010 +0900
@@ -16,6 +16,19 @@
 
 class Application;
 
+typedef struct rendering_data {
+    PolygonPack *ppack;
+    SpanPackPtr spackList;
+    SpanPackPtr *spackList_ptr;
+
+    int spackList_length;
+    int spackList_length_align;
+} RederingData ;
+
+extern RederingData r[2];
+
+extern int  ppi, spi;
+
 class Viewer : public MainLoop {
 
 public:
--- a/Renderer/Engine/viewerFB.cc	Fri Oct 01 22:01:53 2010 +0900
+++ b/Renderer/Engine/viewerFB.cc	Sat Oct 02 03:19:33 2010 +0900
@@ -1,6 +1,10 @@
 #include "viewerFB.h"
 #include "fb.h"
 #include <stdio.h>
+#if 0
+#include <asm/ps3fb.h>
+#endif
+
 
 #define default_sdl_flag SDL_INIT_TIMER | SDL_INIT_JOYSTICK
 
@@ -65,12 +69,20 @@
 	}
 	send_current_information("The framebuffer device was mapped !");
 
+#if 0
+    // Take control of frame buffer from kernel
+    ioctl(fd_framebuffer, PS3FB_IOCTL_ON, 0);
+    int field_ndx = 0;
+    ioctl(fd_framebuffer , PS3FB_IOCTL_FSEL,  &field_ndx );
+#endif
+
+
 	printf("fb: 0x%x \n", (unsigned int)fbptr);
 	info.xres = xres;
         info.yres = yres; 
         info.vbpp = vbpp;
         info.line_len = line_len;
-	info.fbptr = fbptr;
+	info.fbptr[0] = (uint32_t *)fbptr;
       
 	return info;
 	//munmap(fbptr,screensize);
@@ -107,7 +119,7 @@
     }
 
     screen_info = get_fbdev_addr();
-    Uint32 *pixels = (Uint32*) screen_info.fbptr;
+    Uint32 *pixels = screen_info.fbptr[0];
 
     if (pixels == 0) {
 	fprintf(stderr, "Cannot get frame buffer!\n");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/Engine/viewerPS3.cc	Sat Oct 02 03:19:33 2010 +0900
@@ -0,0 +1,100 @@
+#include "viewerPS3.h"
+#include "fb.h"
+#include "types.h"
+#include "ps3fb/cp_vt.h"
+#include "ps3fb/cp_fb.h"
+#include <stdio.h>
+
+#define default_sdl_flag SDL_INIT_TIMER | SDL_INIT_JOYSTICK
+
+ViewerPS3::ViewerPS3() {}
+ViewerPS3::~ViewerPS3() {}
+
+#if defined(__linux__)
+
+#define DEVICE_NAME "/dev/fb0"
+#define DIV_BYTE 8
+
+ScreenInfo 
+ViewerPS3::get_fbdev_addr()
+{
+    ScreenInfo info;
+
+    cp_vt_open_graphics(&vt);
+    cp_fb_open(&fb);
+
+    info.xres = fb.w;
+    info.yres = fb.h; 
+    info.vbpp = 32;
+    info.fbptr[0] = (uint32_t *)fb.draw_addr[ 0 ];
+    info.fbptr[1] = (uint32_t *)fb.draw_addr[ 1 ];
+
+    return info;
+}
+
+#else /* !defined(__linux__) */
+ScreenInfo get_fbdev_addr(void) { 
+    ScreenInfo tmp = {0,0,0,0};
+    return tmp;
+}
+#endif /* defined(__linux__) */
+
+
+Uint32 *
+ViewerPS3::video_init(TaskManager *manager, int bpp, int width, int height)
+{
+    // Uint32 sdl_flag = default_sdl_flag |  SDL_INIT_VIDEO;
+    Uint32 sdl_flag = default_sdl_flag ;
+
+    if (SDL_Init(sdl_flag) < 0) {
+	fprintf(stderr,"Couldn't initialize SDL: %s\n",SDL_GetError());
+	exit(1);
+    }
+
+    screen_info = get_fbdev_addr();
+
+    uint32_t *pixels =  screen_info.fbptr[frame_ndx];
+
+    if (pixels == 0) {
+	fprintf(stderr, "Cannot get frame buffer!\n");
+    	pixels = (new Uint32[width*height*32/8]);
+    }
+    this->width = screen_info.xres;
+    this->height = screen_info.yres;
+    this->bpp = screen_info.vbpp;
+
+    return pixels;
+}
+
+void
+ViewerPS3::clean_pixels()
+{
+}
+
+void
+ViewerPS3::clear_screen()
+{
+}
+
+uint32_t *
+ViewerPS3::flip_screen(uint32_t *old)
+{
+        // At the vsync, the previous frame is finished sending to the CRT
+        // cp_fb_wait_vsync( &fb );
+
+        // Send the frame just drawn to the CRT by the next vblank
+        cp_fb_flip( &fb, frame_ndx );
+
+        frame_ndx  = frame_ndx ^ 0x01;
+	return (uint32_t*)fb.draw_addr[ frame_ndx ];
+}
+
+
+void
+ViewerPS3::free_device()
+{
+    cp_vt_close(&vt);
+    cp_fb_close(&fb);
+}
+
+/* end */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/Engine/viewerPS3.h	Sat Oct 02 03:19:33 2010 +0900
@@ -0,0 +1,33 @@
+#ifndef INCLUDED_VIEWER_PS3
+#define INCLUDED_VIEWER_PS3
+
+#include "fb.h"
+#include "types.h"
+#include "ps3fb/cp_vt.h"
+#include "ps3fb/cp_fb.h"
+
+#include "ViewerDevice.h"
+
+class ViewerPS3 : public ViewerDevice {
+public:
+    ViewerPS3(TaskManager *manager) {};
+    ViewerPS3();
+    virtual ~ViewerPS3();
+
+    ScreenInfo screen_info ;
+    cp_vt vt;
+    cp_fb fb;
+    uint32_t frame_ndx;
+
+    ScreenInfo get_fbdev_addr();
+
+    /* override function */
+    uint32_t *video_init(TaskManager *manager, int bpp, int width, int height);
+    void clean_pixels(void);
+    void clear_screen();
+    void free_device();
+    uint32_t* flip_screen(uint32_t *);
+
+};
+
+#endif
--- a/Renderer/Engine/viewerSDL.cc	Fri Oct 01 22:01:53 2010 +0900
+++ b/Renderer/Engine/viewerSDL.cc	Sat Oct 02 03:19:33 2010 +0900
@@ -3,6 +3,8 @@
 #include "TaskManager.h"
 #include "viewer_types.h"
 
+#define UGA 1
+
 extern void post2runLoop(void *);
 
 #define default_sdl_flag SDL_INIT_TIMER | SDL_INIT_JOYSTICK
@@ -21,7 +23,7 @@
 	exit(1);
     }
 
-    screen = SDL_SetVideoMode(width, height, bpp, SDL_SWSURFACE);
+    screen = SDL_SetVideoMode(width, height, bpp, SDL_HWSURFACE);
     if (screen == NULL) {
 	fprintf(stderr, "Couldn't set GL mode: %s\n", SDL_GetError());
 	SDL_Quit();
@@ -45,14 +47,28 @@
 ViewerSDL::clean_pixels()
 {
     //bzero(pixels, sizeof(int)*width*height);
+#if !UGA
     SDL_FillRect(screen,NULL,SDL_MapRGB(screen->format,0,0,0));
+#endif
 }
 
 void
 ViewerSDL::clear_screen()
 {
+#if !UGA
     SDL_BlitSurface(bitmap, NULL, screen, NULL);
     SDL_UpdateRect(screen, 0, 0, 0, 0);        
+#endif
+}
+
+uint32_t *
+ViewerSDL::flip_screen(uint32_t *old)
+{
+#if UGA
+    SDL_BlitSurface(bitmap,NULL,screen,NULL);
+    SDL_UpdateRect(screen,0,0,0,0);
+#endif
+    return old;
 }
 
 void
--- a/Renderer/Engine/viewerSDL.h	Fri Oct 01 22:01:53 2010 +0900
+++ b/Renderer/Engine/viewerSDL.h	Sat Oct 02 03:19:33 2010 +0900
@@ -17,6 +17,8 @@
     void clean_pixels();
     void clear_screen();
     void free_device();
+    uint32_t* flip_screen(uint32_t *);
+
 };
 
 #endif
--- a/Renderer/Engine/viewer_types.h	Fri Oct 01 22:01:53 2010 +0900
+++ b/Renderer/Engine/viewer_types.h	Sat Oct 02 03:19:33 2010 +0900
@@ -13,6 +13,7 @@
 enum video_type {
     VTYPE_SDL,
     VTYPE_FB,
+    VTYPE_PS3,
     VTYPE_GL
 };
 
--- a/Renderer/Test/Makefile.cell	Fri Oct 01 22:01:53 2010 +0900
+++ b/Renderer/Test/Makefile.cell	Sat Oct 02 03:19:33 2010 +0900
@@ -14,7 +14,7 @@
 %.pb.cc: $(PROTODIR)/%.proto
 	$(PROTO) $(PROTOFLAGS) $<
 
-ALL = spe-main ball_bound boss1_action direction gaplant ieshoot node panel universe untitled vacuum dynamic viewer SgRootChange property_test create_task property_universe chain_old property_chain aquarium init_aquarium
+ALL = spe-main ball_bound boss1_action direction gaplant ieshoot node panel universe untitled vacuum dynamic viewer SgRootChange property_test create_task property_universe chain_old property_chain aquarium network init_aquarium 
 
 all: $(ALL)
 
@@ -108,6 +108,10 @@
 aquarium : $(AQUARIUM_OBJ)
 	$(CC) -o $@ $?    $(LIBS) $(PROTOLIBS)
 
+NETWORK_OBJ = network_game.pb.o network.o
+network : $(NETWORK_OBJ)
+	$(CC) -o $@ $?    $(LIBS) $(PROTOLIBS)
+
 INIT_AQUARIUM_OBJ = aquarium.pb.o init_aquarium.o
 init_aquarium : $(INIT_AQUARIUM_OBJ)
 	$(CC) -o $@ $? $(LIBS) $(PROTOLIBS)
--- a/Renderer/Test/Makefile.macosx	Fri Oct 01 22:01:53 2010 +0900
+++ b/Renderer/Test/Makefile.macosx	Sat Oct 02 03:19:33 2010 +0900
@@ -13,7 +13,7 @@
 %.pb.cc: $(PROTODIR)/%.proto
 	$(PROTO) $(PROTOFLAGS) $<
 
-ALL =  ball_bound boss1_action direction gaplant ieshoot node panel universe untitled vacuum property_test send_linda dynamic writer chain_old SgRootChange viewer aquarium init_aquarium test_linda
+ALL =  ball_bound boss1_action direction gaplant ieshoot node panel universe untitled vacuum property_test send_linda dynamic writer chain_old SgRootChange viewer aquarium network init_aquarium test_linda
 
 oFLAGS=-g -O2
 CFLAGt=-g -O2
@@ -91,6 +91,10 @@
 aquarium : $(AQUARIUM_OBJ)
 	$(CC) -o $@ $?    $(LIBS) $(PROTOLIBS)
 
+NETWORK_OBJ = network_game.pb.o network.o
+network : $(NETWORK_OBJ)
+	$(CC) -o $@ $?    $(LIBS) $(PROTOLIBS)
+
 INIT_AQUARIUM_OBJ = aquarium.pb.o init_aquarium.o
 init_aquarium : $(INIT_AQUARIUM_OBJ)
 	$(CC) -o $@ $? $(LIBS) $(PROTOLIBS)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/Test/network.cc	Sat Oct 02 03:19:33 2010 +0900
@@ -0,0 +1,293 @@
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include "SceneGraphRoot.h"
+#include "lindaapi.h"
+#include "network.h"
+#include "network_game.pb.h"
+
+#define GET_SERIAL_ID 65535
+
+int NetworkGame::last_player_id = 0;
+
+Viewer *NetworkGame::sgroot;
+linda_t NetworkGame::linda_addr = { "localhost", 10000 };
+int NetworkGame::linda;
+int NetworkGame::serial_id;
+int NetworkGame::width;
+int NetworkGame::start_x;
+char *NetworkGame::xml_file_name;
+
+const char *usr_help_str = "Usage: ./network -linda LINDA_SERVER_NAME\n";
+void TMend(TaskManager *manager);
+
+extern void task_initialize();
+extern int init(TaskManager *manager, int argc, char *argv[]);
+extern Application *
+application() {
+    return new NetworkGame();
+}
+
+static void
+null_move(SceneGraphPtr node, void *sgroot_, int screen_w, int screen_h)
+{
+}
+static void
+null_collision(SceneGraphPtr node, void *sgroot_, int screen_w, int screen_h, SceneGraphPtr tree)
+{
+}
+
+void
+NetworkGame::update_last_player_id() {
+	last_player_id++;
+	if (last_player_id == serial_id)
+		last_player_id++;
+}
+
+void
+NetworkGame::set_position(SceneGraphPtr node, unsigned char *reply) {
+	network_game::Position *pos = new network_game::Position();
+	pos->ParseFromArray(reply + LINDA_HEADER_SIZE, psx_get_datalength(reply));
+	node->xyz[0] = pos->x();
+	node->xyz[1] = pos->y();
+	node->angle[0] = pos->angle_x();
+	node->angle[1] = pos->angle_y();
+	delete pos;
+}
+
+static void
+update_position_move(SceneGraphPtr node, void *sgroot_, int screen_w, int screen_h)
+{
+	// LindaServerから座標データを取得してオブジェクトに反映させる。
+	if (!node->resend_flag || node->seq_rd != node->seq) {
+		unsigned char *reply_rd = psx_reply(node->seq_rd);
+		if (reply_rd != NULL) {
+			NetworkGame::set_position(node, reply_rd);
+			psx_free(reply_rd);
+			return;
+		}
+	}
+	unsigned char *reply = psx_reply(node->seq);
+	if (reply != NULL) {
+//		NetworkGame::set_position(node, reply);
+		psx_free(reply);
+		node->seq = psx_wait_rd(NetworkGame::linda, node->id * 10 + 1);
+		node->resend_flag = true;
+	} else if (node->resend_flag) {
+		node->seq_rd = psx_rd(NetworkGame::linda, node->id * 10 + 1);
+		node->resend_flag = false;
+	}
+}
+
+SceneGraphPtr
+create_sg(Viewer *viewer, SceneGraphPtr par, unsigned char *data, int len, int serial_id)
+{
+    SceneGraphPtr child = viewer->sgroot->createSceneGraph();
+    viewer->sgroot->createFromXMLmemory(viewer->sgroot->tmanager, child, (char *)data, len);
+    child->set_move_collision(update_position_move, null_collision);
+    child->id = serial_id;
+	child->seq = psx_wait_rd(NetworkGame::linda, serial_id * 10 + 1);
+	child->seq_rd = psx_rd(NetworkGame::linda, serial_id * 10 + 1);
+	child->resend_flag = false;
+    par->addChild(child);
+    return child;
+}
+
+static void
+check_new_player_move(SceneGraphPtr node, void *sgroot_, int screen_w, int screen_h)
+{
+	unsigned char *reply_rd = psx_reply(node->seq_rd);
+	if (reply_rd != NULL) {
+		unsigned char *xml_data = reply_rd + LINDA_HEADER_SIZE;
+		int xml_len = psx_get_datalength(reply_rd);
+		create_sg(NetworkGame::sgroot, node, xml_data, xml_len, NetworkGame::last_player_id);
+		psx_free(reply_rd);
+		NetworkGame::update_last_player_id();
+		int tuple_id = NetworkGame::last_player_id * 10;
+		node->seq_rd = psx_rd(NetworkGame::linda, tuple_id);
+	}
+	// printf("rd id: %d\n", NetworkGame::last_player_id);
+}
+
+void *
+file_map(const char *filename, int *size) {
+    int fd;
+    void *addr;
+    struct stat sb;
+
+    if ((fd = open(filename, O_RDONLY)) == -1) {
+		fprintf(stderr, "Can't open %s\n", filename);
+		perror(NULL);
+    }
+    if (fstat(fd, &sb) == -1) {
+		fprintf(stderr, "Can't fstat %s\n", filename);
+		perror(NULL);
+    }
+    *size = sb.st_size;
+    addr = mmap(NULL, *size, PROT_READ, MAP_PRIVATE, fd, 0);
+    if (addr == MAP_FAILED) {
+		perror("mmap error\n");
+		exit(EXIT_FAILURE);
+    }
+    close(fd);
+
+    return addr;
+}
+
+void callback_free(unsigned char *tuple, void *arg) {
+	psx_free(tuple);
+}
+
+void
+NetworkGame::send_position(SceneGraphPtr node) {
+	int pos_id = serial_id * 10 + 1;
+	psx_callback_in(linda, pos_id, callback_free, NULL);
+	network_game::Position *pos = new network_game::Position();
+	pos->set_x(node->xyz[0]);
+	pos->set_y(node->xyz[1]);
+	pos->set_angle_x(node->angle[0]);
+	pos->set_angle_y(node->angle[1]);
+	int size = pos->ByteSize();
+	unsigned char *msg = (unsigned char *) sgroot->manager->allocate(sizeof(char) * size);
+	pos->SerializeToArray(msg, size); // 更新したデータを再度シリアライズ
+	delete pos;
+	psx_out(linda, pos_id, msg, size);
+}
+
+void
+my_move(SceneGraphPtr node, void *sgroot_, int w, int h)
+{
+    SceneGraphRoot *sgroot = (SceneGraphRoot *)sgroot_;
+    Pad *pad = sgroot->getController();
+	int flag = 0;
+    if (pad->right.isHold() || pad->left.isHold()) {
+		if (pad->right.isHold()) {
+			node->xyz[0] += 5.0f;
+			sgroot->camera->xyz[0] = node->xyz[0];
+//			node->angle[1] = 0.0f;
+			flag = 1;
+		} else if (pad->left.isHold()) {
+			node->xyz[0] -= 5.0f;
+			sgroot->camera->xyz[0] = node->xyz[0];
+//			node->angle[1] = 180.0f;
+			flag = 1;
+		}
+    }
+    
+    if (pad->down.isHold() || pad->up.isHold() ) {
+		if (pad->down.isHold()) {
+			node->xyz[1] += 5.0f;
+			sgroot->camera->xyz[1] = node->xyz[1];
+			flag = 1;
+		} else if (pad->up.isHold()) {
+			node->xyz[1] -= 5.0f;
+			sgroot->camera->xyz[1] = node->xyz[1];
+			flag = 1;
+		}
+    }
+
+	/* ここで座標を送信 */
+	if (flag || node->resend_flag) {
+		NetworkGame::send_position(node);
+	}
+}
+
+void
+NetworkGame::create_my_sg(Viewer *viewer, SceneGraphPtr par, int screen_w, int screen_h)
+{
+    int size;
+    void *addr = file_map(xml_file_name, &size);
+    SceneGraphPtr sgp = viewer->createSceneGraph();
+    viewer->createFromXMLmemory(sgp, (char *)addr, size);
+    sgp->set_move_collision(my_move, null_collision);
+	Camera *camera = viewer->sgroot->camera;
+	camera->xyz[0] = 0.0;
+	camera->xyz[1] = 0.0;
+	
+    par->addChild(sgp);
+    sgp->c_xyz[0] = 0.0f;
+    sgp->c_xyz[1] = 0.0f;
+    sgp->c_xyz[2] = 0.0f;
+
+    int xml_id = serial_id * 10;
+    psx_out(linda, xml_id, (unsigned char *)addr, size);
+    int pos_id = serial_id * 10 + 1;
+    
+    network_game::Position *pos = new network_game::Position();
+    pos->set_x(0.0f);
+    pos->set_y(0.0f);
+    pos->set_angle_x(0.0f);
+    pos->set_angle_y(0.0f);
+    unsigned char *msg = (unsigned char *) viewer->manager->allocate(sizeof(unsigned char *) * size);
+    pos->SerializeToArray(msg, size);
+    psx_out(linda, pos_id, (unsigned char *)msg, pos->ByteSize());
+    delete pos;
+    sgp->seq = 0;
+    sgp->resend_flag = 0;
+}
+
+MainLoopPtr
+NetworkGame::init(Viewer *sgroot, int screen_w, int screen_h)
+{
+	this->sgroot = sgroot;
+	width = screen_w;
+	linda_connect(); // 接続に合わせて serial_id も取得
+//	update_screen_scope();
+	SceneGraphPtr parent = sgroot->createSceneGraph();
+	parent->set_move_collision(check_new_player_move, null_collision);
+	
+	create_my_sg(sgroot, parent, screen_w, screen_h);
+	update_last_player_id();
+	
+	int tuple_id = NetworkGame::last_player_id * 10;
+	parent->seq_rd = psx_rd(linda, tuple_id);
+	sgroot->setSceneData(parent);
+	return sgroot;
+}
+
+void
+NetworkGame::linda_connect() {
+	init_linda(); // セレクタの初期化
+	linda = open_linda_java(linda_addr.hostname, linda_addr.port);
+	// serial_id の取得
+	int seq = psx_in(linda, GET_SERIAL_ID);
+	unsigned char *data = NULL;
+	do {
+		psx_sync_n();
+		data = psx_reply(seq);
+	} while (data == NULL);
+//	data[LINDA_HEADER_SIZE + psx_get_datalength(data)] = '\0';
+	serial_id = atoi((char *)data + LINDA_HEADER_SIZE);
+	psx_free(data);
+	printf("Get serial_id: %d\n", serial_id);
+}
+
+int
+TMmain(TaskManager *manager, int argc, char *argv[])
+{
+    task_initialize();
+    manager->set_TMend(TMend);
+
+    for (int i = 0; i < argc; i++) {
+        if (strcmp(argv[i],"-linda") == 0 && i + 1 <= argc) {
+			NetworkGame::linda_addr.hostname = argv[i+1];
+        } else if (strcmp(argv[i],"-port") == 0 && i + 1 <= argc) {
+			NetworkGame::linda_addr.port = atoi(argv[i+1]);
+        } else if (strcmp(argv[i],"-xml") == 0 && i + 1 <= argc) {
+			NetworkGame::xml_file_name = argv[i+1];
+		}
+    }
+    return init(manager, argc, argv);
+}
+
+void
+TMend(TaskManager *manager)
+{
+    printf("NetworkGame end\n");
+}
+
+/* end */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/Test/network.h	Sat Oct 02 03:19:33 2010 +0900
@@ -0,0 +1,29 @@
+#include <math.h>
+#include <stdlib.h>
+#include "SceneGraphRoot.h"
+#include "Application.h"
+#include "MainLoop.h"
+typedef struct {
+	const char *hostname;
+	int port;
+} linda_t;
+
+class NetworkGame : public Application {
+public:
+	static int last_player_id;
+	
+	static Viewer *sgroot;
+	static linda_t linda_addr;
+	static int linda;
+	static int serial_id;
+	static int start_x;
+	static int width;
+	static char *xml_file_name;
+	static void linda_connect();
+	static void update_screen_scope();
+	static void send_position(SceneGraphPtr node);
+	static void set_position(SceneGraphPtr node, unsigned char *reply);
+	static void update_last_player_id();
+	void create_my_sg(Viewer *sgroot, SceneGraphPtr parent, int screen_w, int screen_h);
+    MainLoopPtr init(Viewer *viewer, int screen_w, int screen_h);
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/Test/protobuf/network_game.proto	Sat Oct 02 03:19:33 2010 +0900
@@ -0,0 +1,8 @@
+package network_game;
+
+message Position {
+  required float x = 1;
+  required float y = 2;
+  required float angle_x = 3;
+  required float angle_y = 4;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/old/framebuffer/Makefile	Sat Oct 02 03:19:33 2010 +0900
@@ -0,0 +1,14 @@
+all: fb_info fb_test fb_finish
+
+CC = gcc -std=c99 -O2 -g
+fb_info : fb_info.o cp_fb.o cp_vt.o
+	$(CC) -o  $@ $+
+
+fb_test : fb_test.o  cp_fb.o cp_vt.o -lm
+	$(CC) -o  $@ $+
+
+fb_finish : fb_finish.o  cp_fb.o cp_vt.o -lm
+	$(CC) -o  $@ $+
+
+clean:
+	rm -f fb_info fb_test fb_finish *.o
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/old/framebuffer/cp_vt.c	Sat Oct 02 03:19:33 2010 +0900
@@ -0,0 +1,286 @@
+// cp_vt.c 
+//
+// Copyright (c) 2006, Mike Acton <macton@cellperformance.com>
+// 
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
+// documentation files (the "Software"), to deal in the Software without restriction, including without
+// limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial
+// portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
+// LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
+// EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+// AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
+// OR OTHER DEALINGS IN THE SOFTWARE.
+
+// NOTES:
+// From http://www.linuxjournal.com/article/2597
+//
+//     "Console ttys are used when the keyboard and monitor are directly connected to the system without running
+//     the X Window System. Since you can have several virtual consoles, the devices are tty0 through tty63. In
+//     theory you can have 64 virtual consoles, but most people use only a few. The device /dev/console is
+//     identical to tty0 and is needed for historical reasons. If your system lets you log in on consoles 1
+//     through 6, then when you run X Windows System, X uses console 7, so you'll need /dev/tty1 through /dev/
+//     tty7 on your system. I recommend having files up through /dev/tty12. For more information on using
+//     virtual consoles, see the article Keyboards, Consoles and VT Cruising by John Fisk in the November 1996
+//     issue of Linux Journal"
+
+#include <stdio.h>
+#include <stdint.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <linux/vt.h>
+#include <linux/kd.h>
+#include "cp_vt.h"
+
+
+static inline const char*
+select_error_str( int existing_error, const char* const existing_error_str, int new_error, const char* const new_error_str )
+{
+  // Only report the first error found - any error that follows is probably just a cascading effect.
+  const char* error_str = (char*)( (~(intptr_t)existing_error & (intptr_t)new_error & (intptr_t)new_error_str)
+                                 |  ((intptr_t)existing_error & (intptr_t)existing_error_str) );
+
+  return (error_str);
+}
+
+
+int
+cp_vt_open_graphics(cp_vt* restrict vt)
+{
+  const char*    error_str      = NULL;
+  int            error          = 0;
+
+  // Open the current tty
+ 
+  // From http://tldp.org/HOWTO/Text-Terminal-HOWTO-6.html#ss6.3
+  // (An excellent overview by David S. Lawyer)
+  //
+  //     "In Linux the PC monitor is usually called the console and has several device special files associated
+  //     with it: vc/0 (tty0), vc/1 (tty1), vc/2 (tty2), etc. When you log in you are on vc/1. To go to vc/2
+  //     (on the same screen) press down the 2 keys Alt(left)-F3. For vc/3 use Left Alt-F3, etc. These (vc/1,
+  //     vc/2, vc/3, etc.) are called "virtual terminals". vc/0 (tty0) is just an alias for the current virtual
+  //     terminal and it's where messages from the system are sent. Thus messages from the system will be seen
+  //     on the console (monitor) regardless of which virtual terminal it is displaying."
+
+  const int   cur_tty                = open( "/dev/tty0", O_RDWR );
+  const int   open_cur_tty_error     = (cur_tty >> ((sizeof(int)*8)-1));
+  const char* open_cur_tty_error_str = "Could not open /dev/tty0. Check permissions.";
+  
+  error_str = select_error_str( error, error_str, open_cur_tty_error, open_cur_tty_error_str );
+  error     = error | open_cur_tty_error;
+
+  // From: http://www.linuxjournal.com/article/2783
+  // (A little out of date, but a nice primer.)
+  //
+  //     "VT_GETSTATE returns the state of all VT's in the kernel in the structure:
+  //
+  //         struct vt_stat {
+  //               ushort v_active; 
+  //               ushort v_signal; 
+  //               ushort v_state;
+  //          };
+  //
+  //      v_active        the currently active VT 
+  //      v_state         mask of all the opened VT's
+  //
+  //      v_active holds the number of the active VT (starting from 1), while v_state 
+  //      holds a mask where there is a 1 for each VT that has been opened by some process. 
+  //      Note that VT 0 is always opened in this scenario, since it refers to the current VT.
+  //
+  //      Bugs:
+  //      The v_signal member is unsupported."
+
+  struct vt_stat  vts;
+
+  const int   get_state_error     = ioctl( cur_tty, VT_GETSTATE, &vts );
+  const char* get_state_error_str = "VT_GETSTATE failed on /dev/tty0";
+
+  error_str = select_error_str( error, error_str, get_state_error, get_state_error_str );
+  error     = error | get_state_error;
+
+  vt->prev_tty_ndx = vts.v_active;
+
+  // From: http://opensolaris.org/os/project/vconsole/vt.7i.txt
+  // (Close enough to Linux and a pretty good source of documentation.)
+  //
+  // "VT_OPENQRY
+  //     This call is used to find an available VT.    The argu-
+  //     ment to the    ioctl is a pointer to an integer.  The integer
+  //     will be filled in with the number of the first avail-
+  //     able VT that no other process has open (and    hence, is
+  //     available to be opened).  If there are no available
+  //     VTs, then -1 will be filled in."
+
+  const int   open_query_error     = ioctl( cur_tty, VT_OPENQRY, &vt->tty_ndx);
+  const char* open_query_error_str = "No open ttys available";
+
+  error_str = select_error_str( error, error_str, open_query_error, open_query_error_str );
+  error     = error | open_query_error;
+
+  const int   close_cur_tty_error     = close( cur_tty );
+  const char* close_cur_tty_error_str = "Could not close parent tty";
+
+  error_str = select_error_str( error, error_str, close_cur_tty_error, close_cur_tty_error_str );
+  error     = error | close_cur_tty_error;
+
+  char tty_file_name[11];
+
+  (void)snprintf( tty_file_name, 11, "/dev/tty%d", vt->tty_ndx );
+
+  const int   tty                = open( tty_file_name, O_RDWR );
+  const int   open_tty_error     = (cur_tty >> ((sizeof(int)*8)-1));
+  const char* open_tty_error_str = "Could not open tty";
+
+  error_str = select_error_str( error, error_str, open_tty_error, open_tty_error_str );
+  error     = error | open_tty_error;
+
+  vt->tty = tty;
+
+  // From: http://opensolaris.org/os/project/vconsole/vt.7i.txt
+  // (Close enough to Linux and a pretty good source of documentation.)
+  //
+  // "VT_ACTIVATE
+  //    This call has the effect of making the VT specified in
+  //    the argument the active VT. The VT manager will cause
+  //    a switch to occur in the same manner as if a hotkey had
+  //    initiated the switch.  If the specified VT is not open
+  //    or does not exist the call will fail and errno will be
+  //    set to ENXIO."
+  //
+  // "VT_WAITACTIVE
+  //    If the specified VT is already active, this call
+  //    returns immediately. Otherwise, it will sleep until
+  //    the specified VT becomes active, at which point it will
+  //    return."
+
+
+  const int   activate_tty_error     = ioctl( vt->tty, VT_ACTIVATE, vt->tty_ndx );
+  const char* activate_tty_error_str = "Could not activate tty";
+
+  error_str = select_error_str( error, error_str, activate_tty_error, activate_tty_error_str );
+  error     = error | activate_tty_error;
+#if 0
+  const int   waitactive_tty_error     = ioctl( vt->tty, VT_WAITACTIVE, vt->tty_ndx );
+  const char* waitactive_tty_error_str = "Could not switch to tty";
+
+  error_str = select_error_str( error, error_str, waitactive_tty_error, waitactive_tty_error_str );
+  error     = error | waitactive_tty_error;
+#endif
+
+  // From: http://opensolaris.org/os/project/vconsole/vt.7i.txt
+  // (Close enough to Linux and a pretty good source of documentation.)
+  //
+  //  "KDSETMODE
+  //   This call is used to set the text/graphics mode to the VT.
+  //
+  //      KD_TEXT indicates that console text will be displayed on the screen
+  //      with this VT. Normally KD_TEXT is combined with VT_AUTO mode for
+  //      text console terminals, so that the console text display will
+  //      automatically be saved and restored on the hot key screen switches.
+  //
+  //      KD_GRAPHICS indicates that the user/application, usually Xserver,
+  //      will have direct control of the display for this VT in graphics
+  //      mode. Normally KD_GRAPHICS is combined with VT_PROCESS mode for
+  //      this VT indicating direct control of the display in graphics mode.
+  //      In this mode, all writes to this VT using the write system call are
+  //      ignored, and the user is responsible for saving and restoring the
+  //      display on the hot key screen switches."
+
+  // Save the current VT mode. This is most likely KD_TEXT.
+
+  const int   kdgetmode_error     = ioctl( vt->tty, KDGETMODE, &vt->prev_kdmode );
+  const char* kdgetmode_error_str = "Could not get mode for tty";
+
+  error_str = select_error_str( error, error_str, kdgetmode_error, kdgetmode_error_str );
+  error     = error | kdgetmode_error;
+  
+  // Set VT to GRAPHICS (user draw) mode
+
+  const int   kdsetmode_graphics_error     = ioctl( vt->tty, KDSETMODE, KD_GRAPHICS );
+  const char* kdsetmode_graphics_error_str = "Could not set graphics mode for tty";
+
+  error_str = select_error_str( error, error_str, kdsetmode_graphics_error, kdsetmode_graphics_error_str );
+  error     = error | kdsetmode_graphics_error;
+
+  //
+  // Not bothering with VT_PROCESS, VT_AUTO is fine for our purposes.
+  //
+ 
+  // If vt blanking is active, for example when running this program from a remote terminal, 
+  // setting KD_GRAPHICS will not disable the blanking. Reset to KD_TEXT from KD_GRAPHICS will
+  // force disable blanking. Then return to KD_GRAPHICS for drawing.
+  //
+  // Note: KD_TEXT (default) to KD_TEXT will do nothing, so blanking will not be disable unless
+  // the mode is changing. i.e. the initial set to KD_GRAPHICS above is useful.
+
+  const int   kdsetmode_text_error     = ioctl( vt->tty, KDSETMODE, KD_TEXT );
+  const char* kdsetmode_text_error_str = "Could not set text mode for tty";
+
+  error_str = select_error_str( error, error_str, kdsetmode_text_error, kdsetmode_text_error_str );
+  error     = error | kdsetmode_text_error;
+
+  const int   kdsetmode_graphics_reset_error     = ioctl( vt->tty, KDSETMODE, KD_GRAPHICS );
+  const char* kdsetmode_graphics_reset_error_str = "Could not reset graphics mode for tty";
+
+  error_str = select_error_str( error, error_str, kdsetmode_graphics_reset_error, kdsetmode_graphics_reset_error_str );
+  error     = error | kdsetmode_graphics_reset_error;
+
+  if ( error == -1 )
+  {
+      printf("ERROR: vt_graphics_open: %s\n",error_str);
+      return (-1);
+  }
+
+  return (0);
+}
+
+int
+cp_vt_close(cp_vt* restrict vt)
+{
+  const char*    error_str      = NULL;
+  int            error          = 0;
+
+  // Reset previous mode on tty (likely KD_TEXT)
+
+  const int   kdsetmode_error     = ioctl( vt->tty, KDSETMODE, vt->prev_kdmode );
+  const char* kdsetmode_error_str = "Could not reset previous mode for tty";
+
+  error_str = select_error_str( error, error_str, kdsetmode_error, kdsetmode_error_str );
+  error     = error | kdsetmode_error;
+
+  // Restore previous tty
+
+  const int   activate_tty_error     = ioctl( vt->tty, VT_ACTIVATE, vt->prev_tty_ndx );
+  const char* activate_tty_error_str = "Could not activate previous tty";
+
+  error_str = select_error_str( error, error_str, activate_tty_error, activate_tty_error_str );
+  error     = error | activate_tty_error;
+
+  const int   waitactive_tty_error     = ioctl( vt->tty, VT_WAITACTIVE, vt->prev_tty_ndx );
+  const char* waitactive_tty_error_str = "Could not switch to previous tty";
+
+  error_str = select_error_str( error, error_str, waitactive_tty_error, waitactive_tty_error_str );
+  error     = error | waitactive_tty_error;
+
+  // Close tty
+
+  const int   close_tty_error     = close( vt->tty );
+  const char* close_tty_error_str = "Could not close tty";
+
+  error_str = select_error_str( error, error_str, close_tty_error, close_tty_error_str );
+  error     = error | close_tty_error;
+
+  if ( error == -1 )
+  {
+      printf("ERROR: vt_close: %s\n",error_str);
+      return (-1);
+  }
+
+  return (0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/old/framebuffer/cp_vt.h	Sat Oct 02 03:19:33 2010 +0900
@@ -0,0 +1,45 @@
+// cp_vt.h 
+//
+// Copyright (c) 2006, Mike Acton <macton@cellperformance.com>
+// 
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
+// documentation files (the "Software"), to deal in the Software without restriction, including without
+// limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial
+// portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
+// LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
+// EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+// AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
+// OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef CP_VT_H
+#define CP_VT_H
+
+#if defined(__cplusplus)
+extern "C" 
+{
+#endif
+
+typedef struct cp_vt cp_vt;
+
+struct cp_vt
+{
+    int prev_tty_ndx;
+    int prev_kdmode;
+    int tty;
+    int tty_ndx;
+};
+
+int cp_vt_open_graphics(cp_vt* restrict vt);
+int cp_vt_close(cp_vt* restrict vt);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/old/framebuffer/fb_finish.c	Sat Oct 02 03:19:33 2010 +0900
@@ -0,0 +1,45 @@
+// fb_test.c 
+// Simple test application. Draw something to the frame buffer. 
+//
+// Copyright (c) 2006, Mike Acton <macton@cellperformance.com>
+// 
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
+// documentation files (the "Software"), to deal in the Software without restriction, including without
+// limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial
+// portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
+// LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
+// EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+// AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
+// OR OTHER DEALINGS IN THE SOFTWARE.
+
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include "cp_vt.h"
+#include "cp_fb.h"
+
+void write_hline_gouraud_ABGR8888( int32_t x0, int32_t x1, uint32_t left_rgba, uint32_t right_rgba, void* dest_buffer, uint16_t stride );
+
+int 
+main( void )
+{
+    cp_vt vt;
+    cp_fb fb;
+
+    cp_vt_open_graphics(&vt);
+    cp_fb_open(&fb);
+
+
+    cp_vt_close(&vt);
+    cp_fb_close(&fb);
+
+    return (0);
+}
+