Index: osd.c
===================================================================
--- osd.c	(revision 1062)
+++ osd.c	(revision 1063)
@@ -1,611 +1,615 @@
-/*
-    Raydium - CQFD Corp.
-    http://raydium.org/
-    Released under both BSD license and Lesser GPL library license.
-    See "license.txt" file.
-*/
-
-#ifndef DONT_INCLUDE_HEADERS
-#include "index.h"
-#else
-#include "headers/osd.h"
-#endif
-
-// need proto
-void raydium_camera_replace(void);
-
-// OSD color could be changed from one frame to the next one by Raydium
-// itself (console, internal uses, ...) so set your OSD color
-// in the display loop, no before.
-
-void raydium_osd_color_change(GLfloat r, GLfloat g, GLfloat b)
-{
-raydium_osd_color[0]=r;
-raydium_osd_color[1]=g;
-raydium_osd_color[2]=b;
-}
-
-void raydium_osd_alpha_change(GLfloat a)
-{
-raydium_osd_color[3]=a;
-}
-
-void raydium_osd_color_rgba(GLfloat r, GLfloat g, GLfloat b, GLfloat a)
-{
-raydium_osd_color_change(r,g,b);
-raydium_osd_alpha_change(a);
-}
-
-void raydium_osd_color_ega(char hexa)
-{
-int i=15;
-
-if(hexa>='0' && hexa<='9') i=hexa - '0';
-if(hexa>='a' && hexa<='f') i=hexa - 'a'+10;
-if(hexa>='A' && hexa<='F') i=hexa - 'A'+10;
-i*=3;
-raydium_osd_color_change(raydium_osd_ega[i],raydium_osd_ega[i+1],raydium_osd_ega[i+2]);
-}
-
-void raydium_osd_start(void)
-{
-glMatrixMode(GL_PROJECTION);
-glPushMatrix();
-glLoadIdentity();
-
-//glViewport(0, 0, raydium_window_tx, raydium_window_ty);
-glOrtho(0,100, 0,100, -100,100);
-// Rotate and translate the OSD to fit the landscape mode on the iPhone OS.
-#ifdef IPHONEOS
-#ifndef IPHONEOS_ORIENTATION_PORTRAIT
-glRotatef(-90,0,0,1);
-glTranslatef(-100,0,0);
-#endif
-#endif
-
-//glPushMatrix();
-raydium_rendering_internal_prepare_texture_render(0);
-glMatrixMode(GL_MODELVIEW);
-glPushMatrix();
-glLoadIdentity();
-glDisable(GL_DEPTH_TEST);
-glDepthMask(GL_FALSE);
-glDisable(GL_LIGHTING);
-glDisable(GL_FOG);
-glColor4f(1.f,1.f,1.f,1.f);
-}
-
-void raydium_osd_stop(void)
-{
-raydium_window_resize_callback(raydium_window_tx, raydium_window_ty);
-glEnable(GL_DEPTH_TEST);
-glDepthMask(GL_TRUE);
-if(raydium_light_enabled_tag) glEnable(GL_LIGHTING);
-if(raydium_fog_enabled_tag)   glEnable(GL_FOG);
-
-glMatrixMode(GL_PROJECTION);
-glPopMatrix();
-
-glMatrixMode(GL_MODELVIEW);
-glPopMatrix();
-}
-
-
-void raydium_osd_draw(int tex ,GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)
-{
-raydium_osd_start();
-
-raydium_texture_current_set(tex);
-raydium_rendering_internal_prepare_texture_render(tex);
-glColor4fv(raydium_osd_color);
-glBegin(GL_QUADS);
-
-glTexCoord2f(0,0);glVertex3f(x1,y1,0);
-glTexCoord2f(1,0);glVertex3f(x2,y1,0);
-glTexCoord2f(1,1);glVertex3f(x2,y2,0);
-glTexCoord2f(0,1);glVertex3f(x1,y2,0);
-
-
-glEnd();
-raydium_rendering_internal_restore_render_state();
-
-raydium_osd_stop();
-}
-
-void raydium_osd_draw_name(char *tex ,GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)
-{
-raydium_osd_draw(raydium_texture_find_by_name(tex),x1,y1,x2,y2);
-}
-
-void raydium_osd_draw_quad(int tex, GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2, GLfloat angle)
-{
-float tx,ty;
-
-raydium_osd_start();
-
-tx=x1+((x2-x1)/2.0f);
-ty=y1+((y2-y1)/2.0f);
-
-raydium_texture_current_set(tex);
-raydium_rendering_internal_prepare_texture_render(tex);
-glColor4fv(raydium_osd_color);
-
-glTranslatef(tx,ty,0);
-glRotatef(angle,0,0,1);
-
-glBegin(GL_QUADS);
-glTexCoord2f(0,0);glVertex3f(tx-x1,ty-y1,0);
-glTexCoord2f(1,0);glVertex3f(tx-x2,ty-y1,0);
-glTexCoord2f(1,1);glVertex3f(tx-x2,ty-y2,0);
-glTexCoord2f(0,1);glVertex3f(tx-x1,ty-y2,0);
-glEnd();
-
-glRotatef(-angle,0,0,1);
-glTranslatef(-tx,-ty,0);
-
-raydium_rendering_internal_restore_render_state();
-
-raydium_osd_stop();
-}
-
-void raydium_osd_draw_quad_name(char *tex, GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2, GLfloat angle)
-{
-raydium_osd_draw_quad(raydium_texture_find_by_name(tex),x1,y1,x2,y2,angle);
-}
-
-// need to be secured
-void raydium_osd_printf(GLfloat x, GLfloat y, GLfloat size, GLfloat spacer,char *texture, char *format, ...)
-{
-char str[RAYDIUM_MAX_NAME_LEN];
-va_list argptr;
-int i,texsave;
-GLfloat dx=0;
-GLfloat dy=0;
-unsigned char ligne,offset;
-GLfloat u,v;
-char c;
-
-
-size/=RAYDIUM_OSD_FONT_SIZE_FACTOR;
-va_start(argptr,format);
-vsprintf(str,format,argptr);
-va_end(argptr);
-
-raydium_osd_start();
-texsave=raydium_texture_current_main;
-raydium_texture_current_set_name(texture);
-raydium_rendering_internal_prepare_texture_render(raydium_texture_current_main);
-
-glTranslatef(x,y,0);
-
-// strlen is slooow :)
-for( i=0; str[i]; i++ )
- {
- if(str[i]=='\r' || str[i]=='\t') continue;
-
- if(str[i]=='^' && i+1<RAYDIUM_MAX_NAME_LEN && str[i+1]!=0)
- 	{
-	// oh ! ... you cannot draw '^' char since i'm
-	// too lazy to code it for now :)
-	raydium_osd_color_ega(str[++i]);
-	continue;
-	}
-
- if(str[i]=='\n')
- 	{
-	dx=0;
-	dy+=(size*2*(spacer*2));
-	continue;
-	}
-
- c=str[i]; // c=str[i]-32;
- ligne=c/16;
- offset=c-(ligne*16);
- u=offset/16.f;
- v=1-(ligne/16.f); // /*1-*/
-
- glColor4fv(raydium_osd_color);
- glBegin(GL_QUADS);
-
-
-
- glTexCoord2f(u,v-(1/16.f)); glVertex3f(-size+dx,-size-dy,0);
- glTexCoord2f(u+(1/16.f),v-(1/16.f));glVertex3f(size+dx,-size-dy,0);
- glTexCoord2f(u+(1/16.f),v);glVertex3f(size+dx,size-dy,0);
- glTexCoord2f(u,v);glVertex3f(-size+dx,size-dy,0);
- glEnd();
- dx+=(size*2*spacer);
-
- }
-
-//raydium_rendering_internal_restore_render_state();
-raydium_osd_stop();
-//raydium_texture_current_set(texsave);
-}
-
-
-void raydium_osd_printf_3D(GLfloat x, GLfloat y, GLfloat z, GLfloat size, GLfloat spacer,char *texture, char *format, ...)
-{
-char str[RAYDIUM_MAX_NAME_LEN];
-va_list argptr;
-float sx,sy;
-
-va_start(argptr,format);
-vsprintf(str,format,argptr);
-va_end(argptr);
-
-if(raydium_math_point_unproject_3D(x,y,z,&sx,&sy))
-    raydium_osd_printf(sx,sy,size,spacer,texture,"%s",str);
-}
-
-void raydium_osd_logo(char *texture)
-{
-//GLuint vertex_index_save;
-raydium_osd_start();
-raydium_texture_current_set_name(texture);
-
-glTranslatef(85,10,0);
-glRotatef(raydium_osd_logo_angle+=(raydium_frame_time*60),0,1,0); //must be callbacked !
-if(raydium_osd_logo_angle>90) raydium_osd_logo_angle=-90;
-
-raydium_rendering_internal_prepare_texture_render(raydium_texture_current_main);
-glBegin(GL_QUADS);
-glTexCoord2f(0,0);
-glVertex3f(-10,-5,0);
-glTexCoord2f(1,0);
-glVertex3f(10,-5,0);
-glTexCoord2f(1,1);
-glVertex3f(10,5,0);
-glTexCoord2f(0,1);
-glVertex3f(-10,5,0);
-glEnd();
-//raydium_rendering_internal_restore_render_state();
-
-raydium_osd_stop();
-}
-
-
-void raydium_osd_cursor_set(char *texture,GLfloat xsize, GLfloat ysize)
-{
-raydium_mouse_hide();
-if(texture && strlen(texture))
-    raydium_osd_cursor_texture=raydium_texture_find_by_name(texture);
-else
-    raydium_osd_cursor_texture=0;
-
-raydium_osd_cursor_xsize=xsize;
-raydium_osd_cursor_ysize=ysize;
-}
-
-void raydium_osd_cursor_offset(GLfloat xoffset, GLfloat yoffset)
-{
-raydium_osd_cursor_xoffset=xoffset;
-raydium_osd_cursor_yoffset=yoffset;
-}
-
-void raydium_osd_cursor_draw(void)
-{
-if(!raydium_osd_cursor_texture || !raydium_window_tx) return;
-
-raydium_osd_start();
-
-glTranslatef((((((GLfloat)raydium_mouse_x)/raydium_window_tx))*100.f) +raydium_osd_cursor_xoffset,
-((((GLfloat)(raydium_window_ty-raydium_mouse_y)/raydium_window_ty))*100.f) +raydium_osd_cursor_yoffset,0);
-
-raydium_texture_current_set(raydium_osd_cursor_texture);
-raydium_rendering_internal_prepare_texture_render(raydium_texture_current_main);
-
-glBegin(GL_QUADS);
-    glTexCoord2f(0,0);glVertex3f(0,-raydium_osd_cursor_ysize,0);
-    glTexCoord2f(1,0);glVertex3f(raydium_osd_cursor_xsize,-raydium_osd_cursor_ysize,0);
-    glTexCoord2f(1,1);glVertex3f(raydium_osd_cursor_xsize,0,0);
-    glTexCoord2f(0,1);glVertex3f(0,0,0);
-glEnd();
-raydium_rendering_internal_restore_render_state();
-
-raydium_osd_stop();
-
-}
-
-void raydium_osd_internal_vertex(GLfloat x, GLfloat y, GLfloat top)
-{
-if(y>top) y=top;
-glVertex3f(x,y,0);
-}
-
-void raydium_osd_network_stat_draw(GLfloat px, GLfloat py, GLfloat size)
-{
-#define RAYDIUM_OSD_NET_SAMPLES         32
-#define RAYDIUM_OSD_NET_STEP            0.3
-static GLfloat past_delay[RAYDIUM_OSD_NET_SAMPLES];
-static GLfloat past_rx[RAYDIUM_OSD_NET_SAMPLES];
-static GLfloat past_tx[RAYDIUM_OSD_NET_SAMPLES];
-static GLfloat step=0;
-static int last_rx,last_tx;
-
-static GLfloat past_reemitted[RAYDIUM_OSD_NET_SAMPLES];
-static GLfloat past_double[RAYDIUM_OSD_NET_SAMPLES];
-static GLfloat past_lost[RAYDIUM_OSD_NET_SAMPLES];
-static GLfloat past_bogus[RAYDIUM_OSD_NET_SAMPLES];
-
-static GLfloat last_reemitted;
-static GLfloat last_double;
-static GLfloat last_lost;
-static GLfloat last_bogus;
-
-
-int i;
-GLfloat fact_x,fact_y_delay,fact_y_rxtx;
-
-fact_x=size/RAYDIUM_OSD_NET_SAMPLES;
-fact_y_delay=size/(RAYDIUM_NETWORK_ACK_DELAY_MAX*1000);
-fact_y_rxtx=size/50; // 50 KB
-step+=raydium_frame_time;
-
-if(step>=RAYDIUM_OSD_NET_STEP)
-    {
-    step=0;
-
-    // shift array to the left
-    for(i=1;i<RAYDIUM_OSD_NET_SAMPLES;i++)
-        past_delay[i-1]=past_delay[i];
-    past_delay[RAYDIUM_OSD_NET_SAMPLES-1]=raydium_netwok_queue_ack_delay_client;
-
-    for(i=1;i<RAYDIUM_OSD_NET_SAMPLES;i++)
-        past_rx[i-1]=past_rx[i];
-    past_rx[RAYDIUM_OSD_NET_SAMPLES-1]=(raydium_network_stat_rx-last_rx)/1024;
-    last_rx=raydium_network_stat_rx;
-
-    for(i=1;i<RAYDIUM_OSD_NET_SAMPLES;i++)
-        past_tx[i-1]=past_tx[i];
-    past_tx[RAYDIUM_OSD_NET_SAMPLES-1]=(raydium_network_stat_tx-last_tx)/1024;
-    last_tx=raydium_network_stat_tx;
-
-    for(i=1;i<RAYDIUM_OSD_NET_SAMPLES;i++)
-        past_reemitted[i-1]=past_reemitted[i];
-    past_reemitted[RAYDIUM_OSD_NET_SAMPLES-1]=(raydium_network_stat_reemitted-last_reemitted)*(size/10);
-    last_reemitted=raydium_network_stat_reemitted;
-
-    for(i=1;i<RAYDIUM_OSD_NET_SAMPLES;i++)
-        past_double[i-1]=past_double[i];
-    past_double[RAYDIUM_OSD_NET_SAMPLES-1]=(raydium_network_stat_double-last_double)*(size/10);
-    last_double=raydium_network_stat_double;
-
-    for(i=1;i<RAYDIUM_OSD_NET_SAMPLES;i++)
-        past_lost[i-1]=past_lost[i];
-    past_lost[RAYDIUM_OSD_NET_SAMPLES-1]=(raydium_network_stat_lost-last_lost)*(size/10);
-    last_lost=raydium_network_stat_lost;
-
-    for(i=1;i<RAYDIUM_OSD_NET_SAMPLES;i++)
-        past_bogus[i-1]=past_bogus[i];
-    past_bogus[RAYDIUM_OSD_NET_SAMPLES-1]=(raydium_network_stat_bogus_ack-last_bogus)*(size/10);
-    last_bogus=raydium_network_stat_bogus_ack;
-
-    }
-
-// draw data
-raydium_osd_color_ega('0');
-raydium_osd_draw_name("rgb(0,0,0)",px,py,px+size,py+size);
-raydium_osd_start();
-
-raydium_osd_color_ega('9');
-glColor4fv(raydium_osd_color);
-glBegin(GL_LINE_STRIP);
-for(i=0;i<RAYDIUM_OSD_NET_SAMPLES;i++)
-    {
-    raydium_osd_internal_vertex(
-        px+(i*fact_x),
-        py+(past_delay[i]/(double)raydium_timecall_clocks_per_sec*1000*fact_y_delay),
-        py+size);
-    }
-glEnd();
-
-raydium_osd_color_ega('f');
-glColor4fv(raydium_osd_color);
-glBegin(GL_LINE_STRIP);
-for(i=0;i<RAYDIUM_OSD_NET_SAMPLES;i++)
-    {
-    raydium_osd_internal_vertex(
-        px+(i*fact_x),
-        py+(past_tx[i]*fact_y_rxtx),
-        py+size);
-    }
-glEnd();
-
-raydium_osd_color_ega('c');
-glColor4fv(raydium_osd_color);
-glBegin(GL_LINE_STRIP);
-for(i=0;i<RAYDIUM_OSD_NET_SAMPLES;i++)
-    {
-    raydium_osd_internal_vertex(
-        px+(i*fact_x),
-        py+(past_rx[i]*fact_y_rxtx),
-        py+size);
-    }
-glEnd();
-
-raydium_osd_color_ega('d');
-glColor4fv(raydium_osd_color);
-glBegin(GL_LINES);
-for(i=0;i<RAYDIUM_OSD_NET_SAMPLES;i++)
-    {
-    raydium_osd_internal_vertex(
-        px+(i*fact_x),
-        py,
-        py+size);
-    raydium_osd_internal_vertex(
-        px+(i*fact_x),
-        py+past_reemitted[i],
-        py+size);
-    }
-glEnd();
-
-raydium_osd_color_ega('e');
-glColor4fv(raydium_osd_color);
-glBegin(GL_LINES);
-for(i=0;i<RAYDIUM_OSD_NET_SAMPLES;i++)
-    {
-    raydium_osd_internal_vertex(
-        px+(i*fact_x),
-        py,
-        py+size);
-    raydium_osd_internal_vertex(
-        px+(i*fact_x),
-        py+past_double[i],
-        py+size);
-    }
-glEnd();
-
-raydium_osd_color_ega('a');
-glColor4fv(raydium_osd_color);
-glBegin(GL_LINES);
-for(i=0;i<RAYDIUM_OSD_NET_SAMPLES;i++)
-    {
-    raydium_osd_internal_vertex(
-        px+(i*fact_x),
-        py,
-        py+size);
-    raydium_osd_internal_vertex(
-        px+(i*fact_x),
-        py+past_lost[i],
-        py+size);
-    }
-glEnd();
-
-raydium_osd_color_ega('b');
-glColor4fv(raydium_osd_color);
-glBegin(GL_LINES);
-for(i=0;i<RAYDIUM_OSD_NET_SAMPLES;i++)
-    {
-    raydium_osd_internal_vertex(
-        px+(i*fact_x),
-        py,
-        py+size);
-    raydium_osd_internal_vertex(
-        px+(i*fact_x),
-        py+past_bogus[i],
-        py+size);
-    }
-glEnd();
-
-raydium_rendering_internal_restore_render_state();
-raydium_osd_stop();
-raydium_osd_color_ega('f');
-}
-
-void raydium_osd_mask(GLfloat *color4)
-{
-raydium_osd_start();
-
-// invalidate cache
-//raydium_texture_internal_loaded=0;
-raydium_rendering_internal_prepare_texture_render(0);
-glDisable(GL_TEXTURE_2D);
-glEnable(GL_BLEND);
-glDepthMask(GL_FALSE);
-glColor4f(color4[0],color4[1],color4[2],color4[3]);
-
-glBegin(GL_QUADS);
-glVertex3f(0,0,0);
-glVertex3f(100,0,0);
-glVertex3f(100,100,0);
-glVertex3f(0,100,0);
-glEnd();
-raydium_rendering_internal_restore_render_state();
-
-raydium_osd_stop();
-}
-
-
-void raydium_osd_mask_texture_clip(int texture,GLfloat alpha, GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)
-{
-x1/=100;
-y1/=100;
-x2/=100;
-y2/=100;
-
-raydium_osd_start();
-
-// invalidate cache
-//raydium_texture_internal_loaded=0;
-raydium_rendering_internal_prepare_texture_render(texture);
-glEnable(GL_TEXTURE_2D);
-glEnable(GL_BLEND);
-glDepthMask(GL_FALSE);
-glColor4f(1,1,1,alpha);
-
-glBegin(GL_QUADS);
-glTexCoord2f(x1,y1);
-glVertex3f(0,0,0);
-
-glTexCoord2f(x2,y1);
-glVertex3f(100,0,0);
-
-glTexCoord2f(x2,y2);
-glVertex3f(100,100,0);
-
-glTexCoord2f(x1,y2);
-glVertex3f(0,100,0);
-glEnd();
-raydium_rendering_internal_restore_render_state();
-
-raydium_osd_stop();
-}
-
-void raydium_osd_mask_texture_clip_name(char *texture,GLfloat alpha, GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)
-{
-raydium_osd_mask_texture_clip(raydium_texture_find_by_name(texture),alpha,x1,y1,x2,y2);
-}
-
-void raydium_osd_mask_texture(int texture,GLfloat alpha)
-{
-raydium_osd_mask_texture_clip(texture,alpha,0,0,100,100);
-}
-
-void raydium_osd_mask_texture_name(char *texture,GLfloat alpha)
-{
-raydium_osd_mask_texture(raydium_texture_find_by_name(texture),alpha);
-}
-
-
-void raydium_osd_fade_callback(void)
-{
-int i;
-void (*f)(void);
-
-if(raydium_osd_fade_color_timeleft>0)
-    {
-    raydium_osd_fade_color_timeleft-=raydium_frame_time;
-    for(i=0;i<4;i++)
-        raydium_osd_fade_color_current[i]+=
-            raydium_osd_fade_color_increment[i]*raydium_frame_time;
-
-    raydium_osd_mask(raydium_osd_fade_color_current);
-    if(raydium_osd_fade_color_timeleft<=0 && raydium_osd_fade_OnFadeEnd)
-        {
-        f=raydium_osd_fade_OnFadeEnd;
-        f();
-        return; // fade may have changed during playback ...
-        }
-    }
-}
-
-
-void raydium_osd_fade_init(void)
-{
-raydium_osd_fade_color_timeleft=-1;
-memset(raydium_osd_fade_color_increment,0,raydium_internal_size_vector_float_4);
-memset(raydium_osd_fade_color_current,0,raydium_internal_size_vector_float_4);
-raydium_osd_fade_OnFadeEnd=NULL;
-}
-
-void raydium_osd_fade_from(GLfloat *from4, GLfloat *to4, GLfloat time_len, void *OnFadeEnd)
-{
-int i;
-
-raydium_osd_fade_color_timeleft=time_len;
-memcpy(raydium_osd_fade_color_current,from4,raydium_internal_size_vector_float_4);
-raydium_osd_fade_OnFadeEnd=OnFadeEnd;
-for(i=0;i<4;i++)
-    raydium_osd_fade_color_increment[i]=(to4[i]-from4[i])/time_len; // per sec
-}
+/*
+    Raydium - CQFD Corp.
+    http://raydium.org/
+    Released under both BSD license and Lesser GPL library license.
+    See "license.txt" file.
+*/
+
+#ifndef DONT_INCLUDE_HEADERS
+#include "index.h"
+#else
+#include "headers/osd.h"
+#endif
+
+// need proto
+void raydium_camera_replace(void);
+
+// OSD color could be changed from one frame to the next one by Raydium
+// itself (console, internal uses, ...) so set your OSD color
+// in the display loop, no before.
+
+void raydium_osd_color_change(GLfloat r, GLfloat g, GLfloat b)
+{
+raydium_osd_color[0]=r;
+raydium_osd_color[1]=g;
+raydium_osd_color[2]=b;
+}
+
+void raydium_osd_alpha_change(GLfloat a)
+{
+raydium_osd_color[3]=a;
+}
+
+void raydium_osd_color_rgba(GLfloat r, GLfloat g, GLfloat b, GLfloat a)
+{
+raydium_osd_color_change(r,g,b);
+raydium_osd_alpha_change(a);
+}
+
+void raydium_osd_color_ega(char hexa)
+{
+int i=15;
+
+if(hexa>='0' && hexa<='9') i=hexa - '0';
+if(hexa>='a' && hexa<='f') i=hexa - 'a'+10;
+if(hexa>='A' && hexa<='F') i=hexa - 'A'+10;
+i*=3;
+raydium_osd_color_change(raydium_osd_ega[i],raydium_osd_ega[i+1],raydium_osd_ega[i+2]);
+}
+
+void raydium_osd_start(void)
+{
+glMatrixMode(GL_PROJECTION);
+glPushMatrix();
+glLoadIdentity();
+
+//glViewport(0, 0, raydium_window_tx, raydium_window_ty);
+glOrtho(0,100, 0,100, -100,100);
+// Rotate and translate the OSD to fit the landscape mode on the iPhone OS.
+#ifdef IPHONEOS
+#ifndef IPHONEOS_ORIENTATION_PORTRAIT
+glRotatef(-90,0,0,1);
+glTranslatef(-100,0,0);
+#endif
+#endif
+
+//glPushMatrix();
+raydium_rendering_internal_prepare_texture_render(0);
+glMatrixMode(GL_MODELVIEW);
+glPushMatrix();
+glLoadIdentity();
+glDisable(GL_DEPTH_TEST);
+glDepthMask(GL_FALSE);
+glDisable(GL_LIGHTING);
+glDisable(GL_FOG);
+glColor4f(1.f,1.f,1.f,1.f);
+}
+
+void raydium_osd_stop(void)
+{
+if (raydium_viewport_use!=-1)
+    glViewport(0,0, raydium_viewport[raydium_viewport_use].tx,raydium_viewport[raydium_viewport_use].ty);
+else
+    raydium_window_resize_callback(raydium_window_tx, raydium_window_ty);
+
+glEnable(GL_DEPTH_TEST);
+glDepthMask(GL_TRUE);
+if(raydium_light_enabled_tag) glEnable(GL_LIGHTING);
+if(raydium_fog_enabled_tag)   glEnable(GL_FOG);
+
+glMatrixMode(GL_PROJECTION);
+glPopMatrix();
+
+glMatrixMode(GL_MODELVIEW);
+glPopMatrix();
+}
+
+
+void raydium_osd_draw(int tex ,GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)
+{
+raydium_osd_start();
+
+raydium_texture_current_set(tex);
+raydium_rendering_internal_prepare_texture_render(tex);
+glColor4fv(raydium_osd_color);
+glBegin(GL_QUADS);
+
+glTexCoord2f(0,0);glVertex3f(x1,y1,0);
+glTexCoord2f(1,0);glVertex3f(x2,y1,0);
+glTexCoord2f(1,1);glVertex3f(x2,y2,0);
+glTexCoord2f(0,1);glVertex3f(x1,y2,0);
+
+
+glEnd();
+raydium_rendering_internal_restore_render_state();
+
+raydium_osd_stop();
+}
+
+void raydium_osd_draw_name(char *tex ,GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)
+{
+raydium_osd_draw(raydium_texture_find_by_name(tex),x1,y1,x2,y2);
+}
+
+void raydium_osd_draw_quad(int tex, GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2, GLfloat angle)
+{
+float tx,ty;
+
+raydium_osd_start();
+
+tx=x1+((x2-x1)/2.0f);
+ty=y1+((y2-y1)/2.0f);
+
+raydium_texture_current_set(tex);
+raydium_rendering_internal_prepare_texture_render(tex);
+glColor4fv(raydium_osd_color);
+
+glTranslatef(tx,ty,0);
+glRotatef(angle,0,0,1);
+
+glBegin(GL_QUADS);
+glTexCoord2f(0,0);glVertex3f(tx-x1,ty-y1,0);
+glTexCoord2f(1,0);glVertex3f(tx-x2,ty-y1,0);
+glTexCoord2f(1,1);glVertex3f(tx-x2,ty-y2,0);
+glTexCoord2f(0,1);glVertex3f(tx-x1,ty-y2,0);
+glEnd();
+
+glRotatef(-angle,0,0,1);
+glTranslatef(-tx,-ty,0);
+
+raydium_rendering_internal_restore_render_state();
+
+raydium_osd_stop();
+}
+
+void raydium_osd_draw_quad_name(char *tex, GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2, GLfloat angle)
+{
+raydium_osd_draw_quad(raydium_texture_find_by_name(tex),x1,y1,x2,y2,angle);
+}
+
+// need to be secured
+void raydium_osd_printf(GLfloat x, GLfloat y, GLfloat size, GLfloat spacer,char *texture, char *format, ...)
+{
+char str[RAYDIUM_MAX_NAME_LEN];
+va_list argptr;
+int i,texsave;
+GLfloat dx=0;
+GLfloat dy=0;
+unsigned char ligne,offset;
+GLfloat u,v;
+char c;
+
+
+size/=RAYDIUM_OSD_FONT_SIZE_FACTOR;
+va_start(argptr,format);
+vsprintf(str,format,argptr);
+va_end(argptr);
+
+raydium_osd_start();
+texsave=raydium_texture_current_main;
+raydium_texture_current_set_name(texture);
+raydium_rendering_internal_prepare_texture_render(raydium_texture_current_main);
+
+glTranslatef(x,y,0);
+
+// strlen is slooow :)
+for( i=0; str[i]; i++ )
+ {
+ if(str[i]=='\r' || str[i]=='\t') continue;
+
+ if(str[i]=='^' && i+1<RAYDIUM_MAX_NAME_LEN && str[i+1]!=0)
+ 	{
+	// oh ! ... you cannot draw '^' char since i'm
+	// too lazy to code it for now :)
+	raydium_osd_color_ega(str[++i]);
+	continue;
+	}
+
+ if(str[i]=='\n')
+ 	{
+	dx=0;
+	dy+=(size*2*(spacer*2));
+	continue;
+	}
+
+ c=str[i]; // c=str[i]-32;
+ ligne=c/16;
+ offset=c-(ligne*16);
+ u=offset/16.f;
+ v=1-(ligne/16.f); // /*1-*/
+
+ glColor4fv(raydium_osd_color);
+ glBegin(GL_QUADS);
+
+
+
+ glTexCoord2f(u,v-(1/16.f)); glVertex3f(-size+dx,-size-dy,0);
+ glTexCoord2f(u+(1/16.f),v-(1/16.f));glVertex3f(size+dx,-size-dy,0);
+ glTexCoord2f(u+(1/16.f),v);glVertex3f(size+dx,size-dy,0);
+ glTexCoord2f(u,v);glVertex3f(-size+dx,size-dy,0);
+ glEnd();
+ dx+=(size*2*spacer);
+
+ }
+
+//raydium_rendering_internal_restore_render_state();
+raydium_osd_stop();
+//raydium_texture_current_set(texsave);
+}
+
+
+void raydium_osd_printf_3D(GLfloat x, GLfloat y, GLfloat z, GLfloat size, GLfloat spacer,char *texture, char *format, ...)
+{
+char str[RAYDIUM_MAX_NAME_LEN];
+va_list argptr;
+float sx,sy;
+
+va_start(argptr,format);
+vsprintf(str,format,argptr);
+va_end(argptr);
+
+if(raydium_math_point_unproject_3D(x,y,z,&sx,&sy))
+    raydium_osd_printf(sx,sy,size,spacer,texture,"%s",str);
+}
+
+void raydium_osd_logo(char *texture)
+{
+//GLuint vertex_index_save;
+raydium_osd_start();
+raydium_texture_current_set_name(texture);
+
+glTranslatef(85,10,0);
+glRotatef(raydium_osd_logo_angle+=(raydium_frame_time*60),0,1,0); //must be callbacked !
+if(raydium_osd_logo_angle>90) raydium_osd_logo_angle=-90;
+
+raydium_rendering_internal_prepare_texture_render(raydium_texture_current_main);
+glBegin(GL_QUADS);
+glTexCoord2f(0,0);
+glVertex3f(-10,-5,0);
+glTexCoord2f(1,0);
+glVertex3f(10,-5,0);
+glTexCoord2f(1,1);
+glVertex3f(10,5,0);
+glTexCoord2f(0,1);
+glVertex3f(-10,5,0);
+glEnd();
+//raydium_rendering_internal_restore_render_state();
+
+raydium_osd_stop();
+}
+
+
+void raydium_osd_cursor_set(char *texture,GLfloat xsize, GLfloat ysize)
+{
+raydium_mouse_hide();
+if(texture && strlen(texture))
+    raydium_osd_cursor_texture=raydium_texture_find_by_name(texture);
+else
+    raydium_osd_cursor_texture=0;
+
+raydium_osd_cursor_xsize=xsize;
+raydium_osd_cursor_ysize=ysize;
+}
+
+void raydium_osd_cursor_offset(GLfloat xoffset, GLfloat yoffset)
+{
+raydium_osd_cursor_xoffset=xoffset;
+raydium_osd_cursor_yoffset=yoffset;
+}
+
+void raydium_osd_cursor_draw(void)
+{
+if(!raydium_osd_cursor_texture || !raydium_window_tx) return;
+
+raydium_osd_start();
+
+glTranslatef((((((GLfloat)raydium_mouse_x)/raydium_window_tx))*100.f) +raydium_osd_cursor_xoffset,
+((((GLfloat)(raydium_window_ty-raydium_mouse_y)/raydium_window_ty))*100.f) +raydium_osd_cursor_yoffset,0);
+
+raydium_texture_current_set(raydium_osd_cursor_texture);
+raydium_rendering_internal_prepare_texture_render(raydium_texture_current_main);
+
+glBegin(GL_QUADS);
+    glTexCoord2f(0,0);glVertex3f(0,-raydium_osd_cursor_ysize,0);
+    glTexCoord2f(1,0);glVertex3f(raydium_osd_cursor_xsize,-raydium_osd_cursor_ysize,0);
+    glTexCoord2f(1,1);glVertex3f(raydium_osd_cursor_xsize,0,0);
+    glTexCoord2f(0,1);glVertex3f(0,0,0);
+glEnd();
+raydium_rendering_internal_restore_render_state();
+
+raydium_osd_stop();
+
+}
+
+void raydium_osd_internal_vertex(GLfloat x, GLfloat y, GLfloat top)
+{
+if(y>top) y=top;
+glVertex3f(x,y,0);
+}
+
+void raydium_osd_network_stat_draw(GLfloat px, GLfloat py, GLfloat size)
+{
+#define RAYDIUM_OSD_NET_SAMPLES         32
+#define RAYDIUM_OSD_NET_STEP            0.3
+static GLfloat past_delay[RAYDIUM_OSD_NET_SAMPLES];
+static GLfloat past_rx[RAYDIUM_OSD_NET_SAMPLES];
+static GLfloat past_tx[RAYDIUM_OSD_NET_SAMPLES];
+static GLfloat step=0;
+static int last_rx,last_tx;
+
+static GLfloat past_reemitted[RAYDIUM_OSD_NET_SAMPLES];
+static GLfloat past_double[RAYDIUM_OSD_NET_SAMPLES];
+static GLfloat past_lost[RAYDIUM_OSD_NET_SAMPLES];
+static GLfloat past_bogus[RAYDIUM_OSD_NET_SAMPLES];
+
+static GLfloat last_reemitted;
+static GLfloat last_double;
+static GLfloat last_lost;
+static GLfloat last_bogus;
+
+
+int i;
+GLfloat fact_x,fact_y_delay,fact_y_rxtx;
+
+fact_x=size/RAYDIUM_OSD_NET_SAMPLES;
+fact_y_delay=size/(RAYDIUM_NETWORK_ACK_DELAY_MAX*1000);
+fact_y_rxtx=size/50; // 50 KB
+step+=raydium_frame_time;
+
+if(step>=RAYDIUM_OSD_NET_STEP)
+    {
+    step=0;
+
+    // shift array to the left
+    for(i=1;i<RAYDIUM_OSD_NET_SAMPLES;i++)
+        past_delay[i-1]=past_delay[i];
+    past_delay[RAYDIUM_OSD_NET_SAMPLES-1]=raydium_netwok_queue_ack_delay_client;
+
+    for(i=1;i<RAYDIUM_OSD_NET_SAMPLES;i++)
+        past_rx[i-1]=past_rx[i];
+    past_rx[RAYDIUM_OSD_NET_SAMPLES-1]=(raydium_network_stat_rx-last_rx)/1024;
+    last_rx=raydium_network_stat_rx;
+
+    for(i=1;i<RAYDIUM_OSD_NET_SAMPLES;i++)
+        past_tx[i-1]=past_tx[i];
+    past_tx[RAYDIUM_OSD_NET_SAMPLES-1]=(raydium_network_stat_tx-last_tx)/1024;
+    last_tx=raydium_network_stat_tx;
+
+    for(i=1;i<RAYDIUM_OSD_NET_SAMPLES;i++)
+        past_reemitted[i-1]=past_reemitted[i];
+    past_reemitted[RAYDIUM_OSD_NET_SAMPLES-1]=(raydium_network_stat_reemitted-last_reemitted)*(size/10);
+    last_reemitted=raydium_network_stat_reemitted;
+
+    for(i=1;i<RAYDIUM_OSD_NET_SAMPLES;i++)
+        past_double[i-1]=past_double[i];
+    past_double[RAYDIUM_OSD_NET_SAMPLES-1]=(raydium_network_stat_double-last_double)*(size/10);
+    last_double=raydium_network_stat_double;
+
+    for(i=1;i<RAYDIUM_OSD_NET_SAMPLES;i++)
+        past_lost[i-1]=past_lost[i];
+    past_lost[RAYDIUM_OSD_NET_SAMPLES-1]=(raydium_network_stat_lost-last_lost)*(size/10);
+    last_lost=raydium_network_stat_lost;
+
+    for(i=1;i<RAYDIUM_OSD_NET_SAMPLES;i++)
+        past_bogus[i-1]=past_bogus[i];
+    past_bogus[RAYDIUM_OSD_NET_SAMPLES-1]=(raydium_network_stat_bogus_ack-last_bogus)*(size/10);
+    last_bogus=raydium_network_stat_bogus_ack;
+
+    }
+
+// draw data
+raydium_osd_color_ega('0');
+raydium_osd_draw_name("rgb(0,0,0)",px,py,px+size,py+size);
+raydium_osd_start();
+
+raydium_osd_color_ega('9');
+glColor4fv(raydium_osd_color);
+glBegin(GL_LINE_STRIP);
+for(i=0;i<RAYDIUM_OSD_NET_SAMPLES;i++)
+    {
+    raydium_osd_internal_vertex(
+        px+(i*fact_x),
+        py+(past_delay[i]/(double)raydium_timecall_clocks_per_sec*1000*fact_y_delay),
+        py+size);
+    }
+glEnd();
+
+raydium_osd_color_ega('f');
+glColor4fv(raydium_osd_color);
+glBegin(GL_LINE_STRIP);
+for(i=0;i<RAYDIUM_OSD_NET_SAMPLES;i++)
+    {
+    raydium_osd_internal_vertex(
+        px+(i*fact_x),
+        py+(past_tx[i]*fact_y_rxtx),
+        py+size);
+    }
+glEnd();
+
+raydium_osd_color_ega('c');
+glColor4fv(raydium_osd_color);
+glBegin(GL_LINE_STRIP);
+for(i=0;i<RAYDIUM_OSD_NET_SAMPLES;i++)
+    {
+    raydium_osd_internal_vertex(
+        px+(i*fact_x),
+        py+(past_rx[i]*fact_y_rxtx),
+        py+size);
+    }
+glEnd();
+
+raydium_osd_color_ega('d');
+glColor4fv(raydium_osd_color);
+glBegin(GL_LINES);
+for(i=0;i<RAYDIUM_OSD_NET_SAMPLES;i++)
+    {
+    raydium_osd_internal_vertex(
+        px+(i*fact_x),
+        py,
+        py+size);
+    raydium_osd_internal_vertex(
+        px+(i*fact_x),
+        py+past_reemitted[i],
+        py+size);
+    }
+glEnd();
+
+raydium_osd_color_ega('e');
+glColor4fv(raydium_osd_color);
+glBegin(GL_LINES);
+for(i=0;i<RAYDIUM_OSD_NET_SAMPLES;i++)
+    {
+    raydium_osd_internal_vertex(
+        px+(i*fact_x),
+        py,
+        py+size);
+    raydium_osd_internal_vertex(
+        px+(i*fact_x),
+        py+past_double[i],
+        py+size);
+    }
+glEnd();
+
+raydium_osd_color_ega('a');
+glColor4fv(raydium_osd_color);
+glBegin(GL_LINES);
+for(i=0;i<RAYDIUM_OSD_NET_SAMPLES;i++)
+    {
+    raydium_osd_internal_vertex(
+        px+(i*fact_x),
+        py,
+        py+size);
+    raydium_osd_internal_vertex(
+        px+(i*fact_x),
+        py+past_lost[i],
+        py+size);
+    }
+glEnd();
+
+raydium_osd_color_ega('b');
+glColor4fv(raydium_osd_color);
+glBegin(GL_LINES);
+for(i=0;i<RAYDIUM_OSD_NET_SAMPLES;i++)
+    {
+    raydium_osd_internal_vertex(
+        px+(i*fact_x),
+        py,
+        py+size);
+    raydium_osd_internal_vertex(
+        px+(i*fact_x),
+        py+past_bogus[i],
+        py+size);
+    }
+glEnd();
+
+raydium_rendering_internal_restore_render_state();
+raydium_osd_stop();
+raydium_osd_color_ega('f');
+}
+
+void raydium_osd_mask(GLfloat *color4)
+{
+raydium_osd_start();
+
+// invalidate cache
+//raydium_texture_internal_loaded=0;
+raydium_rendering_internal_prepare_texture_render(0);
+glDisable(GL_TEXTURE_2D);
+glEnable(GL_BLEND);
+glDepthMask(GL_FALSE);
+glColor4f(color4[0],color4[1],color4[2],color4[3]);
+
+glBegin(GL_QUADS);
+glVertex3f(0,0,0);
+glVertex3f(100,0,0);
+glVertex3f(100,100,0);
+glVertex3f(0,100,0);
+glEnd();
+raydium_rendering_internal_restore_render_state();
+
+raydium_osd_stop();
+}
+
+
+void raydium_osd_mask_texture_clip(int texture,GLfloat alpha, GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)
+{
+x1/=100;
+y1/=100;
+x2/=100;
+y2/=100;
+
+raydium_osd_start();
+
+// invalidate cache
+//raydium_texture_internal_loaded=0;
+raydium_rendering_internal_prepare_texture_render(texture);
+glEnable(GL_TEXTURE_2D);
+glEnable(GL_BLEND);
+glDepthMask(GL_FALSE);
+glColor4f(1,1,1,alpha);
+
+glBegin(GL_QUADS);
+glTexCoord2f(x1,y1);
+glVertex3f(0,0,0);
+
+glTexCoord2f(x2,y1);
+glVertex3f(100,0,0);
+
+glTexCoord2f(x2,y2);
+glVertex3f(100,100,0);
+
+glTexCoord2f(x1,y2);
+glVertex3f(0,100,0);
+glEnd();
+raydium_rendering_internal_restore_render_state();
+
+raydium_osd_stop();
+}
+
+void raydium_osd_mask_texture_clip_name(char *texture,GLfloat alpha, GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)
+{
+raydium_osd_mask_texture_clip(raydium_texture_find_by_name(texture),alpha,x1,y1,x2,y2);
+}
+
+void raydium_osd_mask_texture(int texture,GLfloat alpha)
+{
+raydium_osd_mask_texture_clip(texture,alpha,0,0,100,100);
+}
+
+void raydium_osd_mask_texture_name(char *texture,GLfloat alpha)
+{
+raydium_osd_mask_texture(raydium_texture_find_by_name(texture),alpha);
+}
+
+
+void raydium_osd_fade_callback(void)
+{
+int i;
+void (*f)(void);
+
+if(raydium_osd_fade_color_timeleft>0)
+    {
+    raydium_osd_fade_color_timeleft-=raydium_frame_time;
+    for(i=0;i<4;i++)
+        raydium_osd_fade_color_current[i]+=
+            raydium_osd_fade_color_increment[i]*raydium_frame_time;
+
+    raydium_osd_mask(raydium_osd_fade_color_current);
+    if(raydium_osd_fade_color_timeleft<=0 && raydium_osd_fade_OnFadeEnd)
+        {
+        f=raydium_osd_fade_OnFadeEnd;
+        f();
+        return; // fade may have changed during playback ...
+        }
+    }
+}
+
+
+void raydium_osd_fade_init(void)
+{
+raydium_osd_fade_color_timeleft=-1;
+memset(raydium_osd_fade_color_increment,0,raydium_internal_size_vector_float_4);
+memset(raydium_osd_fade_color_current,0,raydium_internal_size_vector_float_4);
+raydium_osd_fade_OnFadeEnd=NULL;
+}
+
+void raydium_osd_fade_from(GLfloat *from4, GLfloat *to4, GLfloat time_len, void *OnFadeEnd)
+{
+int i;
+
+raydium_osd_fade_color_timeleft=time_len;
+memcpy(raydium_osd_fade_color_current,from4,raydium_internal_size_vector_float_4);
+raydium_osd_fade_OnFadeEnd=OnFadeEnd;
+for(i=0;i<4;i++)
+    raydium_osd_fade_color_increment[i]=(to4[i]-from4[i])/time_len; // per sec
+}