🎉 Added files

This commit is contained in:
2025-01-26 18:33:45 +01:00
commit 40149d87b3
301 changed files with 81911 additions and 0 deletions

47
raydium/atexit.c Normal file
View File

@ -0,0 +1,47 @@
/*
Raydium - CQFD Corp.
http://raydium.org/
License: GPL - GNU General Public License, see "gpl.txt" file.
*/
#ifndef DONT_INCLUDE_HEADERS
#include "index.h"
#else
#include "headers/atexit.h"
#endif
#include "atexit.h"
int raydium_atexit(void (*func)(void))
{
if(raydium_atexit_index==RAYDIUM_MAX_ATEXIT_FUNCTIONS)
{
raydium_log("atexit: no more free handlers (%i max)",RAYDIUM_MAX_ATEXIT_FUNCTIONS);
return -1;
}
raydium_atexit_functions[raydium_atexit_index++]=func;
return 0;
}
void raydium_atexit_call(void)
{
int i;
void (*f)(void);
for(i=raydium_atexit_index-1;i>=0;i--)
{
f=raydium_atexit_functions[i];
f();
}
}
void raydium_atexit_init(void)
{
raydium_atexit_index=0;
#ifndef RAYDLL
atexit(raydium_atexit_call);
#endif
}

18
raydium/atexit.h Normal file
View File

@ -0,0 +1,18 @@
/*
Raydium - CQFD Corp.
http://raydium.org/
License: GPL - GNU General Public License, see "gpl.txt" file.
*/
#ifndef ATEXIT_H
#define ATEXIT_H
#define RAYDIUM_MAX_ATEXIT_FUNCTIONS 32
__global void *raydium_atexit_functions[RAYDIUM_MAX_ATEXIT_FUNCTIONS];
__global int raydium_atexit_index;
// proto
__rayapi void raydium_log (char *format, ...);
#endif

22
raydium/background.c Normal file
View File

@ -0,0 +1,22 @@
/*
Raydium - CQFD Corp.
http://raydium.org/
License: GPL - GNU General Public License, see "gpl.txt" file.
*/
#ifndef DONT_INCLUDE_HEADERS
#include "index.h"
#else
#include "headers/background.h"
#endif
void raydium_background_color_change(GLfloat r, GLfloat g, GLfloat b, GLfloat a)
{
raydium_background_color[0]=r;
raydium_background_color[1]=g;
raydium_background_color[2]=b;
raydium_background_color[3]=a;
//glColor4fv(raydium_background_color);
raydium_clear_color_update();
raydium_fog_color_update();
}

87
raydium/callback.c Normal file
View File

@ -0,0 +1,87 @@
/*
Raydium - CQFD Corp.
http://raydium.org/
License: GPL - GNU General Public License, see "gpl.txt" file.
*/
#ifndef DONT_INCLUDE_HEADERS
#include "index.h"
#else
#include "headers/callback.h"
#endif
void raydium_osd_cursor_draw(void);
void raydium_console_draw(void);
void raydium_gui_draw(void);
void raydium_osd_fade_callback(void);
#ifdef PHP_SUPPORT
int raydium_php_exec(char *);
#endif
#ifdef ODE_SUPPORT
void raydium_ode_network_read(void);
#endif
void raydium_network_read_faked(void);
void raydium_video_callback(void);
void raydium_internal_live_video_callback(void);
void raydium_object_callback(void);
void raydium_web_callback(void);
void raydium_hdr_map(void);
void raydium_hdr_map_apply(void);
void raydium_callback_image(void)
{
raydium_timecall_callback();
raydium_light_callback();
raydium_particle_draw_all();
raydium_hdr_map_apply();
raydium_particle_callback();
raydium_osd_fade_callback();
raydium_gui_draw();
raydium_console_draw();
raydium_osd_cursor_draw();
raydium_joy_callback();
raydium_sound_callback();
#ifdef ODE_SUPPORT
// 0hz ODE callback workaround
raydium_ode_network_read();
#endif
if(raydium_network_mode==RAYDIUM_NETWORK_MODE_DISCOVER)
raydium_network_read_faked();
#ifndef WIN32
raydium_internal_live_video_callback();
#endif
raydium_video_callback();
raydium_web_callback();
raydium_object_callback();
}
void raydium_callback_set(void)
{
if(raydium_window_mode==RAYDIUM_RENDERING_NONE)
return;
glutReshapeFunc(&raydium_window_resize_callback);
glutKeyboardFunc((void *)raydium_key_normal_callback);
glutSpecialUpFunc((void *)raydium_key_special_up_callback);
glutSpecialFunc((void *)raydium_key_special_callback);
glutMotionFunc((void *)raydium_mouse_move_callback);
glutPassiveMotionFunc((void *)raydium_mouse_move_callback);
glutMouseFunc((void *)raydium_mouse_click_callback);
}
void raydium_callback(void (*loop) )
{
#ifdef PHP_SUPPORT
char autoexec[RAYDIUM_MAX_NAME_LEN];
if(raydium_init_cli_option("autoexec2",autoexec))
raydium_php_exec(autoexec);
#endif
glutDisplayFunc(loop);
glutIdleFunc(loop);
glutMainLoop();
}

463
raydium/camera.c Normal file
View File

@ -0,0 +1,463 @@
/*
Raydium - CQFD Corp.
http://raydium.org/
License: GPL - GNU General Public License, see "gpl.txt" file.
*/
#ifndef DONT_INCLUDE_HEADERS
#include "index.h"
#else
#include "headers/camera.h"
#endif
// res3 is GLfloat[3]
void raydium_camera_vectors(GLfloat *res3)
{
GLfloat m[16];
GLfloat front[3]={1,0,0};
//GLfloat up[3]={0,0,1};
GLfloat res1[3];
GLfloat res2[3];
raydium_trigo_pos_get_modelview(res1); // get current position
raydium_trigo_pos_to_matrix(front,m); // create matrix using front
glPushMatrix();
glMultMatrixf(m); // project front
raydium_trigo_pos_get_modelview(res2); // get new position
glPopMatrix();
// create front vector
res3[1]=-(res1[0]-res2[0]); // x
res3[2]=(res1[1]-res2[1]); // y
res3[0]=(res1[2]-res2[2]); // z
// create up vector
// fallback
res3[3]=res3[4]=0;
res3[5]=1;
/*
raydium_trigo_pos_get_modelview(res1); // get current position
raydium_trigo_pos_to_matrix(up,m); // create matrix using front
glPushMatrix();
glMultMatrixf(m); // project front
raydium_trigo_pos_get_modelview(res2); // get new position
glPopMatrix();
res3[4]=(res1[0]-res2[0]); // x
res3[5]=-(res1[1]-res2[1]); // y
res3[3]=-(res1[2]-res2[2]); // z
*/
//raydium_log("%f %f %f",res3[3],res3[4],res3[5]);
}
void raydium_camera_internal_prepare(void)
{
GLfloat x,y,z;
glLoadIdentity();
if(raydium_camera_rumble_remaining>0)
{
x=raydium_random_f(-raydium_camera_rumble_amplitude,raydium_camera_rumble_amplitude);
y=raydium_random_f(-raydium_camera_rumble_amplitude,raydium_camera_rumble_amplitude);
z=raydium_random_f(-raydium_camera_rumble_amplitude,raydium_camera_rumble_amplitude);
glRotatef(z,0,0,1);
glRotatef(x,1,0,0);
glRotatef(y,0,1,0);
raydium_camera_rumble_remaining-=raydium_frame_time;
raydium_camera_rumble_amplitude+=(raydium_camera_rumble_evolution*raydium_frame_time);
if(raydium_camera_rumble_amplitude<=0)
{
raydium_camera_rumble_amplitude=0;
raydium_camera_rumble_remaining=0;
}
}
else raydium_camera_rumble_remaining=0;
}
void raydium_camera_internal(GLfloat x, GLfloat y, GLfloat z)
{
if(raydium_frame_first_camera_pass)
{
float pos[3];
float or[6];
pos[0]=x;
pos[1]=y;
pos[2]=z;
if(raydium_sound)
{
raydium_camera_vectors(or); // get vectors
raydium_sound_SetListenerPos(pos);
raydium_sound_SetListenerOr(or);
}
if(raydium_sky_atmosphere_check())
{
raydium_sky_box_render(x,y,z);
raydium_sky_atmosphere_render(x,y,z,RAYDIUM_SKY_SPHERE_DEFAULT_DETAIL);
}
else
{
raydium_sky_box_render(x,y,z);
}
//raydium_sky_box_render(x,y,z);
//raydium_atmosphere_render(x,y,z,SPHERE_DEFAULT_DETAIL);
raydium_frame_first_camera_pass=0;
raydium_light_update_position_all();
}
if(!raydium_camera_pushed)
{
raydium_camera_pushed=1;
raydium_camera_x=x;
raydium_camera_y=y;
raydium_camera_z=z;
glPushMatrix();
memset(raydium_camera_cursor_place,0,3*sizeof(GLfloat));
}
else raydium_log("Warning: too many calls to camera_* ! (matrix already pushed)");
}
void raydium_camera_place(GLfloat x, GLfloat y, GLfloat z,
GLfloat lacet, GLfloat tangage, GLfloat roulis)
{
//glLoadIdentity();
raydium_camera_internal_prepare();
glRotatef(roulis,0,0,1);
glRotatef(tangage,1,0,0);
glRotatef(lacet,0,1,0);
glTranslatef(x, y, z);
glRotatef(90,0,0,1);
glRotatef(90,0,1,0);
raydium_camera_internal(z,x,-y);
}
void raydium_camera_look_at(GLfloat x, GLfloat y, GLfloat z,
GLfloat x_to, GLfloat y_to, GLfloat z_to)
{
//glLoadIdentity();
raydium_camera_internal_prepare();
glRotatef(raydium_camera_look_at_roll,0,0,1);
raydium_camera_look_at_roll=0;
gluLookAt(x,y,z,z_to,x_to,-y_to,0.,0.,1.);
raydium_camera_internal(x,y,z);
}
void raydium_camera_replace(void)
{
if(raydium_shadow_rendering)
{
glLoadIdentity();
return;
}
if(!raydium_camera_pushed)
raydium_log("Warning: no camera to replace (matrix stack's empty)");
else
{
glPopMatrix();
glPushMatrix();
memset(raydium_camera_cursor_place,0,3*sizeof(GLfloat));
}
}
void raydium_camera_replace_go(GLfloat *pos, GLfloat *R)
{
// pos[3], R[3*3]
GLfloat matrix[16];
raydium_camera_replace();
matrix[0]=R[0];
matrix[1]=R[4];
matrix[2]=R[8];
matrix[3]=0;
matrix[4]=R[1];
matrix[5]=R[5];
matrix[6]=R[9];
matrix[7]=0;
matrix[8]=R[2];
matrix[9]=R[6];
matrix[10]=R[10];
matrix[11]=0;
matrix[12]=pos[0];
matrix[13]=pos[1];
matrix[14]=pos[2];
matrix[15]=1;
glMultMatrixf(matrix);
memcpy(raydium_camera_cursor_place,pos,3*sizeof(GLfloat));
}
void raydium_camera_rumble(GLfloat amplitude, GLfloat ampl_evo, GLfloat secs)
{
raydium_camera_rumble_amplitude=amplitude;
raydium_camera_rumble_evolution=ampl_evo;
raydium_camera_rumble_remaining=secs;
}
void raydium_camera_path_reset(void)
{
raydium_camera_path_reset_flag=1;
}
// if step is <= 0, moves will be instaneous
// camera will be placed only if step is >=0 (negative steps are used
// only to change internal vars)
void raydium_camera_smooth(GLfloat px, GLfloat py, GLfloat pz,
GLfloat lx, GLfloat ly, GLfloat lz,
GLfloat zoom, GLfloat roll, GLfloat step)
{
static GLfloat opx,opy,opz;
static GLfloat olx,oly,olz;
static GLfloat ozoom=90;
static GLfloat oroll=0;
//raydium_log("camera smooth (asked): %.2f %.2f %.2f | %.2f %.2f %.2f | %.2f %.2f",px,py,pz,lx,ly,lz,zoom,step);
if(step<=0 || // wow.. smells inf, do a instantaneous step. (and don't place cam)
raydium_camera_path_reset_flag)
{
opx=px;
opy=py;
opz=pz;
olx=lx;
oly=ly;
olz=lz;
ozoom=zoom;
oroll=roll;
raydium_camera_path_reset_flag=0;
}
else
{
opx+=(px-opx)*step;
opy+=(py-opy)*step;
opz+=(pz-opz)*step;
olx+=(lx-olx)*step;
oly+=(ly-oly)*step;
olz+=(lz-olz)*step;
ozoom+=(zoom-ozoom)*step;
oroll+=(roll-oroll)*step;
if(ozoom<0) ozoom=0;
if(ozoom>180) ozoom=270;
if(ozoom!=raydium_projection_fov)
{
raydium_projection_fov=ozoom;
raydium_window_view_update();
}
}
raydium_camera_look_at_roll=oroll;
if(step>=0)
raydium_camera_look_at(opx,opy,opz,olx,oly,olz);
//raydium_log("camera smooth (result): %.2f %.2f %.2f | %.2f %.2f %.2f | %.2f | %.2f",opx,opy,opz,olx,oly,olz,ozoom,step);
}
void raydium_camera_path_init(int p)
{
int i;
raydium_camera_path[p].name[0]=0;
raydium_camera_path[p].steps=-1;
for(i=0;i<RAYDIUM_MAX_CAMERA_PATH_STEPS;i++)
{
raydium_camera_path[p].x[i]=0;
raydium_camera_path[p].y[i]=0;
raydium_camera_path[p].z[i]=0;
raydium_camera_path[p].zoom[i]=0;
raydium_camera_path[p].roll[i]=0;
}
}
void raydium_camera_path_init_all(void)
{
int i;
for(i=0;i<RAYDIUM_MAX_CAMERA_PATHS;i++)
raydium_camera_path_init(i);
}
int raydium_camera_path_find(char *name)
{
int i;
for(i=0;i<RAYDIUM_MAX_CAMERA_PATHS;i++)
if(!strcmp(raydium_camera_path[i].name,name) && raydium_camera_path[i].steps>-1)
return i;
return -1;
}
int raydium_camera_path_load(char *filename)
{
FILE *fp;
int i=0;
GLfloat x,y,z,zoom,roll;
int p;
fp=raydium_file_fopen(filename,"rt");
if(!fp)
{
raydium_log("camera: cannot open camera path '%s'",filename);
return -1;
}
for(p=0;p<RAYDIUM_MAX_CAMERA_PATHS;p++)
if(raydium_camera_path[p].steps==-1)
break;
if(p==RAYDIUM_MAX_CAMERA_PATHS)
{
raydium_log("camera: cannot find any free slot !",filename);
return -1;
}
strcpy(raydium_camera_path[p].name,filename);
while( fscanf(fp,"%f %f %f %f %f\n",&x,&y,&z,&zoom,&roll)!=EOF )
{
raydium_camera_path[p].x[i]=x;
raydium_camera_path[p].y[i]=y;
raydium_camera_path[p].z[i]=z;
raydium_camera_path[p].zoom[i]=zoom;
raydium_camera_path[p].roll[i]=roll;
i++;
}
raydium_camera_path[p].steps=i;
raydium_log("camera path '%s' loaded (slot %i, %i steps)",filename,p,i);
return p;
}
void raydium_camera_path_draw(int p)
{
int i;
if(p>=0 && p<RAYDIUM_MAX_CAMERA_PATHS)
{
glDisable(GL_LIGHTING);
raydium_texture_current_set_name("rgb(1,0,0)");
raydium_rendering_internal_prepare_texture_render(raydium_texture_current_main);
glLineWidth(1.f);
glBegin(GL_LINE_LOOP);
for(i=0;i<raydium_camera_path[p].steps;i++)
{
glVertex3f(
raydium_camera_path[p].x[i],
raydium_camera_path[p].y[i],
raydium_camera_path[p].z[i]);
}
glEnd();
if(raydium_light_enabled_tag)
glEnable(GL_LIGHTING);
return;
}
raydium_log("camera path draw failed : invalid index");
}
void raydium_camera_path_draw_name(char *path)
{
int p;
p=raydium_camera_path_find(path);
if(p==-1) p=raydium_camera_path_load(path);
raydium_camera_path_draw(p);
}
signed char raydium_camera_smooth_path(char *path, GLfloat step, GLfloat *x, GLfloat *y, GLfloat *z, GLfloat *zoom, GLfloat *roll)
{
int p;
int step1,step2;
GLfloat vx,vy,vz,vzoom,vroll;
GLfloat diff;
p=raydium_camera_path_find(path);
if(p==-1)
p=raydium_camera_path_load(path);
if(p==-1)
return 0;
step1=(int)step;
step2=step1+1;
diff=step-step1;
while(step1>=raydium_camera_path[p].steps)
{
step1-=raydium_camera_path[p].steps;
}
while(step2>=raydium_camera_path[p].steps)
{
step2-=raydium_camera_path[p].steps;
}
vx=raydium_camera_path[p].x[step2]-raydium_camera_path[p].x[step1];
vy=raydium_camera_path[p].y[step2]-raydium_camera_path[p].y[step1];
vz=raydium_camera_path[p].z[step2]-raydium_camera_path[p].z[step1];
vzoom=raydium_camera_path[p].zoom[step2]-raydium_camera_path[p].zoom[step1];
vroll=raydium_camera_path[p].roll[step2]-raydium_camera_path[p].roll[step1];
*x=raydium_camera_path[p].x[step1]+(vx*diff);
*y=raydium_camera_path[p].y[step1]+(vy*diff);
*z=raydium_camera_path[p].z[step1]+(vz*diff);
*zoom=raydium_camera_path[p].zoom[step1]+(vzoom*diff);
*roll=raydium_camera_path[p].roll[step1]+(vroll*diff);
return 1;
}
void raydium_camera_smooth_path_to_pos(char *path, GLfloat lx, GLfloat ly, GLfloat lz, GLfloat path_step, GLfloat smooth_step)
{
GLfloat x,y,z,zoom,roll;
if(raydium_camera_smooth_path(path,path_step,&x,&y,&z,&zoom,&roll)==-1)
raydium_log("camera path error with '%s'",path);
raydium_camera_smooth(x,y,z,ly,-lz,lx,zoom,roll,smooth_step);
}
void raydium_camera_smooth_pos_to_path(GLfloat lx, GLfloat ly, GLfloat lz, char *path, GLfloat path_step, GLfloat smooth_step)
{
GLfloat x,y,z,zoom,roll;
if(raydium_camera_smooth_path(path,path_step,&x,&y,&z,&zoom,&roll)==-1)
raydium_log("camera path error with '%s'",path);
raydium_camera_smooth(lx,ly,lz,y,-z,x,zoom,roll,smooth_step);
}
void raydium_camera_smooth_path_to_path(char *path_from, GLfloat path_step_from, char *path_to, GLfloat path_step_to, GLfloat smooth_step)
{
GLfloat fx,fy,fz,fzoom,froll;
GLfloat tx,ty,tz,tzoom,troll;
if(raydium_camera_smooth_path(path_from,path_step_from,&fx,&fy,&fz,&fzoom,&froll)==-1)
raydium_log("camera path error with '%s' (from)",path_from);
if(raydium_camera_smooth_path(path_to,path_step_to,&tx,&ty,&tz,&tzoom,&troll)==-1)
raydium_log("camera path error with '%s' (to)",path_to);
raydium_camera_smooth(fx,fy,fz, ty,-tz,tx,fzoom,froll,smooth_step);
}

173
raydium/capture.c Normal file
View File

@ -0,0 +1,173 @@
/*
Raydium - CQFD Corp.
http://raydium.org/
License: GPL - GNU General Public License, see "gpl.txt" file.
*/
#ifndef DONT_INCLUDE_HEADERS
#include "index.h"
#else
#include "headers/capture.h"
#endif
// Present capture code was inspired from various web files...
// Not a pure CQFD Corp. production :)
// proto
FILE *raydium_file_fopen(char *file, char *mode);
void raydium_capture_frame(char *filename)
{
raydium_capture_asked=RAYDIUM_CAPTURE_TGA;
strcpy(raydium_capture_filename,filename);
}
void raydium_capture_frame_now(char *filename)
{
unsigned char cGarbage = 0, type,mode,aux,bpp, *imageData;
short int iGarbage = 0;
GLuint i;
GLuint size;
FILE *file;
mode=3; // RGB (Bpp)
bpp=mode*8;
type=2; // Color
size=raydium_window_tx * raydium_window_ty * mode;
imageData=malloc(size+1);
glReadPixels(0, 0,raydium_window_tx,raydium_window_ty,GL_RGB,GL_UNSIGNED_BYTE,imageData);
// open file and check for errors
file = raydium_file_fopen(filename, "wb");
if (file == NULL) { raydium_log("Error: capture: cannot open %s for writing",filename); return; }
// write the header
fwrite(&cGarbage, sizeof(unsigned char), 1, file);
fwrite(&cGarbage, sizeof(unsigned char), 1, file);
fwrite(&type, sizeof(unsigned char), 1, file);
fwrite(&iGarbage, sizeof(short int), 1, file);
fwrite(&iGarbage, sizeof(short int), 1, file);
fwrite(&cGarbage, sizeof(unsigned char), 1, file);
fwrite(&iGarbage, sizeof(short int), 1, file);
fwrite(&iGarbage, sizeof(short int), 1, file);
fwrite(&raydium_window_tx, sizeof(short int), 1, file);
fwrite(&raydium_window_ty, sizeof(short int), 1, file);
fwrite(&bpp, sizeof(unsigned char), 1, file);
fwrite(&cGarbage, sizeof(unsigned char), 1, file);
// convert the image data from RGB(a) to BGR(A)
for (i=0; i < size ; i+= mode)
{
aux = imageData[i];
imageData[i] = imageData[i+2];
imageData[i+2] = aux;
}
// save the image data
fwrite(imageData, sizeof(unsigned char), size, file);
fclose(file);
// release the memory
free(imageData);
raydium_log("screenshot saved as %s",filename);
}
void raydium_capture_frame_jpeg(char *filename)
{
raydium_capture_asked=RAYDIUM_CAPTURE_JPG;
strcpy(raydium_capture_filename,filename);
}
void raydium_capture_frame_jpeg_now(char *filename)
{
JSAMPLE * image_buffer; /* Points to large array of R,G,B-order data */
int image_height; /* Number of rows in image */
int image_width; /* Number of columns in image */
int quality;
struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;
FILE * outfile; /* target file */
JSAMPROW row_pointer[1]; /* pointer to JSAMPLE row[s] */
int row_stride; /* physical row width in image buffer */
int size;
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_compress(&cinfo);
outfile = raydium_file_fopen(filename, "wb");
if (outfile == NULL) { raydium_log("Error: capture: cannot open %s for writing",filename); return; }
size=raydium_window_tx * raydium_window_ty * 3;
image_buffer=malloc(size+1);
glReadPixels(0, 0,raydium_window_tx,raydium_window_ty,GL_RGB,GL_UNSIGNED_BYTE,image_buffer);
image_width=raydium_window_tx;
image_height=raydium_window_ty;
quality=DEBUG_JPEG_QUALITY;
jpeg_stdio_dest(&cinfo, outfile);
cinfo.image_width = image_width; /* image width and height, in pixels */
cinfo.image_height = image_height;
cinfo.input_components = 3; /* # of color components per pixel */
cinfo.in_color_space = JCS_RGB; /* colorspace of input image */
jpeg_set_defaults(&cinfo);
jpeg_set_quality(&cinfo, quality, TRUE /* limit to baseline-JPEG values */);
jpeg_start_compress(&cinfo, TRUE);
row_stride = image_width * 3; /* JSAMPLEs per row in image_buffer */
while (cinfo.next_scanline < cinfo.image_height)
{
row_pointer[0] = & image_buffer[(cinfo.image_height-cinfo.next_scanline-1) * row_stride];
(void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
}
jpeg_finish_compress(&cinfo);
fclose(outfile);
jpeg_destroy_compress(&cinfo);
free(image_buffer);
}
void raydium_capture_filename_auto(char *dest,char *format)
{
static int cpt=0;
time_t rawtime;
struct tm *ptm;
time(&rawtime);
ptm=gmtime(&rawtime); // localtime() ?
sprintf(dest,"raycap%i-%02i-%02i-%02i%02i%02i-%02i.%s",
ptm->tm_year+1900,
ptm->tm_mon+1,
ptm->tm_mday,
ptm->tm_hour,
ptm->tm_min,
ptm->tm_sec,
cpt,
format);
cpt++;
}
void raydium_capture_frame_auto(void)
{
char f[RAYDIUM_MAX_NAME_LEN];
raydium_capture_filename_auto(f,"tga");
raydium_capture_frame(f);
}
void raydium_capture_frame_jpeg_auto(void)
{
char f[RAYDIUM_MAX_NAME_LEN];
raydium_capture_filename_auto(f,"jpg");
raydium_capture_frame_jpeg(f);
}

29
raydium/clear.c Normal file
View File

@ -0,0 +1,29 @@
/*
Raydium - CQFD Corp.
http://raydium.org/
License: GPL - GNU General Public License, see "gpl.txt" file.
*/
#ifndef DONT_INCLUDE_HEADERS
#include "index.h"
#else
#include "headers/clear.h"
#endif
void raydium_clear_frame(void)
{
//glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glEnable(GL_STENCIL_TEST); // HDR
raydium_frame_first_camera_pass=1;
raydium_vertex_counter=0;
}
void raydium_clear_color_update(void)
{
glClearColor(raydium_background_color[0],
raydium_background_color[1],
raydium_background_color[2],
raydium_background_color[3]);
}

165
raydium/cli.c Normal file
View File

@ -0,0 +1,165 @@
/*
Raydium - CQFD Corp.
http://raydium.org/
License: GPL - GNU General Public License, see "gpl.txt" file.
*/
#ifndef DONT_INCLUDE_HEADERS
#include "index.h"
#else
#include "headers/cli.h"
#endif
char *raydium_version(void);
int raydium_init_cli_option(char *option, char *value)
{
int i;
int found;
char full_option[RAYDIUM_MAX_NAME_LEN];
char head[3];
strcpy(full_option ,"--");
strcpy(full_option+2,option);
found=0;
for(i=1;i<raydium_init_argc;i++)
if(!strcasecmp(full_option,raydium_init_argv[i]))
found=i;
if(!found) return 0; // option not found
if((found+1) >= raydium_init_argc)
{
if(value) strcpy(value,"");
return 1; // found, no value (last option of cli)
}
strncpy(head,raydium_init_argv[found+1],3);
head[2]=0;
if(!strcasecmp(head,"--"))
{
if(value) strcpy(value,"");
return 1; // found, no value (value starts with -- : is a option)
}
if(value) strcpy(value,raydium_init_argv[found+1]);
return 1;
}
int raydium_init_cli_option_default(char *option, char *value, char *default_value)
{
if(!raydium_init_cli_option(option,value))
strcpy(value,default_value);
return 1;
}
void raydium_init_internal_homedir_find(char *app_name)
{
FILE *fp;
char *str;
char *str2;
raydium_homedir[0]=0;
#ifndef WIN32
str=getenv("HOME");
str2="";
if(!str) // strange session :/
{
raydium_log("ERROR ! Unable to find HOME variable !");
exit(100);
}
#else
str=getenv("HOMEDRIVE");
str2=getenv("HOMEPATH");
if(!str || !str2)
{
raydium_log("ERROR ! Unable to find HOMEDRIVE and HOMEPATH variables !");
exit(100);
}
#endif
// right, 'str' is now the absolute home dir of user, let's build Raydium's one
// if not already given by user
if(!raydium_init_cli_option("home",raydium_homedir))
{
sprintf(raydium_homedir,"%s%s/.%s",str,str2,app_name);
}
// is writable ?
fp=fopen(raydium_file_home_path("flag"),"wt");
if(!fp)
{
if(mkdir(raydium_homedir,S_IRUSR|S_IWUSR|S_IRWXU)<0)
{
raydium_log("ERROR ! Unable to create home dir: '%s'",raydium_homedir);
exit(101);
}
}
else
{
fclose(fp);
unlink(raydium_file_home_path("flag"));
}
raydium_log("using '%s' as home dir",raydium_homedir);
}
#ifndef RAYDLL
void raydium_init_args_name(int argc, char **argv, char *app_name)
#else
void raydium_init_args_name_hack(int argc, char **argv, char *app_name)
#endif
{
int i;
char logfile[RAYDIUM_MAX_NAME_LEN];
raydium_init_argc=argc;
raydium_init_argv=malloc(argc*sizeof(char *));
for(i=0;i<argc;i++)
{
raydium_init_argv[i]=malloc(strlen(argv[i])+1);
strcpy(raydium_init_argv[i],argv[i]);
}
raydium_log("Raydium 3D Game Engine");
if(raydium_init_cli_option("logfile",logfile))
{
raydium_log_file=fopen(logfile,"wt");
if(!raydium_log_file) raydium_log("init: Warning: cannot open logfile (%s) with rw mode",logfile);
}
else raydium_log_file=NULL;
raydium_log("version %s",raydium_version());
raydium_log("command line args: OK");
#ifndef RAYDIUM_NETWORK_ONLY
raydium_file_dirname(raydium_init_wd,raydium_init_argv[0]);
if(!chdir(raydium_init_wd))
raydium_log("chdir to '%s': OK",raydium_init_wd);
else
perror("chdir");
#endif
// Find user's home directory
raydium_init_internal_homedir_find(app_name);
raydium_atexit_init();
}
#ifndef RAYDLL
void raydium_init_args (int argc, char **argv)
{
raydium_init_args_name(argc,argv,RAYDIUM_APP_SHORTNAME);
}
#else
void raydium_init_args_hack (int argc, char **argv)
{
raydium_init_args_name_hack(argc,argv,RAYDIUM_APP_SHORTNAME);
}
#endif

660
raydium/common.h Normal file
View File

@ -0,0 +1,660 @@
#ifndef _CORE_COMMON_H
#define _CORE_COMMON_H
/*
* Raydium - CQFD Corp.
* http://raydium.org/
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#define RAYDIUM_MAJOR 0
#define RAYDIUM_MINOR 705
#ifdef WIN32
# ifdef RAYDLL
# ifdef MAIN_H
# define __global __declspec(dllimport)
# define __rayapi __declspec(dllimport)
# endif
# ifdef MAIN_C
# define __global __declspec(dllexport)
# define __rayapi __declspec(dllexport)
# endif
# endif
#else // Not under WIN32
# ifdef LIBRAY
# define __global
# define __rayapi
# else
# ifdef MAIN_H
# define __global extern
# define __rayapi
# endif
# ifdef MAIN_C
# define __global
# define __rayapi
# endif
# endif
#endif
#ifdef SWIG
#define __global
#endif
#ifdef WIN32
#include "windows.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <GL/glew.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <math.h>
#include <time.h>
#include <memory.h>
#include <string.h>
#include <sys/types.h>
#include <signal.h>
#include <stdarg.h>
#include <AL/al.h>
#include <AL/alut.h>
#include <vorbis/vorbisfile.h>
#ifdef WIN32
#include <winsock2.h>
#include <ws2tcpip.h>
#endif
// need to separate LINUX & others, using glut for joystick..
#ifndef WIN32
#include <linux/joystick.h>
#include <sys/ioctl.h>
#include <linux/rtc.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <pwd.h>
#endif
#ifdef linux
#include <linux/if.h>
#include <linux/sockios.h>
#endif
#include <errno.h>
#include "config.h"
#ifdef PHP_SUPPORT
#ifdef WIN32
#define PHP_WIN32
#define ZTS
#define ZEND_WIN32
#endif
#include "php.h"
#include "php_version.h"
#include "php_globals.h"
#include "php_variables.h"
#include "zend_modules.h"
#include "SAPI.h"
#include "php.h"
//#include "build-defs.h"
#include "zend.h"
#include "zend_extensions.h"
#include "php_ini.h"
#include "php_globals.h"
#include "php_main.h"
#include "fopen_wrappers.h"
#include "ext/standard/php_standard.h"
#endif
#include <jpeglib.h>
#define PI (3.1415926535f)
// Our turn, let's define all about Raydium ...
#define RAYDIUM_APP_SHORTNAME "raydium"
#define RAYDIUM_MAX_VERTICES 2000000
#define RAYDIUM_MAX_TEXTURES 256
#define RAYDIUM_MAX_LIGHTS 8
#define RAYDIUM_MAX_NAME_LEN 255
#define RAYDIUM_MAX_DIR_LEN 4096
#define RAYDIUM_MAX_OBJECTS 1024
#define RAYDIUM_MAX_OBJECT_ANIMS 20
#define RAYDIUM_MAX_OBJECT_ANIM_INSTANCES 64
#define RAYDIUM_MAX_TIMECALLS 16
#define RAYDIUM_MAX_REG_VARIABLES 256
#define RAYDIUM_MAX_REG_FUNCTION 256
#define RAYDIUM_MAX_LOG_FOPEN 256
#define RAYDIUM_MAX_CAMERA_PATHS 16
#define RAYDIUM_MAX_CAMERA_PATH_STEPS 512
#define RAYDIUM_MAX_VIDEO_DEVICES 4
#define RAYDIUM_MAX_LIVE_TEXTURES 8
#define RAYDIUM_MAX_VIDEOS 4
#define RAYDIUM_MAX_SHADERS 32
#define RAYDIUM_LIGHT_ON 1
#define RAYDIUM_LIGHT_BLINKING 2
#define RAYDIUM_LIGHT_OFF -1
#define RAYDIUM_TEXTURE_FILTER_NONE 0
#define RAYDIUM_TEXTURE_FILTER_BILINEAR 1
#define RAYDIUM_TEXTURE_FILTER_TRILINEAR 2
#define RAYDIUM_TEXTURE_BLEND_NONE 0
#define RAYDIUM_TEXTURE_BLEND_BLENDED 1
#define RAYDIUM_TEXTURE_BLEND_CUTOUT 2
#define RAYDIUM_TEXTURE_PHANTOM 3
#define RAYDIUM_RENDERING_WINDOW 0
#define RAYDIUM_RENDERING_FULLSCREEN 1
#define RAYDIUM_RENDERING_NONE 2
#define RAYDIUM_PROJECTION_ORTHO 0
#define RAYDIUM_PROJECTION_PERSPECTIVE 1
#define RAYDIUM_KEYBOARD_SIZE 256
#define RAYDIUM_JOY_MAX_BUTTONS 16
#define RAYDIUM_JOY_MAX_AXIS 8
#define RAYDIUM_NETWORK_PORT 29104
#define RAYDIUM_NETWORK_BEACON_PORT (RAYDIUM_NETWORK_PORT+1)
#define RAYDIUM_NETWORK_PACKET_SIZE 512
#define RAYDIUM_NETWORK_TIMEOUT 10
#define RAYDIUM_NETWORK_PACKET_OFFSET 4
#define RAYDIUM_NETWORK_MAX_CLIENTS 8
#define RAYDIUM_NETWORK_MAX_SERVERS 32 // LAN server list
#define RAYDIUM_NETWORK_TX_QUEUE_SIZE 128
#define RAYDIUM_NETWORK_MAX_TRIES 8
#define RAYDIUM_NETWORK_MAX_NETCALLS 32
#define RAYDIUM_NETWORK_MAX_PROPAGS 32
#define RAYDIUM_NETWORK_ACK_DELAY_MAX 2
#define RAYDIUM_NETWORK_PROPAG_HEAD sizeof(int)
#define RAYDIUM_NETWORK_BEACON_DELAY 5
#define RAYDIUM_NETWORK_BEACON_DEFAULT_TTL 15
#define RAYDIUM_NETWORK_BEACON_INFO_MAX_LEN 100
#define RAYDIUM_NETWORK_MODE_NONE 0
#define RAYDIUM_NETWORK_MODE_CLIENT 1
#define RAYDIUM_NETWORK_MODE_SERVER 2
#define RAYDIUM_NETWORK_MODE_DISCOVER 3
//#define RAYDIUM_NETWORK_TCP SOCK_STREAM
#define RAYDIUM_NETWORK_UDP SOCK_DGRAM
#define RAYDIUM_NETWORK_DATA_OK 1
#define RAYDIUM_NETWORK_DATA_NONE 0
#define RAYDIUM_NETWORK_DATA_ERROR -1
#define RAYDIUM_NETWORK_PACKET_DATA 1
#define RAYDIUM_NETWORK_PACKET_ERROR_NO_MORE_PLACE 2
#define RAYDIUM_NETWORK_PACKET_ATTRIB_UID 3
#define RAYDIUM_NETWORK_PACKET_REQUEST_UID 4
#define RAYDIUM_NETWORK_PACKET_INFO_NAME 5
#define RAYDIUM_NETWORK_PACKET_ACK 6
#define RAYDIUM_NETWORK_PACKET_SERVER_BEACON 7
#define RAYDIUM_NETWORK_PACKET_ODE_DATA 10
#define RAYDIUM_NETWORK_PACKET_ODE_NEWELEM 11
#define RAYDIUM_NETWORK_PACKET_ODE_REMELEM 12
#define RAYDIUM_NETWORK_PACKET_ODE_NIDWHO 13
#define RAYDIUM_NETWORK_PACKET_ODE_EXPLOSION 14
#define RAYDIUM_NETWORK_PACKET_BASE 20
#define RAYDIUM_SOUND_NUM_BUFFERS 30
#define RAYDIUM_SOUND_NUM_SOURCES 30
#define SOUNDDATASIZE (4096*20)
//#define RAYDIUM_SOUND_NUM_ENVIRONMENTS 1
#define RAYDIUM_CONSOLE_MAX_LINES 18
#define RAYDIUM_CONSOLE_MAX_HISTORY 1000
#define RAYDIUM_CONSOLE_FONT_SIZE 16
#define RAYDIUM_CONSOLE_FONT_SPACER 0.5
#define RAYDIUM_CONSOLE_MAX_COMPLETION 10
#define RAYDIUM_TIMECALL_METHOD_NONE 0
#define RAYDIUM_TIMECALL_METHOD_CLOCK 1
#define RAYDIUM_TIMECALL_METHOD_DEVRTC 2
#define RAYDIUM_TIMECALL_FREQ_MIN 100
#define RAYDIUM_TIMECALL_FREQ_PREFERED 8192
#define RAYDIUM_TIMECALL_W32_MODULO_MIN 15
#define RAYDIUM_REGISTER_INT 1
#define RAYDIUM_REGISTER_FLOAT 2
#define RAYDIUM_REGISTER_STR 3
#define RAYDIUM_REGISTER_ICONST 4
#define RAYDIUM_REGISTER_FCONST 5
#define RAYDIUM_REGISTER_SCHAR 6
#define RAYDIUM_PARSER_TYPE_EOF 0
#define RAYDIUM_PARSER_TYPE_FLOAT 1
#define RAYDIUM_PARSER_TYPE_STRING 2
#define RAYDIUM_PARSER_TYPE_DEBUG 3
#define RAYDIUM_PARSER_TYPE_RAWDATA 4
#define RAYDIUM_OSD_FONT_SIZE_FACTOR (12.f)
#define RAYDIUM_RENDER_MULTITEX_AUTO_UV_FACT (50.f)
#define RAYDIUM_RENDER_REFLECTION_FACT (0.1f)
#define RAYDIUM_SKY_SPHERE_MAX_DETAIL 30
#define RAYDIUM_SKY_SPHERE_DEFAULT_DETAIL 25
#define RAYDIUM_CAPTURE_NONE 0
#define RAYDIUM_CAPTURE_TGA 1
#define RAYDIUM_CAPTURE_JPG 2
#define RAYDIUM_DB_FILENAME raydium_file_home_path("raydium.db")
#define RAYDIUM_DB_TEMP raydium_file_home_path("raydium.db.temp")
#define RAYDIUM_DB_SEPARATOR ';'
#define RAYDIUM_HDR_SIZE 64
#define RAYDIUM_HDR_PASS 8
#define RAYDIUM_HDR_EYE_SPEED_DEFAULT 0.1f
#define RAYDIUM_FOG_MODE_LINEAR GL_LINEAR
#define RAYDIUM_FOG_MODE_EXP GL_EXP
#define RAYDIUM_FOG_MODE_EXP2 GL_EXP2
__global int raydium_init_argc;
__global char **raydium_init_argv;
__global char raydium_init_wd[RAYDIUM_MAX_DIR_LEN];
__global char raydium_homedir[RAYDIUM_MAX_DIR_LEN];
__global int raydium_key_last;
__global signed char raydium_key[RAYDIUM_KEYBOARD_SIZE];
__global signed char raydium_key_trace; // change this from ingame console !
__global signed char raydium_mouse_click;
__global signed char raydium_mouse_button[3];
__global GLuint raydium_mouse_x;
__global GLuint raydium_mouse_y;
__global signed char raydium_joy_button[RAYDIUM_JOY_MAX_BUTTONS];
__global GLfloat raydium_joy_axis[RAYDIUM_JOY_MAX_AXIS];
__global signed char raydium_joy_click;
__global GLfloat raydium_joy_x;
__global GLfloat raydium_joy_y;
__global GLfloat raydium_joy_z;
__global int raydium_joy;
__global char raydium_joy_n_axes; // read only
__global char raydium_joy_n_buttons; // read only
__global GLuint raydium_texture_index;
__global GLuint raydium_texture_current_main;
__global GLuint raydium_texture_current_multi;
__global GLfloat raydium_texture_current_multi_u;
__global GLfloat raydium_texture_current_multi_v;
__global GLuint raydium_texture_current_env;
__global signed char raydium_texture_filter;
__global GLint raydium_texture_size_max;
__global GLint raydium_texture_units;
__global GLuint raydium_internal_size_vector_float_4;
__global GLuint raydium_texture_to_replace;
__global GLfloat raydium_texture_used_memory;
__global signed char raydium_projection;
__global GLfloat raydium_projection_fov; // perspective only
__global GLfloat raydium_projection_near; // perspective & ortho
__global GLfloat raydium_projection_far; // perspective & ortho
__global GLfloat raydium_projection_left; // ortho only
__global GLfloat raydium_projection_right; // ortho only
__global GLfloat raydium_projection_bottom; // ortho only
__global GLfloat raydium_projection_top; // ortho only
__global GLfloat raydium_background_color[4];
__global signed char raydium_sky_force;
__global signed char raydium_sky_atmosphere_enable_tag;
__global GLfloat raydium_sky_sphere_angle_orbit_u;
__global GLfloat raydium_sky_sphere_angle_orbit_v;
__global GLfloat raydium_sky_sphere_x_vel;
__global GLfloat raydium_sky_sphere_y_vel;
__global GLfloat raydium_sky_sphere_x_pos;
__global GLfloat raydium_sky_sphere_y_pos;
__global GLfloat raydium_sky_sphere_quality;
__global GLfloat raydium_sky_sphere_heigth;
__global signed char raydium_sky_sphere_generated;
__global GLsizei raydium_window_tx;
__global GLsizei raydium_window_ty;
__global signed char raydium_window_mode;
__global GLuint raydium_vertex_index;
__global GLuint raydium_vertex_counter;
__global signed char raydium_vertex_offset_triangle;
__global GLfloat *raydium_vertex_x;
__global GLfloat *raydium_vertex_y;
__global GLfloat *raydium_vertex_z;
__global GLfloat *raydium_vertex_normal_x;
__global GLfloat *raydium_vertex_normal_y;
__global GLfloat *raydium_vertex_normal_z;
__global GLfloat *raydium_vertex_normal_visu_x; //
__global GLfloat *raydium_vertex_normal_visu_y; // used for smoothing
__global GLfloat *raydium_vertex_normal_visu_z; //
__global GLfloat *raydium_vertex_texture_u;
__global GLfloat *raydium_vertex_texture_v;
__global GLuint *raydium_vertex_texture;
__global GLuint *raydium_vertex_texture_multi;
__global GLfloat *raydium_vertex_texture_multi_u;
__global GLfloat *raydium_vertex_texture_multi_v;
__global GLuint *raydium_vertex_texture_env;
__global signed char *raydium_vertex_tag;
__global signed char raydium_texture_islightmap[RAYDIUM_MAX_TEXTURES];
__global signed char raydium_texture_nolight[RAYDIUM_MAX_TEXTURES];
__global signed char raydium_texture_blended[RAYDIUM_MAX_TEXTURES];
__global signed char raydium_texture_hdr[RAYDIUM_MAX_TEXTURES];
__global signed char raydium_texture_env[RAYDIUM_MAX_TEXTURES];
__global GLint raydium_texture_shader[RAYDIUM_MAX_TEXTURES];
__global char raydium_texture_name[RAYDIUM_MAX_TEXTURES][RAYDIUM_MAX_NAME_LEN];
__global GLfloat raydium_texture_rgb[RAYDIUM_MAX_TEXTURES][4];
__global GLuint raydium_object_index;
__global GLuint raydium_object_start[RAYDIUM_MAX_OBJECTS];
__global GLuint raydium_object_end[RAYDIUM_MAX_OBJECTS];
__global char raydium_object_name[RAYDIUM_MAX_OBJECTS][RAYDIUM_MAX_NAME_LEN];
__global signed char raydium_object_anims[RAYDIUM_MAX_OBJECTS]; // number of anims
__global GLuint raydium_object_anim_len[RAYDIUM_MAX_OBJECTS]; // len of each anim
__global GLuint raydium_object_anim_start[RAYDIUM_MAX_OBJECTS][RAYDIUM_MAX_OBJECT_ANIMS];
__global GLuint raydium_object_anim_end[RAYDIUM_MAX_OBJECTS][RAYDIUM_MAX_OBJECT_ANIMS];
__global char raydium_object_anim_names[RAYDIUM_MAX_OBJECTS][RAYDIUM_MAX_OBJECT_ANIMS][RAYDIUM_MAX_NAME_LEN]; // anims name array
__global GLuint raydium_object_anim_default_anim[RAYDIUM_MAX_OBJECTS];
__global GLuint raydium_object_anim_instance_current[RAYDIUM_MAX_OBJECTS]; // current "rendering" instance
__global GLfloat raydium_object_anim_automatic_factor[RAYDIUM_MAX_OBJECTS][RAYDIUM_MAX_OBJECT_ANIMS]; // frame automatic factor
__global GLfloat raydium_object_anim_time_factor;
// states
__global int raydium_object_anim_current[RAYDIUM_MAX_OBJECTS][RAYDIUM_MAX_OBJECT_ANIM_INSTANCES]; // current anim
__global GLfloat raydium_object_anim_frame_current[RAYDIUM_MAX_OBJECTS][RAYDIUM_MAX_OBJECT_ANIM_INSTANCES]; // current frame
__global int raydium_object_anim_previous[RAYDIUM_MAX_OBJECTS][RAYDIUM_MAX_OBJECT_ANIM_INSTANCES]; // anim switch blending (last anim)
__global GLfloat raydium_object_anim_frame_previous[RAYDIUM_MAX_OBJECTS][RAYDIUM_MAX_OBJECT_ANIM_INSTANCES]; // anim switch blending (last frame)
__global GLfloat raydium_object_anim_frame_previous_timeout[RAYDIUM_MAX_OBJECTS][RAYDIUM_MAX_OBJECT_ANIM_INSTANCES]; // "timer" for anim switch blending
__global int raydium_object_anim_punctually_flag[RAYDIUM_MAX_OBJECTS][RAYDIUM_MAX_OBJECT_ANIM_INSTANCES];
__global int raydium_render_fps;
__global GLfloat raydium_render_rgb_force[4];
__global GLfloat raydium_render_lightmap_color_value[4];
__global signed char raydium_render_rgb_force_tag;
__global char raydium_render_displaylists_tag;
__global GLboolean raydium_render_internal_light_previous_step;
__global signed char raydium_fog_enabled_tag;
__global signed char raydium_fog_volumetric_enabled_tag;
__global int raydium_fog_mode_value;
__global float raydium_fog_far_value;
__global float raydium_fog_near_value;
__global float raydium_fog_density_value;
__global GLfloat * raydium_fog_volumetric_array;
__global signed char raydium_light_enabled_tag;
__global signed char raydium_light_internal_state[RAYDIUM_MAX_LIGHTS];
__global GLfloat raydium_light_position[RAYDIUM_MAX_LIGHTS][4];
__global GLfloat raydium_light_color[RAYDIUM_MAX_LIGHTS][4];
__global GLfloat raydium_light_intensity[RAYDIUM_MAX_LIGHTS];
__global GLfloat raydium_light_blink_low[RAYDIUM_MAX_LIGHTS];
__global GLfloat raydium_light_blink_high[RAYDIUM_MAX_LIGHTS];
__global GLfloat raydium_light_blink_increment[RAYDIUM_MAX_LIGHTS];
// TODO: light_spot
__global signed char raydium_internal_vertex_next_extras;
__global GLfloat raydium_internal_vertex_next_u;
__global GLfloat raydium_internal_vertex_next_v;
__global GLfloat raydium_internal_vertex_next_nx;
__global GLfloat raydium_internal_vertex_next_ny;
__global GLfloat raydium_internal_vertex_next_nz;
__global signed char raydium_frame_first_camera_pass;
__global float raydium_frame_time;
__global GLfloat raydium_camera_x;
__global GLfloat raydium_camera_y; // read only, undocumented.
__global GLfloat raydium_camera_z;
__global signed char raydium_camera_pushed;
__global GLfloat raydium_camera_cursor_place[3];
__global GLfloat raydium_camera_look_at_roll;
__global GLfloat raydium_camera_rumble_amplitude;
__global GLfloat raydium_camera_rumble_evolution;
__global GLfloat raydium_camera_rumble_remaining;
typedef struct raydium_camera_Path
{
char name[RAYDIUM_MAX_NAME_LEN];
GLfloat x[RAYDIUM_MAX_CAMERA_PATH_STEPS];
GLfloat y[RAYDIUM_MAX_CAMERA_PATH_STEPS];
GLfloat z[RAYDIUM_MAX_CAMERA_PATH_STEPS];
GLfloat zoom[RAYDIUM_MAX_CAMERA_PATH_STEPS];
GLfloat roll[RAYDIUM_MAX_CAMERA_PATH_STEPS];
int steps;
} raydium_camera_Path;
__global raydium_camera_Path raydium_camera_path[RAYDIUM_MAX_CAMERA_PATHS];
__global signed char raydium_camera_path_reset_flag;
__global int raydium_network_socket;
__global int raydium_network_uid;
__global signed char raydium_network_mode;
__global signed char raydium_network_client[RAYDIUM_NETWORK_MAX_CLIENTS];
__global time_t raydium_network_start;
__global struct sockaddr
raydium_network_client_addr[RAYDIUM_NETWORK_MAX_CLIENTS];
__global time_t raydium_network_keepalive[RAYDIUM_NETWORK_MAX_CLIENTS];
__global char raydium_network_name_local[RAYDIUM_MAX_NAME_LEN];
__global char raydium_network_name[RAYDIUM_NETWORK_MAX_CLIENTS][RAYDIUM_MAX_NAME_LEN];
__global char raydium_network_connected_server[RAYDIUM_MAX_NAME_LEN];
__global int raydium_network_netcall_type[RAYDIUM_NETWORK_MAX_NETCALLS];
__global void * raydium_network_netcall_func[RAYDIUM_NETWORK_MAX_NETCALLS];
__global signed char raydium_network_netcall_tcp[RAYDIUM_NETWORK_MAX_NETCALLS];
__global void * raydium_network_on_connect;
__global void * raydium_network_on_disconnect;
__global int raydium_network_stat_rx;
__global int raydium_network_stat_tx;
__global int raydium_network_stat_reemitted;
__global int raydium_network_stat_double;
__global int raydium_network_stat_lost;
__global int raydium_network_stat_bogus_ack;
typedef struct raydium_network_Tcp
{
signed char state;
unsigned short tcpid;
char packet[RAYDIUM_NETWORK_PACKET_SIZE];
unsigned long time;
unsigned short retries_left;
struct sockaddr to;
int to_player;
} raydium_network_Tcp;
__global raydium_network_Tcp raydium_network_queue[RAYDIUM_NETWORK_TX_QUEUE_SIZE];
__global int raydium_network_queue_index;
__global unsigned short raydium_network_tcpid_i[RAYDIUM_NETWORK_TX_QUEUE_SIZE]; // ID
__global int raydium_network_tcpid_p[RAYDIUM_NETWORK_TX_QUEUE_SIZE]; // Player
__global int raydium_network_tcpid_index;
__global unsigned long raydium_netwok_queue_ack_delay_client;
__global unsigned long raydium_netwok_queue_ack_delay_server[RAYDIUM_NETWORK_MAX_CLIENTS];
__global signed char raydium_network_write_notcp;
typedef struct raydium_network_Propag
{
signed char state;
int type;
unsigned short size;
unsigned int version;
void *data;
} raydium_network_Propag;
__global raydium_network_Propag raydium_network_propag[RAYDIUM_NETWORK_MAX_PROPAGS];
typedef struct raydium_network_Beacon
{
int id;
char name[RAYDIUM_MAX_NAME_LEN];
char ip[RAYDIUM_MAX_NAME_LEN];
char info[RAYDIUM_NETWORK_BEACON_INFO_MAX_LEN];
int player_count;
int player_max;
unsigned long when; // 0 means "free"
} raydium_network_Beacon;
typedef struct raydium_network_BeaconSearch
{
signed char active;
char app_or_mod[RAYDIUM_MAX_NAME_LEN];
int version;
} raydium_network_BeaconSearch;
__global raydium_network_Beacon raydium_network_server_list[RAYDIUM_NETWORK_MAX_SERVERS];
__global char raydium_network_beacon[RAYDIUM_NETWORK_PACKET_SIZE];
__global int raydium_network_beacon_info_offset;
__global raydium_network_BeaconSearch raydium_network_beacon_search;
#ifdef linux
#define RAYDIUM_NETWORK_BROADCAST_INTERFACE_MAX 8
__global int raydium_network_broadcast_interface_index;
__global struct sockaddr_in raydium_network_broadcast_interfaces[RAYDIUM_NETWORK_BROADCAST_INTERFACE_MAX];
#endif
__global ALuint raydium_sound_buffer[RAYDIUM_SOUND_NUM_BUFFERS];
__global ALuint raydium_sound_source[RAYDIUM_SOUND_NUM_SOURCES];
__global ALfloat raydium_sound_source_fade_factor[RAYDIUM_SOUND_NUM_SOURCES];
__global char raydium_sound_source_fade_tofile[RAYDIUM_SOUND_NUM_SOURCES][RAYDIUM_MAX_NAME_LEN];
__global ALfloat raydium_sound_DefaultReferenceDistance;
__global int raydium_sound;
__global int raydium_sound_top_buffer;
__global char raydium_sound_music_buf[SOUNDDATASIZE];
__global FILE *raydium_sound_music_file;
__global OggVorbis_File raydium_sound_vf;
__global vorbis_info *raydium_sound_ogginfo;
__global int (*raydium_sound_music_eof_callback)(char *);
__global void (*raydium_sound_music_changed_callback)(void);
typedef struct raydium_sound_music_Info {
char artist[RAYDIUM_MAX_NAME_LEN];
char title [RAYDIUM_MAX_NAME_LEN];
char album [RAYDIUM_MAX_NAME_LEN];
} raydium_sound_music_Info;
__global raydium_sound_music_Info raydium_sound_music_info;
__global GLfloat raydium_osd_logo_angle;
__global GLuint raydium_osd_cursor_texture;
__global GLfloat raydium_osd_cursor_xsize;
__global GLfloat raydium_osd_cursor_ysize;
__global GLfloat raydium_osd_color[4];
#ifdef MAIN_C
__global GLfloat raydium_osd_ega[]=
{
0.0f, 0.0f, 0.0f, // 0: black
0.0f, 0.0f, 0.6f, // 1: blue
0.0f, 0.6f, 0.0f, // 2: green
0.0f, 0.6f, 0.6f, // 3: cyan
0.6f, 0.0f, 0.0f, // 4: red
0.6f, 0.0f, 0.6f, // 5: purple
0.6f, 0.3f, 0.0f, // 6: brown
0.6f, 0.6f, 0.6f, // 7: white
0.3f, 0.3f, 0.3f, // 8: grey
0.3f, 0.3f, 1.0f, // 9: light blue
0.3f, 1.0f, 0.3f, // A: light green
0.3f, 1.0f, 1.0f, // B: light cyan
1.0f, 0.3f, 0.3f, // C: light red
1.0f, 0.3f, 1.0f, // D: light purple
1.0f, 1.0f, 0.3f, // E: light yellow
1.0f, 1.0f, 1.0f // F: light white
};
#else
__global GLfloat raydium_osd_ega[48];
#endif
__global GLfloat raydium_osd_fade_color_timeleft;
__global GLfloat raydium_osd_fade_color_increment[4];
__global GLfloat raydium_osd_fade_color_current[4];
__global void * raydium_osd_fade_OnFadeEnd;
__global GLfloat raydium_console_pos;
__global GLfloat raydium_console_inc;
__global GLfloat raydium_console_config_max;
__global GLfloat raydium_console_config_speed;
__global char raydium_console_config_texture[RAYDIUM_MAX_NAME_LEN];
__global char raydium_console_config_font[RAYDIUM_MAX_NAME_LEN];
__global GLfloat raydium_console_cursor_blink;
__global char raydium_console_lines[RAYDIUM_CONSOLE_MAX_LINES][RAYDIUM_MAX_NAME_LEN];
__global int raydium_console_line_last;
__global char raydium_console_get_string[RAYDIUM_MAX_NAME_LEN];
__global char raydium_console_get_string_last[RAYDIUM_MAX_NAME_LEN];
__global void * raydium_console_gets_callback;
__global char raydium_console_history[RAYDIUM_CONSOLE_MAX_HISTORY][RAYDIUM_MAX_NAME_LEN];
__global int raydium_console_history_index; // store
__global int raydium_console_history_index_current; // user
__global char raydium_console_history_filename[RAYDIUM_MAX_NAME_LEN];
__global int raydium_timecall_index;
__global signed char raydium_timecall_method;
__global unsigned long raydium_timecall_max_frequency;
__global unsigned long raydium_timecall_clocks_per_sec;
__global int raydium_timecall_devrtc_handle;
__global unsigned long raydium_timecall_devrtc_clocks;
__global void * raydium_timecall_funct[RAYDIUM_MAX_TIMECALLS];
__global GLint raydium_timecall_soft_call[RAYDIUM_MAX_TIMECALLS];
__global clock_t raydium_timecall_interval[RAYDIUM_MAX_TIMECALLS];
__global clock_t raydium_timecall_next[RAYDIUM_MAX_TIMECALLS];
__global int raydium_timecall_w32_divmodulo;
__global signed char raydium_shadow_tag;
__global signed char raydium_shadow_rendering;
__global int raydium_shadow_ground_mesh;
__global signed char raydium_capture_asked;
__global char raydium_capture_filename[RAYDIUM_MAX_NAME_LEN];
__global signed char raydium_hdr_state;
__global signed char raydium_hdr_generated;
__global int raydium_hdr_texture_id;
__global float raydium_hdr_eye;
__global float raydium_hdr_eye_speed;
__global float raydium_hdr_alpha_max;
__global GLfloat raydium_hdr_color_local[4];
__global GLfloat raydium_hdr_color_ambient[4];
__global unsigned char *raydium_hdr_mem;
__global unsigned char *raydium_hdr_mem_hdr;
__global unsigned char *raydium_hdr_mem_hdr2;
__global unsigned char *raydium_hdr_mem_hdr3;
__global int raydium_register_variable_index;
__global int raydium_register_function_index;
__global char raydium_register_variable_name[RAYDIUM_MAX_REG_VARIABLES][RAYDIUM_MAX_NAME_LEN];
__global void * raydium_register_variable_addr[RAYDIUM_MAX_REG_VARIABLES];
__global int raydium_register_variable_type[RAYDIUM_MAX_REG_VARIABLES];
#ifdef PHP_SUPPORT
#define ZFE zend_function_entry
#else
#define ZFE void *
#endif
__global ZFE raydium_register_function_list[RAYDIUM_MAX_REG_FUNCTION];
__global char raydium_php_rayphp_path[RAYDIUM_MAX_NAME_LEN];
__global FILE *raydium_log_file;
__global char raydium_file_log_fopen[RAYDIUM_MAX_LOG_FOPEN][RAYDIUM_MAX_NAME_LEN];
__global int raydium_file_log_fopen_index;
typedef struct matrix4x4
{
double ray[16];
} matrix4x4;
#endif
// EOF

73
raydium/config.h Normal file
View File

@ -0,0 +1,73 @@
/*
Raydium - CQFD Corp.
http://raydium.org/
License: GPL - GNU General Public License, see "gpl.txt" file.
*/
// Raydium configuration file
// For other options, see common.h
// Enable PHP support
#ifndef NO_PHP_SUPPORT
#define PHP_SUPPORT
#define PHP_INI_PATH "./"
#endif
#ifndef NO_ODE_SUPPORT
// Enable ODE physics support
#define ODE_SUPPORT
#define ODE_QUICKSTEP
#define ODE_PREDICTION
//#define ODE_NETWORK_GHOSTS
#endif
// RegApi Support (exports Raydium API to PHP)
#define REG_API
// enable profiling
#define DEBUG_PROFILE
// (link to OpenAL is always required !)
//#define NO_SOUND_DEBUG
// Allow Xinerama Support for X11
#define HAVE_XINERAMA
// will highlight triangle with tag != 0 at render time :
//#define RENDER_DEBUG_TAG
// disable clipping
//#define RENDER_DEBUG_NO_CLIP
// disable display list optims
//#define DEBUG_RENDER_DISABLE_DISPLAYLISTS
// draw shadow map (view from main light)
//#define DEBUG_SHADOW_MAP_VIEW
// draw HDR stencil (press F10)
//#define DEBUG_HDR_STENCIL
// debug network "tcp style" ACKs
//#define DEBUG_NETWORK
// debug ODE Network interface (verbose !)
//#define DEBUG_ODENET
// enable movie linear framerate (1/x sec)
// press F11 and see movie/ subdir [or create it]
//#define DEBUG_MOVIE 25
// allow vertex lighting for lightmaps textures
//#define RENDER_ALLOW_LIGHTING_FOR_LIGHTMAPS
// raydium_capture_frame_jpeg() JPEG quality percentage
#define DEBUG_JPEG_QUALITY 75
// axis used by Volumetric Fog when rendering meshes
// values: 0=x y=1 z=2
#define RENDER_VOLUMETRIC_FOG_AXIS 2
// reverse values from axis ?
#define RENDER_VOLUMETRIC_FOG_AXIS_REVERSE

483
raydium/console.c Normal file
View File

@ -0,0 +1,483 @@
/*
Raydium - CQFD Corp.
http://raydium.org/
License: GPL - GNU General Public License, see "gpl.txt" file.
*/
#ifndef DONT_INCLUDE_HEADERS
#include "index.h"
#else
#include "headers/console.h"
#endif
// proto
void raydium_console_exec_last_command(void);
void raydium_console_history_add(char *str);
void raydium_console_init(void)
{
int i;
FILE *fp;
char line[RAYDIUM_MAX_NAME_LEN];
raydium_console_pos=0;
raydium_console_inc=0;
raydium_console_config_max=50;
raydium_console_config_speed=3;
raydium_init_cli_option_default("consoletexture",raydium_console_config_texture,"rgb(0.2,0.2,0.2)");
raydium_init_cli_option_default("consolefont",raydium_console_config_font,"font2.tga");
raydium_console_line_last=-1;
raydium_console_cursor_blink=0;
for(i=0;i<RAYDIUM_CONSOLE_MAX_LINES;i++)
raydium_console_lines[i][0]=0;
raydium_console_get_string[0]=0;
raydium_console_get_string_last[0]=0;
raydium_init_cli_option_default("history",raydium_console_history_filename,
raydium_file_home_path("raydium_history"));
for(i=0;i<RAYDIUM_CONSOLE_MAX_HISTORY;i++)
raydium_console_history[i][0]=0;
raydium_console_history_index_current=-1;
raydium_console_history_index=0;
fp=fopen(raydium_console_history_filename,"rt");
if(fp)
{
while(fgets(line,RAYDIUM_MAX_NAME_LEN,fp))
{
line[strlen(line)-1]=0;
raydium_console_history_add(line);
}
fclose(fp);
}
}
void raydium_console_history_save(void)
{
int i;
FILE *fp;
char last[RAYDIUM_MAX_NAME_LEN];
last[0]=0;
fp=fopen(raydium_console_history_filename,"wt");
if(!fp)
{
raydium_log("console: error: cannot save history file ('%s')",raydium_console_history_filename);
return;
}
for(i=0;i<raydium_console_history_index;i++)
if(strcmp(raydium_console_history[i],last))
{
strcpy(last,raydium_console_history[i]);
fprintf(fp,"%s\n",raydium_console_history[i]);
}
fclose(fp);
}
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// Now DISABLED,
// use raydium_console_gets_callback fptr instead.
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
int raydium_console_gets(char *where)
{
raydium_log("ERROR: raydium_console_gets is now DISABLED ! See API doc.");
// always here for compat' only, do not use.
/*if(strlen(raydium_console_get_string_last))
{
strcpy(where,raydium_console_get_string_last);
raydium_console_get_string_last[0]=0;
return 1;
} else*/ return 0;
}
void raydium_console_history_previous(void)
{
raydium_console_history_index_current--;
if(raydium_console_history_index_current<0)
{
raydium_console_history_index_current=0;
return;
}
strcpy(raydium_console_get_string,raydium_console_history[raydium_console_history_index_current]);
}
void raydium_console_history_next(void)
{
raydium_console_history_index_current++;
if(raydium_console_history_index_current>=raydium_console_history_index)
{
raydium_console_history_index_current=raydium_console_history_index;
strcpy(raydium_console_get_string,"");
return;
}
strcpy(raydium_console_get_string,raydium_console_history[raydium_console_history_index_current]);
}
void raydium_console_history_add(char *str)
{
int i;
if(raydium_console_history_index==RAYDIUM_CONSOLE_MAX_HISTORY)
{
raydium_console_history_index_current=raydium_console_history_index;
/*
printf("-----\n");
for(i=0;i<RAYDIUM_CONSOLE_MAX_HISTORY;i++)
printf("%s\n",raydium_console_history[i]);
*/
for(i=0;i<RAYDIUM_CONSOLE_MAX_HISTORY-1;i++)
strcpy(raydium_console_history[i],raydium_console_history[i+1]);
strcpy(raydium_console_history[RAYDIUM_CONSOLE_MAX_HISTORY-1],str);
/*
printf("-----\n");
for(i=0;i<RAYDIUM_CONSOLE_MAX_HISTORY;i++)
printf("%s\n",raydium_console_history[i]);
*/
return;
}
raydium_console_history_index_current=raydium_console_history_index+1;
strcpy(raydium_console_history[raydium_console_history_index],str);
raydium_console_history_index++;
}
void raydium_console_exec_script(char *file)
{
FILE *fp;
char command[RAYDIUM_MAX_NAME_LEN];
if(!raydium_console_gets_callback)
{
raydium_log("ERROR: console: script: no command callback is defined, aborded.");
return;
}
fp=raydium_file_fopen(file,"rt");
if(!fp)
{
raydium_log("ERROR: console: script: file not found \"%s\"",file);
return;
}
while(fgets(command,RAYDIUM_MAX_NAME_LEN,fp))
{
strcpy(raydium_console_get_string_last,command);
raydium_console_exec_last_command();
}
fclose(fp);
}
void raydium_console_exec_last_command(void)
{
int treated=0;
void (*f)(char *);
char temp[RAYDIUM_MAX_NAME_LEN];
raydium_console_get_string_last[strlen(raydium_console_get_string_last)-1]=0;
raydium_console_history_add(raydium_console_get_string_last);
if(raydium_console_get_string_last[0]=='!')
{
treated=1;
raydium_console_exec_script(raydium_console_get_string_last+1);
}
if(raydium_console_get_string_last[0]=='>')
{
treated=1;
#ifdef PHP_SUPPORT
raydium_php_exec(raydium_console_get_string_last+1);
#else
raydium_log("ERROR: No PHP support compiled");
#endif
}
if(raydium_console_get_string_last[0]!='/' && !treated)
{
#ifdef PHP_SUPPORT
#define TEMPFILE raydium_file_home_path("temp.delme.php")
FILE *fp;
fp=fopen(TEMPFILE,"wt");
if(!fp) { raydium_log("console: php call: cannot create %s temporary file",TEMPFILE); return; }
fprintf(fp,"<? %s; ?>",raydium_console_get_string_last);
fclose(fp);
raydium_php_exec(TEMPFILE);
treated=1; // all is sended to PHP for now
#endif
}
if(!treated && raydium_console_gets_callback)
{
f=raydium_console_gets_callback;
strcpy(temp,raydium_console_get_string_last+1);
f(temp);
}
}
void raydium_console_line_add(char *format, ...)
{
va_list argptr;
int retlen;
raydium_console_line_last++;
if(raydium_console_line_last>=RAYDIUM_CONSOLE_MAX_LINES)
raydium_console_line_last=0;
va_start(argptr,format);
retlen = vsnprintf(raydium_console_lines[raydium_console_line_last],RAYDIUM_MAX_NAME_LEN - 1,format,argptr);
va_end(argptr);
if(retlen < 0) retlen = 0;
raydium_console_lines[raydium_console_line_last][retlen] = '\0';
}
int raydium_console_history_read(char **hist)
{
int i,start,cpt=0;
cpt=0;
start=raydium_console_line_last;
//for(i=RAYDIUM_CONSOLE_MAX_LINES-1;i>raydium_console_line_last;i--)
for(i=raydium_console_line_last+1;i<RAYDIUM_CONSOLE_MAX_LINES;i++)
{
hist[cpt]=raydium_console_lines[i];
cpt++;
}
//for(i=start;i>=0;i--)
for(i=0;i<=start;i++)
{
hist[cpt]=raydium_console_lines[i];
cpt++;
}
return cpt++;
}
void raydium_console_event(void)
{
#ifdef PHP_SUPPORT
static signed char first=1;
if(first)
{
raydium_texture_find_by_name(raydium_console_config_texture); // cache
// raydium_texture_find_by_name(RAYDIUM_CONSOLE_FONT_SIZE); // cache
raydium_log(" --- This console provides a PHP parser and text completion ---");
first=0;
}
#endif
if(raydium_console_inc!=0) raydium_console_inc*=-1;
else {
if(raydium_console_pos==0) raydium_console_inc=raydium_console_config_speed;
else raydium_console_inc=-raydium_console_config_speed;
}
}
void raydium_console_draw(void)
{
GLfloat y,off;
int i,cpt;
int texsave;
char *hist[RAYDIUM_CONSOLE_MAX_LINES];
raydium_console_pos+=raydium_console_inc*(raydium_frame_time*100);
if(raydium_console_pos<0)
{
raydium_console_pos=0;
raydium_console_inc=0;
}
if(raydium_console_pos>raydium_console_config_max)
{
raydium_console_pos=raydium_console_config_max;
raydium_console_inc=0;
}
if(!raydium_console_pos) return;
raydium_osd_start();
texsave=raydium_texture_current_main;
raydium_texture_current_set_name(raydium_console_config_texture);
raydium_rendering_internal_prepare_texture_render(raydium_texture_current_main);
off=raydium_console_config_max-raydium_console_pos;
glBegin(GL_QUADS);
glTexCoord2f(0,0);
glVertex3f(0,100-raydium_console_pos,0);
glTexCoord2f(1,0);
glVertex3f(100,100-raydium_console_pos,0);
glTexCoord2f(1,1);
glVertex3f(100,100+off,0);
glTexCoord2f(0,1);
glVertex3f(0,100+off,0);
glEnd();
raydium_osd_stop();
y=100-raydium_console_pos+(RAYDIUM_CONSOLE_FONT_SIZE/6.f);
raydium_osd_color_ega('f');
raydium_console_cursor_blink+=(raydium_frame_time*2);
raydium_osd_printf(1,y,RAYDIUM_CONSOLE_FONT_SIZE,RAYDIUM_CONSOLE_FONT_SPACER,raydium_console_config_font,"%s%c",raydium_console_get_string,( (((int)raydium_console_cursor_blink)%2)?'_':' '));
y+=(RAYDIUM_CONSOLE_FONT_SIZE/6.f);
cpt=raydium_console_history_read(hist);
for(i=cpt-1;i>=0;i--)
{
raydium_osd_color_ega('f');
raydium_osd_printf(1,y,RAYDIUM_CONSOLE_FONT_SIZE,RAYDIUM_CONSOLE_FONT_SPACER,raydium_console_config_font,"%s",hist[i]);
y+=(RAYDIUM_CONSOLE_FONT_SIZE/6.f);
}
//raydium_texture_current_set(texsave);
//raydium_rendering_internal_prepare_texture_render(raydium_texture_current);
}
// is alpha, num or '_' ?
int raydium_console_internal_isalphanumuscore(char c)
{
if(c=='_' || isalnum(c)) return 1;
return 0;
}
// "str": RAYDIUM_MAX_NAME_LEN only
void raydium_console_complete(char *str)
{
#ifdef PHP_SUPPORT
char candidates[RAYDIUM_CONSOLE_MAX_COMPLETION][RAYDIUM_MAX_NAME_LEN];
char candidates_type[RAYDIUM_CONSOLE_MAX_COMPLETION];
int n_candidates=0;
char word[RAYDIUM_MAX_NAME_LEN];
char candidate[RAYDIUM_MAX_NAME_LEN];
int word_offset;
int i,j;
int len;
int candidate_min_len;
char c;
// 0 - find last word, and store start offset
len=strlen(str);
//if(len==0) return;
for(i=(len-1);i>=0;i--)
{
if(!raydium_console_internal_isalphanumuscore(str[i]))
{
i++;
break;
}
}
if(i==-1) i=0; // first word of sentence
//if(i<0 || !raydium_console_internal_isalphanumuscore(str[i]))
//return; // empty word
word_offset=i;
strcpy(word,str+i);
len=strlen(word);
// 1 - build candidates list
for(i=0;i<raydium_register_variable_index;i++)
{
strcpy(candidate,raydium_register_variable_name[i]);
candidate[len]=0;
if(!strcmp(candidate,word))
{
candidates_type[n_candidates]=0; // 0 = variable
strcpy(candidates[n_candidates++],raydium_register_variable_name[i]);
}
if(n_candidates==RAYDIUM_CONSOLE_MAX_COMPLETION) break;
}
if(n_candidates<RAYDIUM_CONSOLE_MAX_COMPLETION)
for(i=0;i<raydium_register_function_index;i++)
{
strcpy(candidate,raydium_register_function_list[i].fname);
candidate[len]=0;
if(!strcmp(candidate,word))
{
candidates_type[n_candidates]=1; // 1 = function
strcpy(candidates[n_candidates++],raydium_register_function_list[i].fname);
}
if(n_candidates==RAYDIUM_CONSOLE_MAX_COMPLETION) break;
}
// 2 - no candidate ? only one ?
if(!n_candidates)
return;
if(n_candidates==1)
{
str[word_offset]=0;
if(strlen(str)+strlen(candidates[0]) >= (RAYDIUM_MAX_NAME_LEN-1))
return;
strcat(str,candidates[0]);
if(candidates_type[0])
strcat(str,"(");
else
strcat(str," ");
return;
}
// 3 - more than one candidate : display candidates and find the common root
raydium_console_line_add("> %s",str);
// display
for(i=0;i<n_candidates;i++)
{
if(candidates_type[i])
raydium_console_line_add("%s()",candidates[i]);
else
raydium_console_line_add("$%s",candidates[i]);
}
if(n_candidates==RAYDIUM_CONSOLE_MAX_COMPLETION)
raydium_console_line_add("..."); // limited results
// root: find shortest candidate
candidate_min_len=RAYDIUM_MAX_NAME_LEN+1;
for(i=0;i<n_candidates;i++)
if(strlen(candidates[i])<candidate_min_len)
candidate_min_len=strlen(candidates[i]);
// root: find common chars
for(i=strlen(word);i<=candidate_min_len;i++) // '\0' must be tested, too
{
c=candidates[0][i];
for(j=1;j<n_candidates;j++)
if(c!=candidates[j][i]) // last equiv
{
candidates[0][i]=0;
strcpy(candidate,candidates[0]);
str[word_offset]=0;
if(strlen(str)+strlen(candidate) >= (RAYDIUM_MAX_NAME_LEN-1))
return;
strcat(str,candidate);
return;
}
}
#endif
}

230
raydium/file.c Normal file
View File

@ -0,0 +1,230 @@
/*
Raydium - CQFD Corp.
http://raydium.org/
License: GPL - GNU General Public License, see "gpl.txt" file.
*/
#ifndef DONT_INCLUDE_HEADERS
#include "index.h"
#else
#include "headers/file.h"
#endif
// proto
void raydium_path_resolv(char *in, char *out, char mode);
// far better than glibc's 'dirname' (and portable)
void raydium_file_dirname(char *dest,char *from)
{
char *c;
int n;
c=strrchr(from,'/'); // Unix
if(!c)
c=strrchr(from,'\\'); // win32
if(!c)
{
strcpy(dest,"./");
return;
}
n=c-from;
memcpy(dest,from,n+1);
dest[n+1]=0;
}
void raydium_file_basename(char *dest,char *from)
{
char *c;
int n;
c=strrchr(from,'/'); // Unix
if(!c)
c=strrchr(from,'\\'); // win32
if(!c)
{
strcpy(dest,from);
return;
}
n=(c-from+1);
if(n==strlen(from))
{
dest[0]=0;
return;
}
strcpy(dest,from+n);
}
void raydium_file_ext(char *dest, char *from)
{
char name[RAYDIUM_MAX_DIR_LEN];
char *c;
dest[0]=0;
raydium_file_basename(name,from);
if( (c=strrchr(name,'.')) )
if(c[1]!=0)
strcpy(dest,c+1);
}
signed char raydium_file_directory_writable(char *path)
{
char file[RAYDIUM_MAX_NAME_LEN];
FILE *fp;
sprintf(file,"%s/RAYDIUM-WRITE-TEST.delme",path);
fp=fopen(file,"wb");
if(!fp)
return 0;
fclose(fp);
unlink(file);
return 1;
}
signed char raydium_file_readable(char *filename)
{
FILE *fp;
fp=fopen(filename,"r");
if(!fp)
return 0;
fclose(fp);
return 1;
}
void raydium_file_log_fopen_display(void)
{
int i;
raydium_log("List of all opended files:");
for(i=0;i<raydium_file_log_fopen_index;i++)
raydium_log("%s",raydium_file_log_fopen[i]);
}
FILE *raydium_file_fopen(char *file, char *mode)
{
FILE *fp;
int i;
char found=0;
char file2[RAYDIUM_MAX_DIR_LEN];
if(!file || !strlen(file))
return NULL;
for(i=0;i<raydium_file_log_fopen_index;i++)
if(!strcmp(raydium_file_log_fopen[i],file))
{
found=1;
break;
}
if(!found) strcpy(raydium_file_log_fopen[raydium_file_log_fopen_index++],file);
// use paths
raydium_path_resolv(file,file2,mode[0]);
// local mode ?
if(strchr(mode,'l') || raydium_init_cli_option("repository-disable",NULL))
{
return fopen(file2,mode);
}
if(strchr(mode,'w'))
{
return fopen(file2,mode);
}
if( !raydium_init_cli_option("repository-refresh",NULL) &&
!raydium_init_cli_option("repository-force",NULL) )
{
fp=fopen(file2,mode);
if(fp) return fp;
}
raydium_rayphp_repository_file_get(file2);
fp=fopen(file2,mode);
return fp;
}
unsigned long raydium_file_sum_simple_mode(char *filename,char *mode)
{
unsigned long total=0;
unsigned long cpt=0;
int c;
FILE *fp;
fp=raydium_file_fopen(filename,mode);
if(!fp)
{
raydium_log("file simple sum: error: cannot open file '%s'",filename);
return 0;
}
while( (c=fgetc(fp))!=EOF )
{
c*=cpt;
total+=c;
cpt++;
}
fclose(fp);
return total;
}
unsigned long raydium_file_sum_simple(char *filename)
{
return raydium_file_sum_simple_mode(filename,"rb");
}
char * raydium_file_home_path(char *file)
{
static char path[RAYDIUM_MAX_DIR_LEN];
sprintf(path,"%s/%s",raydium_homedir,file);
return path;
}
void raydium_file_home_path_cpy(char *file, char *dest)
{
strcpy(dest,raydium_file_home_path(file));
}
char *raydium_file_load(char *filename)
{
int len;
FILE *fp;
char *mem;
fp=raydium_file_fopen(filename,"rb");
if(!fp)
return NULL;
fseek(fp,0,SEEK_END);
len=ftell(fp);
mem=malloc(len+1);
if(!mem)
{
fclose(fp);
return NULL;
}
mem[len]=0;
fseek(fp,0,SEEK_SET);
if(fread(mem,len,1,fp)!=1)
{
fclose(fp);
free(mem);
return NULL;
}
fclose(fp);
return mem;
}

291
raydium/file_tri.c Normal file
View File

@ -0,0 +1,291 @@
/*
Raydium - CQFD Corp.
http://raydium.org/
License: GPL - GNU General Public License, see "gpl.txt" file.
*/
#ifndef DONT_INCLUDE_HEADERS
#include "index.h"
#else
#include "headers/file_tri.h"
#endif
// WARNING: most functions of this file are not part of Raydium yet !
// So, be carefull with functions without "raydium_file" prefix.
#define DONT_SAVE_DUMMY_TEXTURE
void dump_vertex_to(char *filename)
{
FILE *fp;
//GLuint tex;
GLuint i;
char text[256];
char bl;
fp=raydium_file_fopen(filename,"wt");
if(!fp) { printf("cannot write to file \"%s\", fopen() failed\n",filename); return; }
fprintf(fp,"1\n");
/*
for(tex=0;tex<raydium_texture_index;tex++)
{
// fprintf(fp,"%s\n",raydium_texture_name[tex]);
// fprintf(fp,"%i\n",j);
for(i=0;i<raydium_vertex_index;i++)
if(raydium_vertex_texture[i]==tex)
fprintf(fp,"%f %f %f %f %f %s\n",
raydium_vertex_x[i],raydium_vertex_y[i],raydium_vertex_z[i],
raydium_vertex_texture_u[i],raydium_vertex_texture_v[i],raydium_texture_name[tex]);
}
*/
for(bl=0;bl<2;bl++)
{
for(i=0;i<raydium_vertex_index;i++)
if( (raydium_texture_blended[raydium_vertex_texture[i]]?1:0) == bl)
{
if(raydium_vertex_texture_multi[i])
{
sprintf(text,"%s;%f|%f|%s",raydium_texture_name[raydium_vertex_texture[i]],
raydium_vertex_texture_multi_u[i],
raydium_vertex_texture_multi_v[i],
raydium_texture_name[raydium_vertex_texture_multi[i]]);
}
else
strcpy(text,raydium_texture_name[raydium_vertex_texture[i]]);
#ifdef DONT_SAVE_DUMMY_TEXTURE
if(raydium_vertex_texture[i])
#endif
fprintf(fp,"%f %f %f %f %f %f %f %f %s\n",
raydium_vertex_x[i],raydium_vertex_y[i],raydium_vertex_z[i],
raydium_vertex_normal_visu_x[i], raydium_vertex_normal_visu_y[i], raydium_vertex_normal_visu_z[i],
raydium_vertex_texture_u[i],raydium_vertex_texture_v[i],
text);
}
}
fclose(fp);
printf("saved.\n");
}
// sorts alpha textures
void dump_vertex_to_alpha(char *filename)
{
FILE *fp;
GLuint tex;
GLuint i;
char text[256];
int bl;
raydium_log("WARNING: 'dump_vertex_to_alpha' function is deprecated, since regular 'dump_vertex_to' function now sorts alpha textures");
fp=raydium_file_fopen(filename,"wt");
if(!fp) { printf("cannot write to file \"%s\", fopen() failed\n",filename); return; }
fprintf(fp,"1\n");
for(bl=0;bl<2;bl++)
{
for(tex=0;tex<raydium_texture_index;tex++)
if( (raydium_texture_blended[tex]?1:0) == bl)
{
printf("%s\n",raydium_texture_name[tex]);
strcpy(text,raydium_texture_name[tex]);
// fprintf(fp,"%i\n",j);
for(i=0;i<raydium_vertex_index;i++)
if(raydium_vertex_texture[i]==tex )
fprintf(fp,"%f %f %f %f %f %f %f %f %s\n",
raydium_vertex_x[i],raydium_vertex_y[i],raydium_vertex_z[i],
raydium_vertex_normal_visu_x[i], raydium_vertex_normal_visu_y[i], raydium_vertex_normal_visu_z[i],
raydium_vertex_texture_u[i],raydium_vertex_texture_v[i],
text);
}
printf("----\n");
}
fclose(fp);
printf("saved.\n");
}
#define MULTI_SEP ';'
#define MULTI_UVSEP '|'
#define ENVMAP_SEP '#'
int raydium_file_set_textures(char *name)
{
char *sep;
char *sep2=NULL;
char *sep_env;
char texname[RAYDIUM_MAX_NAME_LEN];
sep = strchr(name,MULTI_SEP);
sep_env = strchr(name,ENVMAP_SEP);
if(sep) sep2 = strchr(sep+1,MULTI_UVSEP);
if(sep_env)
{
raydium_texture_current_multi=0;
raydium_texture_current_env=raydium_texture_find_by_name(sep_env+1);
*sep_env=0;
raydium_texture_current_set_name(name);
*sep_env=ENVMAP_SEP;
return 3;
}
// 2 textures + 1 uv
if(sep && sep2)
{
sscanf(sep+1,"%f|%f|%s\n", &raydium_texture_current_multi_u,
&raydium_texture_current_multi_v,
texname);
raydium_texture_current_env=0;
raydium_texture_current_multi=raydium_texture_find_by_name(texname);
*sep=0;
raydium_texture_current_set_name(name);
*sep=MULTI_SEP;
return 2;
}
// 2 textures, but 0 uv
if(sep && !sep2)
{
raydium_texture_current_env=0;
raydium_texture_current_multi=raydium_texture_find_by_name(sep+1);
*sep=0;
raydium_texture_current_set_name(name);
*sep=MULTI_SEP;
raydium_texture_current_multi_u=-99999;
raydium_texture_current_multi_v=-99999;
return 1;
}
// 1 texture and 0 uv
if(!sep && !sep2)
{
raydium_texture_current_env=0;
raydium_texture_current_multi=0;
raydium_texture_current_set_name(name);
return 0;
}
return -1; // should never reach this
}
void read_vertex_from(char *filename)
{
GLfloat x,y,z,nx,ny,nz,u,v;
int i,ii;
GLuint save;
GLint visu;
FILE *fp;
char name[RAYDIUM_MAX_NAME_LEN];
fp=raydium_file_fopen(filename,"rt");
if(!fp) { printf("cannot read from file \"%s\", fopen() failed\n",filename); return; }
fscanf(fp,"%i\n",&visu);
raydium_log("Object: loading \"%s\", version %i",filename,visu);
// test here version 2 (anims)
if(visu==2)
{
int j,k;
fscanf(fp,"%i %i\n",&j,&k);
if(j>RAYDIUM_MAX_OBJECT_ANIMS)
{
raydium_log("object: too much anims for this fime ! (%i max)",RAYDIUM_MAX_OBJECT_ANIMS);
j=RAYDIUM_MAX_OBJECT_ANIMS; // will no work ;) (fixme)
}
raydium_object_anims[raydium_object_index]=j;
raydium_object_anim_len[raydium_object_index]=k;
raydium_object_anim_instance_current[raydium_object_index]=0;
raydium_object_anim_default_anim[raydium_object_index]=0;
for(ii=0;ii<RAYDIUM_MAX_OBJECT_ANIM_INSTANCES;ii++)
{
raydium_object_anim_current[raydium_object_index][ii]=0;
raydium_object_anim_frame_current[raydium_object_index][ii]=0;
raydium_object_anim_previous[raydium_object_index][ii]=-1;
raydium_object_anim_frame_previous[raydium_object_index][ii]=0;
raydium_object_anim_frame_previous_timeout[raydium_object_index][ii]=0;
raydium_object_anim_punctually_flag[raydium_object_index][ii]=-1;
}
for(i=0;i<raydium_object_anims[raydium_object_index];i++)
{
fscanf(fp,"%i %i %s\n",&j,&k,name);
raydium_object_anim_start[raydium_object_index][i]=j;
raydium_object_anim_end[raydium_object_index][i]=k;
raydium_object_anim_automatic_factor[raydium_object_index][i]=0;
strcpy(raydium_object_anim_names[raydium_object_index][i],name);
}
// build "current transformed model" space
for(i=0;i<raydium_object_anim_len[raydium_object_index];i++)
{
raydium_vertex_add(0,0,0);
raydium_vertex_texture[raydium_vertex_index-1]=0;
}
fscanf(fp,"%i\n",&visu);
raydium_log("object: anim: %i frame(s) with %i vertice per frame (ver %i)",raydium_object_anims[raydium_object_index],raydium_object_anim_len[raydium_object_index],visu);
}
// ...
save=raydium_texture_current_main;
i=0;
if(visu>0)
{
while( fscanf(fp,"%f %f %f %f %f %f %f %f %s\n",&x,&y,&z,&nx,&ny,&nz,&u,&v,name)!=EOF )
{
raydium_file_set_textures(name);
raydium_vertex_uv_normals_add(x,y,z,nx,ny,nz,u,v);
i++;
}
}
else if(visu==0)
{
while( fscanf(fp,"%f %f %f %f %f %s\n",&x,&y,&z,&u,&v,name)!=EOF )
{
raydium_file_set_textures(name);
raydium_vertex_uv_add(x,y,z,u,v);
i++;
}
}
else if(visu<0)
{
while( fscanf(fp,"%f %f %f %s\n",&x,&y,&z,name)!=EOF )
{
raydium_file_set_textures(name);
raydium_vertex_add(x,y,z);
i++;
}
}
if(i%3)
{
printf("ERROR with object %s ... must be *3 !",filename);
// and generate dummy vertices ?
}
fclose(fp);
raydium_texture_current_multi=0;
raydium_texture_current_set(save);
//printf("loaded.\n");
}

125
raydium/fog.c Normal file
View File

@ -0,0 +1,125 @@
/*
Raydium - CQFD Corp.
http://raydium.org/
License: GPL - GNU General Public License, see "gpl.txt" file.
*/
#ifndef DONT_INCLUDE_HEADERS
#include "index.h"
#else
#include "headers/fog.h"
#endif
void raydium_fog_enable(void)
{
raydium_fog_enabled_tag=1;
raydium_fog_apply();
}
void raydium_fog_disable(void)
{
raydium_fog_enabled_tag=0;
raydium_fog_apply();
}
void raydium_fog_color_update(void)
{
glFogfv(GL_FOG_COLOR,raydium_background_color);
}
void raydium_fog_mode(GLuint mode)
{
raydium_fog_mode_value=mode;
}
void raydium_fog_density(GLfloat density)
{
raydium_fog_density_value=density;
}
void raydium_fog_near(GLfloat fnear)
{
raydium_fog_near_value=fnear;
}
void raydium_fog_far(GLfloat ffar)
{
raydium_fog_far_value=ffar;
}
void raydium_fog_apply(void)
{
if(raydium_fog_enabled_tag)
{
glEnable(GL_FOG);
glFogi(GL_FOG_MODE,raydium_fog_mode_value);
raydium_fog_color_update();
glFogf(GL_FOG_DENSITY, raydium_fog_density_value);
glHint(GL_FOG_HINT, GL_FASTEST);
if(raydium_fog_far_value==0)
{
raydium_fog_far_value=raydium_projection_far;
raydium_fog_near_value=raydium_projection_far/4.f;
}
glFogf(GL_FOG_START,raydium_fog_near_value);
glFogf(GL_FOG_END,raydium_fog_far_value);
}
else
{
glDisable(GL_FOG);
}
}
void raydium_fog_wait(void)
{
glDisable(GL_FOG);
}
void raydium_fog_init(void)
{
raydium_fog_far_value=0;
raydium_fog_near_value=0;
raydium_fog_density_value=0;
raydium_fog_mode_value=RAYDIUM_FOG_MODE_LINEAR;
raydium_fog_volumetric_enabled_tag=0;
switch(RENDER_VOLUMETRIC_FOG_AXIS)
{
case 0:
raydium_fog_volumetric_array=raydium_vertex_x;
break;
case 1:
raydium_fog_volumetric_array=raydium_vertex_y;
break;
case 2:
raydium_fog_volumetric_array=raydium_vertex_z;
break;
default:
raydium_log("fog: FAILED: RENDER_VOLUMETRIC_FOG_AXIS is broken !");
exit(100);
}
raydium_fog_enable();
raydium_log("fog: OK");
}
void raydium_fog_volumetric_support(void)
{
raydium_fog_volumetric_enabled_tag=1;
}
void raydium_fog_volumetric_enable(void)
{
glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT);
}
void raydium_fog_volumetric_disable(void)
{
glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
}

340
raydium/gpl.txt Normal file
View File

@ -0,0 +1,340 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

2469
raydium/gui.c Normal file

File diff suppressed because it is too large Load Diff

155
raydium/gui.h Normal file
View File

@ -0,0 +1,155 @@
/*
Raydium - CQFD Corp.
http://raydium.org/
License: GPL - GNU General Public License, see "gpl.txt" file.
*/
// window borders & moves
// multiple windows tests
// modal windows
#ifndef RAY_GUI_H
#define RAY_GUI_H
#define RAYDIUM_GUI_MAX_OBJECTS 128
#define RAYDIUM_GUI_MAX_WINDOWS 16
#define RAYDIUM_GUI_BUTTON 1
#define RAYDIUM_GUI_LABEL 2
#define RAYDIUM_GUI_TRACK 3
#define RAYDIUM_GUI_EDIT 4
#define RAYDIUM_GUI_CHECK 5
#define RAYDIUM_GUI_COMBO 6
#define RAYDIUM_GUI_ZONE 7
#define RAYDIUM_GUI_NORMAL 1
#define RAYDIUM_GUI_FOCUS 2
#define RAYDIUM_GUI_HOVER 3
#define RAYDIUM_GUI_DATASIZE 4096
#define RAYDIUM_GUI_ITEM_SEPARATOR '\n'
#define RAYDIUM_GUI_COMBO_LIST_HEIGHT 5
typedef struct raydium_gui_Button
{
void * OnClick;
char caption[RAYDIUM_MAX_NAME_LEN];
GLfloat uv_normal[4];
GLfloat uv_focus[4];
GLfloat uv_hover[4];
GLfloat font_color[3];
} raydium_gui_Button;
typedef struct raydium_gui_Zone
{
void * OnClick;
GLfloat col_normal[4];
GLfloat col_focus[4];
GLfloat col_hover[4];
int tag;
} raydium_gui_Zone;
typedef struct raydium_gui_Label
{
char caption[RAYDIUM_MAX_NAME_LEN];
GLfloat font_color[3];
} raydium_gui_Label;
typedef struct raydium_gui_Track
{
GLfloat uv_rule[4];
GLfloat uv_cursor_normal[4];
GLfloat uv_cursor_focus[4];
int min;
int max;
int current;
} raydium_gui_Track;
typedef struct raydium_gui_Edit
{
char text[RAYDIUM_GUI_DATASIZE];
GLfloat uv_normal[4];
GLfloat uv_focus[4];
GLfloat font_color[3];
int cursor;
int offset;
} raydium_gui_Edit;
typedef struct raydium_gui_Check
{
char caption[RAYDIUM_MAX_NAME_LEN];
signed char checked;
GLfloat uv_normal[4];
GLfloat uv_checked[4];
GLfloat font_color_normal[3];
GLfloat font_color_focus[3];
} raydium_gui_Check;
typedef struct raydium_gui_Combo
{
char items[RAYDIUM_GUI_DATASIZE];
int current;
char current_str[RAYDIUM_GUI_DATASIZE]; // provided as a "bonus"
signed char expanded;
int offset;
GLfloat uv_body_normal[4];
GLfloat uv_body_focus[4];
int body_border_right;
GLfloat uv_list_top[4];
GLfloat uv_list_middle[4];
GLfloat uv_list_bottom[4];
GLfloat uv_list_current[4];
GLfloat uv_arrow[4];
GLfloat font_color[3];
} raydium_gui_Combo;
// Parent of all widgets
typedef struct raydium_gui_Object
{
int id;
char name[RAYDIUM_MAX_NAME_LEN];
signed char state;
signed char type;
int window;
GLfloat pos[2];
GLfloat size[2];
GLfloat font_size;
void * widget;
} raydium_gui_Object;
typedef struct raydium_gui_Window
{
int id;
char name[RAYDIUM_MAX_NAME_LEN];
signed char state;
GLfloat pos[2];
GLfloat size[2];
raydium_gui_Object widgets[RAYDIUM_GUI_MAX_OBJECTS];
int focused_widget;
int old_focused;
void * OnDelete;
} raydium_gui_Window;
typedef struct raydium_gui_Theme
{
signed char loaded;
char filename[RAYDIUM_MAX_NAME_LEN];
int texture;
int texture_size[2];
GLfloat background_uv[4];
char font[RAYDIUM_MAX_NAME_LEN];
} raydium_gui_Theme;
__global raydium_gui_Theme raydium_gui_theme_current;
__global raydium_gui_Window raydium_gui_windows[RAYDIUM_GUI_MAX_WINDOWS];
__global signed char raydium_gui_visible;
__global int raydium_gui_window_focused;
__global signed char raydium_gui_oldstate;
__global GLfloat raydium_gui_widget_sizes_default[3];
__global int raydium_gui_button_clicked_id;
__global void * raydium_gui_AfterGuiDrawCallback;
#endif

387
raydium/hdr.c Normal file
View File

@ -0,0 +1,387 @@
/*
Raydium - CQFD Corp.
http://raydium.org/
License: GPL - GNU General Public License, see "gpl.txt" file.
*/
#ifndef DONT_INCLUDE_HEADERS
#include "index.h"
#else
#include "headers/hdr.h"
#endif
void raydium_hdr_settings_color_local(GLfloat r, GLfloat g, GLfloat b, GLfloat a)
{
raydium_hdr_color_local[0]=r;
raydium_hdr_color_local[1]=g;
raydium_hdr_color_local[2]=b;
raydium_hdr_color_local[3]=a;
}
void raydium_hdr_settings_color_ambient(GLfloat r, GLfloat g, GLfloat b, GLfloat a)
{
raydium_hdr_color_ambient[0]=r;
raydium_hdr_color_ambient[1]=g;
raydium_hdr_color_ambient[2]=b;
raydium_hdr_color_ambient[3]=a;
}
void raydium_hdr_settings_eye(float speed, float alpha_max)
{
raydium_hdr_alpha_max=alpha_max;
raydium_hdr_eye_speed=speed;
}
void raydium_hdr_settings(GLfloat *color_local, GLfloat *color_ambient, float eye_speed, float alpha_max)
{
GLfloat r,g,b,a;
r=color_ambient[0];
g=color_ambient[1];
b=color_ambient[2];
a=color_ambient[3];
raydium_hdr_settings_color_ambient(r,g,b,a);
r=color_local[0];
g=color_local[1];
b=color_local[2];
a=color_local[3];
raydium_hdr_settings_color_local(r,g,b,a);
raydium_hdr_settings_eye(eye_speed,alpha_max);
}
void raydium_hdr_init(void)
{
glClearStencil(0); // default stencil "color"
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
glStencilFunc(GL_ALWAYS, 0, 0xffffffff);
glEnable(GL_STENCIL_TEST);
raydium_hdr_eye=0;
raydium_hdr_state=0;
raydium_hdr_texture_id=-1;
raydium_hdr_generated=0;
raydium_hdr_settings_color_local(1,1,1,1);
raydium_hdr_settings_color_ambient(0.45,0.45,0.45,0.45);
raydium_hdr_settings_eye(RAYDIUM_HDR_EYE_SPEED_DEFAULT,1);
raydium_log("HDR: OK");
}
void raydium_hdr_internal_window_malloc(void)
{
if(!raydium_hdr_state)
return;
if(raydium_hdr_mem)
free(raydium_hdr_mem);
raydium_hdr_mem=malloc(raydium_window_tx*raydium_window_ty);
}
void raydium_hdr_enable(void)
{
raydium_hdr_state=1;
if(raydium_hdr_texture_id<0)
{
raydium_hdr_texture_id=raydium_texture_load_internal("","hdrmap",1,RAYDIUM_HDR_SIZE,RAYDIUM_HDR_SIZE,3,-1);
raydium_hdr_mem=NULL;
raydium_hdr_internal_window_malloc();
raydium_hdr_mem_hdr=malloc(RAYDIUM_HDR_SIZE*RAYDIUM_HDR_SIZE);
raydium_hdr_mem_hdr2=malloc(RAYDIUM_HDR_SIZE*RAYDIUM_HDR_SIZE);
raydium_hdr_mem_hdr3=malloc(RAYDIUM_HDR_SIZE*RAYDIUM_HDR_SIZE*3);
}
}
void raydium_hdr_disable(void)
{
raydium_hdr_state=0;
}
void raydium_hdr_block(signed char blocking)
{
if(blocking)
glStencilFunc(GL_ALWAYS, 0, 0xffffffff);
else
glStencilFunc(GL_ALWAYS, 1, 0xffffffff);
}
void raydium_hdr_blur(unsigned char *in, unsigned char *out)
{
int x,y;
float p;
// 1st row and last row
for(x=1;x<RAYDIUM_HDR_SIZE-1;x++)
{
p=0;
p+=in[ (x-1) + (RAYDIUM_HDR_SIZE*0) ];
p+=in[ (x+1) + (RAYDIUM_HDR_SIZE*0) ];
p+=in[ (x-1) + (RAYDIUM_HDR_SIZE*1) ];
p+=in[ (x+0) + (RAYDIUM_HDR_SIZE*1) ];
p+=in[ (x+1) + (RAYDIUM_HDR_SIZE*1) ];
out[x]=p/5;
p=0;
p+=in[ (x-1) + (RAYDIUM_HDR_SIZE*(RAYDIUM_HDR_SIZE-2)) ];
p+=in[ (x+0) + (RAYDIUM_HDR_SIZE*(RAYDIUM_HDR_SIZE-2)) ];
p+=in[ (x+1) + (RAYDIUM_HDR_SIZE*(RAYDIUM_HDR_SIZE-2)) ];
p+=in[ (x-1) + (RAYDIUM_HDR_SIZE*(RAYDIUM_HDR_SIZE-1)) ];
p+=in[ (x+1) + (RAYDIUM_HDR_SIZE*(RAYDIUM_HDR_SIZE-1)) ];
out[x+(RAYDIUM_HDR_SIZE*(RAYDIUM_HDR_SIZE-1))]=p/5;
}
// 1st col and last col
for(y=1;y<RAYDIUM_HDR_SIZE-1;y++)
{
p=0;
p+=in[ 1 + ((y-1)*RAYDIUM_HDR_SIZE) ];
p+=in[ 1 + ((y+0)*RAYDIUM_HDR_SIZE) ];
p+=in[ 1 + ((y+1)*RAYDIUM_HDR_SIZE) ];
p+=in[ 0 + ((y-1)*RAYDIUM_HDR_SIZE) ];
p+=in[ 0 + ((y+1)*RAYDIUM_HDR_SIZE) ];
out[y*RAYDIUM_HDR_SIZE]=p/5;
p=0;
p+=in[ (RAYDIUM_HDR_SIZE-2) + ((y-1)*RAYDIUM_HDR_SIZE) ];
p+=in[ (RAYDIUM_HDR_SIZE-2) + ((y+0)*RAYDIUM_HDR_SIZE) ];
p+=in[ (RAYDIUM_HDR_SIZE-2) + ((y+1)*RAYDIUM_HDR_SIZE) ];
p+=in[ (RAYDIUM_HDR_SIZE-1) + ((y-1)*RAYDIUM_HDR_SIZE) ];
p+=in[ (RAYDIUM_HDR_SIZE-1) + ((y+1)*RAYDIUM_HDR_SIZE) ];
out[(y*RAYDIUM_HDR_SIZE) + (RAYDIUM_HDR_SIZE-1) ]=p/5;
}
// body
for(x=1;x<RAYDIUM_HDR_SIZE-1;x++)
for(y=1;y<RAYDIUM_HDR_SIZE-1;y++)
{
p=0;
p+=in[(x+0)+((y+0)*RAYDIUM_HDR_SIZE)];
p+=in[(x-1)+((y-1)*RAYDIUM_HDR_SIZE)];
p+=in[(x+0)+((y-1)*RAYDIUM_HDR_SIZE)];
p+=in[(x+1)+((y-1)*RAYDIUM_HDR_SIZE)];
p+=in[(x-1)+((y+0)*RAYDIUM_HDR_SIZE)];
p+=in[(x+1)+((y+0)*RAYDIUM_HDR_SIZE)];
p+=in[(x-1)+((y+1)*RAYDIUM_HDR_SIZE)];
p+=in[(x+0)+((y+1)*RAYDIUM_HDR_SIZE)];
p+=in[(x+1)+((y+1)*RAYDIUM_HDR_SIZE)];
out[x+(y*RAYDIUM_HDR_SIZE)]=p/9;
}
// upper left pixel
p=0;
p+=in[1+(0*RAYDIUM_HDR_SIZE)];
p+=in[1+(1*RAYDIUM_HDR_SIZE)];
p+=in[0+(1*RAYDIUM_HDR_SIZE)];
out[0]=p/3;
// upper right pixel
p=0;
p+=in[(RAYDIUM_HDR_SIZE-2)+(0*RAYDIUM_HDR_SIZE)];
p+=in[(RAYDIUM_HDR_SIZE-2)+(1*RAYDIUM_HDR_SIZE)];
p+=in[(RAYDIUM_HDR_SIZE-1)+(1*RAYDIUM_HDR_SIZE)];
out[RAYDIUM_HDR_SIZE-1]=p/3;
// bottom left pixel
p=0;
p+=in[ ((RAYDIUM_HDR_SIZE-1)*RAYDIUM_HDR_SIZE) + 1 ];
p+=in[ ((RAYDIUM_HDR_SIZE-2)*RAYDIUM_HDR_SIZE) + 1 ];
p+=in[ ((RAYDIUM_HDR_SIZE-2)*RAYDIUM_HDR_SIZE) + 0 ];
out[(RAYDIUM_HDR_SIZE-1)*RAYDIUM_HDR_SIZE]=p/3;
// bottom right pixel
p=0;
p+=in[ ((RAYDIUM_HDR_SIZE-1)*RAYDIUM_HDR_SIZE) + (RAYDIUM_HDR_SIZE-2) ];
p+=in[ ((RAYDIUM_HDR_SIZE-2)*RAYDIUM_HDR_SIZE) + (RAYDIUM_HDR_SIZE-1) ];
p+=in[ ((RAYDIUM_HDR_SIZE-2)*RAYDIUM_HDR_SIZE) + (RAYDIUM_HDR_SIZE-2) ];
out[((RAYDIUM_HDR_SIZE-1)*RAYDIUM_HDR_SIZE) + (RAYDIUM_HDR_SIZE-1) ]=p/3;
}
void raydium_hdr_map(void)
{
int x,y,i;
float fx,fy;
float incx,incy;
int offset;
unsigned char pixel;
int total;
float hdr_exposure;
if(!raydium_hdr_state || raydium_hdr_generated)
return;
glDisable(GL_STENCIL_TEST);
// download stencil to RAM ...
glReadPixels (0,0,raydium_window_tx,raydium_window_ty,GL_STENCIL_INDEX,GL_UNSIGNED_BYTE,raydium_hdr_mem);
incx=raydium_window_tx/(RAYDIUM_HDR_SIZE*1.f);
incy=raydium_window_ty/(RAYDIUM_HDR_SIZE*1.f);
fx=0;
fy=0;
total=0;
// ... downscaling ...
for(y=0;y<RAYDIUM_HDR_SIZE;y++)
{
for(x=0;x<RAYDIUM_HDR_SIZE;x++)
{
offset=(x+(RAYDIUM_HDR_SIZE*y));
pixel=raydium_hdr_mem[raydium_trigo_round(fx)+(raydium_window_tx*(raydium_trigo_round(fy)))];
//slooooooooooooow ! (?!)
//glReadPixels(raydium_trigo_round(fx),raydium_trigo_round(fy),1,1,GL_STENCIL_INDEX,GL_UNSIGNED_BYTE,&pixel);
raydium_hdr_mem_hdr2[offset]=(pixel?255:0);
total+=pixel;
fx+=incx;
}
fx=0;
fy+=incy;
}
hdr_exposure=(float)total/(RAYDIUM_HDR_SIZE*RAYDIUM_HDR_SIZE);
// dec intensity using exposure factor
if(raydium_hdr_eye>0)
{
raydium_hdr_eye-=(hdr_exposure*(raydium_hdr_eye_speed*raydium_frame_time));
if(raydium_hdr_eye<=0)
raydium_hdr_eye=-9999; // the eye is now ok
}
// we're in "total" drak
if(hdr_exposure==0)
raydium_hdr_eye=0; // be ready for another "flash"
if(hdr_exposure>0 && raydium_hdr_eye==0)
raydium_hdr_eye=raydium_hdr_alpha_max;
//printf("%i/%i (%f)\n",total,RAYDIUM_HDR_SIZE*RAYDIUM_HDR_SIZE,hdr_exposure*100);
if(raydium_hdr_eye>0)
// if(!raydium_key[GLUT_KEY_F11])
for(x=0;x<RAYDIUM_HDR_PASS;x++)
{
raydium_hdr_blur(raydium_hdr_mem_hdr2,raydium_hdr_mem_hdr);
raydium_hdr_blur(raydium_hdr_mem_hdr,raydium_hdr_mem_hdr2);
}
hdr_exposure=(raydium_hdr_eye>0?raydium_hdr_eye:0); // clamp
for(i=0;i<RAYDIUM_HDR_SIZE*RAYDIUM_HDR_SIZE;i++)
{
raydium_hdr_mem_hdr3[0 + i*3] = raydium_hdr_mem_hdr2[i] * hdr_exposure;
raydium_hdr_mem_hdr3[1 + i*3] = raydium_hdr_mem_hdr2[i] * hdr_exposure;
raydium_hdr_mem_hdr3[2 + i*3] = raydium_hdr_mem_hdr2[i] * hdr_exposure;
}
// ... and we upload to hdr_texture
glBindTexture(GL_TEXTURE_2D,raydium_hdr_texture_id);
glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,RAYDIUM_HDR_SIZE,RAYDIUM_HDR_SIZE,0,GL_RGB,GL_UNSIGNED_BYTE,raydium_hdr_mem_hdr3);
raydium_hdr_generated=1;
}
void raydium_hdr_map_apply(void)
{
if(!raydium_hdr_state)
return;
if(!raydium_hdr_generated)
raydium_hdr_map();
raydium_hdr_generated=0;
#ifdef DEBUG_HDR_STENCIL
if(raydium_key[GLUT_KEY_F10])
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
raydium_osd_start();
glStencilFunc(GL_EQUAL, 1, 0xffffffff);
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
glEnable(GL_STENCIL_TEST);
glDisable(GL_TEXTURE_2D);
glColor4f(1,1,1,1);
glBegin(GL_QUADS);
glVertex3f(0,0,0);
glVertex3f(100,0,0);
glVertex3f(100,100,0);
glVertex3f(0,100,0);
glEnd();
raydium_osd_stop();
glEnable(GL_TEXTURE_2D);
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
glStencilFunc(GL_ALWAYS, 0, 0xffffffff);
glDisable(GL_STENCIL_TEST);
}
else
{
#endif
raydium_osd_start();
glBindTexture(GL_TEXTURE_2D,raydium_hdr_texture_id);
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glDepthMask(GL_FALSE);
glBlendFunc(GL_ONE,GL_ONE);
//localized hdr "glow" effect
glColor4fv(raydium_hdr_color_local);
glBegin(GL_QUADS);
glTexCoord2f(0,0);
glVertex3f(0,0,0);
glTexCoord2f(1,0);
glVertex3f(100,0,0);
glTexCoord2f(1,1);
glVertex3f(100,100,0);
glTexCoord2f(0,1);
glVertex3f(0,100,0);
glEnd();
//ambiental hdr "glow" effect
glColor4fv(raydium_hdr_color_ambient);
glBegin(GL_QUADS);
glTexCoord2f(0,0);
glVertex3f(-50,-50,0);
glTexCoord2f(1,0);
glVertex3f(150,-50,0);
glTexCoord2f(1,1);
glVertex3f(150,150,0);
glTexCoord2f(0,1);
glVertex3f(-50,150,0);
glEnd();
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
raydium_rendering_internal_restore_render_state();
raydium_osd_stop();
#ifdef DEBUG_HDR_STENCIL
}
#endif
}
signed char raydium_hdr_texture(int texture, signed char hdr)
{
if(texture>=0 && texture<raydium_texture_index)
{
raydium_texture_hdr[texture]=hdr;
return 1;
}
raydium_log("HDR: cannot set HDR attribute on texture: invalid name or index");
return 0;
}
signed char raydium_hdr_texture_name(char *name, signed char hdr)
{
return raydium_hdr_texture(raydium_texture_find_by_name(name),hdr);
}
void raydium_hdr_texture_reset(void)
{
int i;
for(i=0;i<RAYDIUM_MAX_TEXTURES;i++)
raydium_texture_hdr[i]=0;
}

52
raydium/headers/atexit.h Normal file
View File

@ -0,0 +1,52 @@
#ifndef _ATEXIT__H
#define _ATEXIT__H
#include "../atexit.h"
/*=
Atexit functions
4400
**/
// Introduction
/**
Raydium provides its own atexit function, since Win32 DLL requires a bit
of magic for such things. This support is mainly here for internal reasons,
you can continue to use regular atexit() in your applications.
**/
__rayapi int raydium_atexit(void (*func)(void));
/**
As the original atexit():
Register a function to be called at norma program termination.
Functions so registered are called in the reverse order of their
registration; no arguments are passed.
Returns 0 if successful.
**/
__rayapi void raydium_atexit_call(void);
/**
Internal use. Will call all registered functions.
**/
__rayapi void raydium_atexit_init(void);
/**
Internal use.
**/
// Hack. See cli.h header for more information.
#ifdef RAYDLL
#define raydium_init_args(argc,argv)\
{\
atexit(raydium_atexit_call);\
raydium_init_args_hack(argc,argv);\
}
#define raydium_init_args_name(argc,argv,app_name)\
{\
atexit(raydium_atexit_call);\
raydium_init_args_name_hack(argc,argv,app_name);\
}
#endif
#endif

View File

@ -0,0 +1,14 @@
#ifndef _BACKGROUND_H
#define _BACKGROUND_H
/*=
Background
800
**/
__rayapi void raydium_background_color_change (GLfloat r, GLfloat g, GLfloat b, GLfloat a);
/**
Will change ##raydium_background_color## array and apply this modification.
(will update fog color, obviously).
**/
#endif

View File

@ -0,0 +1,34 @@
#ifndef _CALLBACK_H
#define _CALLBACK_H
/*=
Callbacks
1500
**/
// Introduction
/**
This file contains many initializations, a few internal callbacks, but
will provides a very important function for end-user, wich will
gives user display function to Raydium: see below
**/
__rayapi void raydium_callback_image (void);
/**
Internal use.
**/
__rayapi void raydium_callback_set (void);
/**
Internal use.
**/
__rayapi void raydium_callback (void (*loop));
/**
This function will loop over the provided display function, indefinitely.
"loop" must be:
%%(c) void loop(void) %%
**/
#endif

173
raydium/headers/camera.h Normal file
View File

@ -0,0 +1,173 @@
#ifndef _CAMERA_H
#define _CAMERA_H
/*=
Camera
2200
**/
// Introduction
/**
Raydium provides camera management functions, allowing the coder to
move camera with very simple functions, even for complex moves.
You have to place your camera once per frame (not more, not less).
"look_at" style functions can be affected by ##raydium_camera_look_at_roll##
global variable, if needed.
A few words about camera path: Take a look to a .cam file if you want to
understand this simple file format, but you probably only need the ##cam.c##
application, dedicated to camera path creation.
Some camera functions are provided by physics module, see suitable chapter.
**/
__rayapi void raydium_camera_vectors (GLfloat * res3);
/**
This function will return two vectors (2 * 3 * GLfloat), giving the camera
orientation (front vector and up vector). At this day, the up vector is
always the same as the world up vector, even if the camera is rotated
or upside down (and yes, this MUST be corrected :).
Designed for internal uses, before all.
**/
__rayapi void raydium_camera_internal_prepare(void);
/**
Internal use. (pre)
**/
__rayapi void raydium_camera_internal (GLfloat x, GLfloat y, GLfloat z);
/**
Internal use. (post)
**/
__rayapi void raydium_camera_place (GLfloat x, GLfloat y, GLfloat z, GLfloat lacet, GLfloat tangage, GLfloat roulis);
/**
Sets the camera at (x,y,z) position, and using (lacet,tangage,roulis)
as rotation angles.
**/
__rayapi void raydium_camera_look_at (GLfloat x, GLfloat y, GLfloat z, GLfloat x_to, GLfloat y_to, GLfloat z_to);
/**
Sets the camera at (x,y,z) position, and looks at (x_to,y_to,z_to).
**/
__rayapi void raydium_camera_replace (void);
/**
You'll need to reset camera position and orientation after each object drawing.
If this is unclear to you, read the "example" section, below.
You will need to make your own 3D transformations (GLRotate, GLTranslate,
...) to draw your objects, or you can use the following function.
**/
__rayapi void raydium_camera_replace_go (GLfloat * pos, GLfloat * R);
/**
This function will replace the camera, as ##raydium_camera_replace()##,
but will place "3D drawing cursor" at position ##pos## (3 GLfloat) with
rotation ##R## (4 GLfloat quaternion).
No eulers (rotx, roty, rotz) version of this function is provided for now..
Do you really need it ?
**/
// Example of camera use
/**
1. place camera
2. move "drawing cursor" to object's place
3. draw object
4. reset camera to initial place (the one given at step 1)
5. move "drawing cursor" to another object's place
6. draw another object
7. [...]
Steps 4 and 5 can be done with raydium_camera_replace_go().
**/
__rayapi void raydium_camera_rumble(GLfloat amplitude, GLfloat ampl_evo, GLfloat secs);
/**
Camera (any type) will rumble for ##secs## seconds, with ##amplitude## (radians).
This ##amplitude## will be incremented of ##ampl_evo## every second (negative
values are allowed for ##ampl_evo##).
An ##amplitude## is always positive.
**/
__rayapi void raydium_camera_smooth (GLfloat px, GLfloat py, GLfloat pz, GLfloat lx, GLfloat ly, GLfloat lz, GLfloat zoom, GLfloat roll, GLfloat step);
/**
Smooth style clone of ##raydium_camera_look_at##.
Roll is given by ##roll## and not global variable ##raydium_camera_look_at_roll##
as for regular look_at function.
##zoom## is the requested FOV.
Play with step to modify smoothing level of the movement. A good way to use
this function is the following usage :
%%(c) raydium_camera_smooth(cam[0],cam[1],cam[2],pos[1],-pos[2],pos[0],70,0,raydium_frame_time*3); %%
**/
__rayapi void raydium_camera_path_init (int p);
/**
Internal use.
**/
__rayapi void raydium_camera_path_init_all (void);
/**
Internal use.
**/
__rayapi int raydium_camera_path_find (char *name);
/**
Lookups path's id using filename ##name##.
This function will not try to load a camera path if it's not found, and
will return -1.
**/
__rayapi int raydium_camera_path_load (char *filename);
/**
Obvious : use this function to load a camera path.
**/
__rayapi void raydium_camera_path_draw (int p);
/**
Draws ##p## camera path, as red lines. This must be done at each frame.
**/
__rayapi void raydium_camera_path_draw_name (char *path);
/**
Same as above, but using camera path's name.
**/
__rayapi signed char raydium_camera_smooth_path (char *path, GLfloat step, GLfloat * x, GLfloat * y, GLfloat * z, GLfloat * zoom, GLfloat * roll);
/**
Returns the (##x,y,z##) point of the camera path for step ##step##, using
provided ##zoom## (FOV) and ##roll## angle.
It's important to note that ##step## is a float.
Mostly for internal use.
**/
__rayapi void raydium_camera_path_reset(void);
/**
Next smooth call will be instantaneous.
**/
__rayapi void raydium_camera_smooth_path_to_pos (char *path, GLfloat lx, GLfloat ly, GLfloat lz, GLfloat path_step, GLfloat smooth_step);
/**
"Camera on path looking at a point".
Simple ##raydium_camera_smooth## version: give a path name, a "look_at"
point (##lx,ly,lz##), a current ##step##, anda ##smooth_step## time
factor (see ##raydium_camera_smooth## example above).
**/
__rayapi void raydium_camera_smooth_pos_to_path (GLfloat lx, GLfloat ly, GLfloat lz, char *path, GLfloat path_step, GLfloat smooth_step);
/**
"Camera on point looking at a path".
Same style as previous function.
**/
__rayapi void raydium_camera_smooth_path_to_path (char *path_from, GLfloat path_step_from, char *path_to, GLfloat path_step_to, GLfloat smooth_step);
/**
"Camera on a path looking at another path".
Same style as previous functions.
**/
#endif

76
raydium/headers/capture.h Normal file
View File

@ -0,0 +1,76 @@
#ifndef _CAPTURE_H
#define _CAPTURE_H
/*=
Capture (2D)
700
**/
// Quickview
/**
Captures are made in TGA (without RLE compression) or JPEG formats and saved into
the current directory.
These functions may fail (garbage in resulting capture) if frame size if
not "standard", mostly after a window resize.
Also there are "auto" functions that provide a simplest method to make an screen
capture. So,the following example (put into the ##display()## function), allows jpeg
screenshots just pressing F9 key:
##
if(raydium_key_last==9) raydium_capture_frame_jpeg_auto();
##
Raydium also allow you to capture movies: activate ##DEBUG_MOVIE## option
in ##raydium/config.h## with the needed framerate, and press F11. Raydium
will use a dedicated time line, allowing smooth capture. This system may cause
strange behaviours with movies providing network action.
The movie is stored in multiples files in ##movie## directory, and you can
use mencoder like this:
##mencoder -ovc lavc -lavcopts vcodec=mpeg4:vhq:vbitrate=780
mf://\*.tga -vf scale=320:240 -mf fps=25 -o ~/ray.avi##
You can also use audio file adding this:
## -audiofile audio.mp3 -oac copy## for example.
**/
__rayapi void raydium_capture_frame(char *filename);
/**
Capture current frame to ##filename##.
**/
__rayapi void raydium_capture_frame_auto(void);
/**
Same as above, but to an auto-generated filename (raycap*).
**/
__rayapi void raydium_capture_frame_jpeg(char *filename);
/**
Same as ##raydium_capture_frame()## but using JPEG image format.
See ##raydium/config.h## for quality setting.
**/
__rayapi void raydium_capture_frame_now(char *filename);
/**
Same as ##raydium_capture_frame()##, but without waiting the end of the frame,
saving the hardware color buffer, whatever it contains. Use with caution.
**/
__rayapi void raydium_capture_frame_jpeg_now(char *filename);
/**
Same as above, but using JPEG image format.
**/
__rayapi void raydium_capture_filename_auto(char *dest,char *format);
/**
Internal Use. Generates filenames for new screenshots.
**/
__rayapi void raydium_capture_frame_auto(void);
/**
Capture the current frame giving the resulting file and automatic name.
**/
__rayapi void raydium_capture_frame_jpeg_auto(void);
/**
Same as above, but using JPEG image format.
**/
#endif

17
raydium/headers/clear.h Normal file
View File

@ -0,0 +1,17 @@
#ifndef _CLEAR_H
#define _CLEAR_H
/*=
Frame clearing
801
**/
__rayapi void raydium_clear_frame (void);
/**
You need to call this function every frame to clear all hardware buffers.
**/
__rayapi void raydium_clear_color_update (void);
/**
Will apply background color modification. Probably useless for you.
**/
#endif

84
raydium/headers/cli.h Normal file
View File

@ -0,0 +1,84 @@
#ifndef _CLI_H
#define _CLI_H
/*=
Command Line Interface
2401
**/
// Introduction
/**
Here, you'll find a few functions to deal with command line
interface of Raydium.
**/
__rayapi int raydium_init_cli_option(char *option, char *value);
/**
This function will search command line ##option##.
If this option is found, the functions stores any argument to ##value## and
returns 1.
The function will return 0 if ##option## is not found.
Example (search for: ##--ground##)
%%(c)
char model[RAYDIUM_MAX_NAME_LEN];
if(raydium_init_cli_option("ground",model))
{
setground(model);
}
%%
**/
__rayapi int raydium_init_cli_option_default(char *option, char *value, char *default_value);
/**
Same as above, but allows you to provide a default value (##default##) if
the ##option## is not found on command line.
**/
__rayapi void raydium_init_internal_homedir_find(char *);
/**
Internal use.
**/
#ifndef RAYDLL
__rayapi void raydium_init_args(int argc, char **argv);
/**
You must use this function, wich send application arguments to Raydium
and external libs (GLUT, OpenAL, ...).
This must be done **before** any other call to Raydium.
Example:
%%(c)
int main(int argc, char **argv)
{
raydium_init_args(argc,argv);
[...]
%%
**/
#endif
#ifndef RAYDLL
__rayapi void raydium_init_args_name(int argc, char **argv, char *app_name);
/**
Same as above, but with application short name. This string is used to
build things like runtime configuration directory name (~/.raydium/ by default).
Use this wrapper if you don't want to share your configuration with Raydium.
**/
#endif
/*
Ok ... all this is a very ugly part: under win32, a DLL use a different
atexit() queue than the application. We can't use the DLL_PROCESS_DETACH
DLL reason, since it seems that OpenAL DLL is unloaded *before* raydium.dll !
So the idea here is to provide a wrapper to the application for these two
init functions so they use their own atexit() queue, in a transparent way.
See atexit.h header for wrappers.
*/
#ifdef RAYDLL
__rayapi void raydium_init_args_hack(int argc, char **argv);
__rayapi void raydium_init_args_name_hack(int argc, char **argv, char *app_name);
#endif
#endif

122
raydium/headers/console.h Normal file
View File

@ -0,0 +1,122 @@
#ifndef _CONSOLE_H
#define _CONSOLE_H
/*=
In-game console
3000
**/
// Introduction
/**
This chapter introduce Raydium console, allowing applications to take
user keyboard input (game commands, chat, ...) and to send informations
to this console.
The end user can call the console using "the key below esc".
By default, if PHP support is enabled, all user commands will be redirected
to PHP engine. Each command will get his own context, don't expect to create
anything else than "single line PHP scripts" with the console. See PHP chapter
for more informations.
The console allows the user to prefix command with the following characters:
- ##/##: Non PHP command. The command will be sent to application (see
##raydium_console_gets_callback##, below.
- ##>##: Will launch argument as a PHP script (identical to ##include("...")##)
- ##!##: Will launch argument as a sequence script
Command history is saved to ##raydium_history## file when application exits.
You can use a ##void prompt(char *)## callback to get user commands. Your
callback must be registered thru ##raydium_console_gets_callback##:
%%(c) raydium_console_gets_callback=prompt; %%
This console provides auto-completion of register functions and variables.
See the suitable chapter for more information.
**/
__rayapi void raydium_console_init (void);
/**
Internal use.
**/
__rayapi void raydium_console_history_save (void);
/**
Internal use (will flush console history to disk).
You can call it by yourself if needed.
**/
__rayapi int raydium_console_gets (char *where);
/**
**DISABLED**.
Use ##raydium_console_gets_callback## function pointer instead.
**/
__rayapi void raydium_console_history_previous (void);
/**
Internal use.
**/
__rayapi void raydium_console_history_next (void);
/**
Internal use.
**/
__rayapi void raydium_console_history_add (char *str);
/**
Internal use.
**/
__rayapi void raydium_console_exec_script (char *file);
/**
Internal use.
**/
__rayapi void raydium_console_exec_last_command (void);
/**
Internal use.
**/
__rayapi void raydium_console_line_add (char *format, ...);
/**
Mostly reserved for internal use, but unless ##raydium_log##, this function will
add the provided data only to ingame console, and not to "native" console.
**/
__rayapi int raydium_console_history_read(char **hist);
/**
This function will build an history list.
See this example :
%%(c)
char *hist[RAYDIUM_CONSOLE_MAX_LINES];
int i,n;
n=raydium_console_history_read(hist);
for(i=0;i<n;i++)
printf("> %s\n",hist[i]);
%%
**Warning**: Be sure that there's no new history line between the call and
the end of ##hist## usage (Or copy ##hist## to a safer place).
**/
__rayapi void raydium_console_event (void);
/**
Internal use. Will switch console up and down.
**/
__rayapi void raydium_console_draw (void);
/**
Internal use.
**/
__rayapi int raydium_console_internal_isalphanumuscore (char c);
/**
Internal use.
**/
__rayapi void raydium_console_complete (char *str);
/**
Internal use.
**/
#endif

108
raydium/headers/file.h Normal file
View File

@ -0,0 +1,108 @@
#ifndef _FILE_H
#define _FILE_H
/*=
Files (generic)
2100
**/
// Introduction
/**
File support is now splitted in two parts: generic functions and TRI format
specific functions. This chapter talks about generic part, where you'll find
some libc replacements and wrappers, and functions dealing with
"private directory" of the current user.
**/
__rayapi void raydium_file_dirname(char *dest,char *from);
/**
Reliable and portable version of libc's ##dirname## function.
This function extracts directory from ##from## filename, and writes it
to ##dest##.
No memory allocation will be done by the function.
**/
__rayapi void raydium_file_basename(char *dest,char *from);
/**
Another libc clone, for ##basename## function. Extracts file name from a
path into ##dest## string.
**/
__rayapi void raydium_file_ext(char *dest, char *from);
/**
Return the extension of ##from## filename (can be a complete path), without
the . (dot), or an empty string if extension is not found.
**/
__rayapi signed char raydium_file_directory_writable(char *path);
/**
Return **1** if ##path## directory is writable, **0** otherwise.
**/
__rayapi signed char raydium_file_readable(char *filename);
/**
Return **1** if ##filename## exists and is readable, **0** otherwise.
**/
__rayapi void raydium_file_log_fopen_display(void);
/**
Display (console) all filenames that were opened before the call.
##--files## command line option will call this function at the application's
exit, closed or not.
**/
__rayapi FILE *raydium_file_fopen(char *file, char *mode);
/**
Raydium wrapper to libc's ##fopen## function.
This function will:
- Update some stats
- Try to download the file from repositories if no local version is found, or
will try to update the file if asked (##--repository-refresh## or
##repository-force##). See R3S on Raydium's Wiki.
- You can disable R3S client (for a "local only" file) adding a 'l'
in ##mode## ("rl" or "rbl" for example).
- Use Raydium paths (see suitable chapter)
**/
#ifdef PHP_SUPPORT
__rayapi int raydium_rayphp_repository_file_get(char *file);
#else
#define raydium_php_repository_file_get fopen
#endif
__rayapi unsigned long raydium_file_sum_simple(char *filename);
/**
This function will generate a very simple checksum on ##filename##.
**/
unsigned long raydium_file_sum_simple_mode(char *filename,char *mode);
/**
Same as above, but you can pass a fopen ##mode## ("rt", or "rbl" for example).
See ##raydium_file_fopen()## for more informations about ##mode##.
**/
__rayapi char * raydium_file_home_path(char *file);
/**
This function will return an absolute file path for ##file## in the home
directory of the current user.
Returned value is a pointer to static memory. Do not free this memory and use
it before any other call to this function, since it will be overwritten.
Example:
for ##test.cfg##, this function will return ##/home/me/.raydium/test.cfg##
See also ##raydium_init_args_name()## if you want to tune this result.
**/
__rayapi void raydium_file_home_path_cpy(char *file, char *dest);
/**
Same as above, but you must provide memory with ##dest##.
**/
__rayapi char *raydium_file_load(char *filename);
/**
This function loads ##filename## (as a binary file under win32, no matter
under Linux) in a string, and returns its address. **You** must free this
memory when finished.
**/
#endif

View File

@ -0,0 +1,85 @@
#ifndef _FILE_TRI_H
#define _FILE_TRI_H
/*=
Files (TRI format)
2101
**/
// Warning
/**
It's important to use only functions with ##raydium_file_*## prefix.
All other functions may change or disappear. Upper level functions are
available (see ##object.c##).
**/
// Introduction
/**
##file.c## use .tri mesh files (text), available in 4 versions:
1. version 1: providing normals and uv texture mapping informations.
2. version 0: providing uv texture mapping.
3. version -1: only providing vertices.
4. version 2: mesh animation support
Version 1 example file:
%%
1
5.1 15.75 -3.82 0.0000 0.0000 -1.0000 0.5158 0.5489 rgb(0.5,0.5,0.5)
6.3 11.75 -3.82 0.0000 0.0000 -1.0000 0.5196 0.5365 rgb(0.5,0.5,0.5)
5.0 11.75 -3.82 0.0000 0.0000 -1.0000 0.5158 0.5365 rgb(0.5,0.5,0.5)
...
%%
You can find the file version on first line, and then data.
Next lines: vertex position (x,y,z), normal (x,y,z), texture mapping (u,v)
and texture (string).
Version 2 files are a bit different, as showed below:
%%
2
3 1743
0 39 stand
40 45 run
46 53 attack
1
5.1 15.75 -3.82 0.0000 0.0000 -1.0000 0.5158 0.5489 rgb(0.5,0.5,0.5)
6.3 11.75 -3.82 0.0000 0.0000 -1.0000 0.5196 0.5365 rgb(0.5,0.5,0.5)
5.0 11.75 -3.82 0.0000 0.0000 -1.0000 0.5158 0.5365 rgb(0.5,0.5,0.5)
...
%%
You may have seen that headers are longer for v2 files. You'll find (just
after the version number) how many "anims" are hosted by this file, and how
many vertices are required for one frame. Then you'll find one line per
"anim", with starting frame, ending frame and anim's name.
Then starts a regular tri file ("sub-file", with its own version number)
with ALL concatened frames.
**/
#define DONT_SAVE_DUMMY_TEXTURE
__rayapi void dump_vertex_to (char *filename);
/**
This function save all scene to filename (.tri file) in version 1.
Vertice may be sorted.
Please, try to do not use this function.
**/
__rayapi void dump_vertex_to_alpha (char *filename);
/**
Now useless and deprecated.
**/
__rayapi int raydium_file_set_textures (char *name);
/**
Internal use.
This function analyze texture filename, and search for extended multitexturing
informations (u,v and another texture).
**/
__rayapi void read_vertex_from (char *filename);
/**
Loads filename. Again, avoid use of this function.
**/
#endif

137
raydium/headers/fog.h Normal file
View File

@ -0,0 +1,137 @@
#ifndef _FOG_H
#define _FOG_H
/*=
Fog
500
**/
// Introduction
/**
Fog is usefull for two major reasons:
1. Realism: Just try, and you'll understand:
amazing depth impression, no ?
2. Speed: For a correct fog effect (i'm talking
about estetic aspect), you must bring near_clipping to a closer value,
reducing the overall number of triangles displayed at the same time.
There are 3 types of fog. They are:
* Linear:
Far-z
fog= ---------
Far-Near
* Exp:
(-density*z)
fog= e^
* Exp2:
(-density*z)^2
fog= e^
Above ##z## is the distance to the calculated point from the camera.
As you can see, linear mode doesn't use ##Density##; and Exp & Exp2 modes don't
use near and far values. Remember that.
**/
__rayapi void raydium_fog_enable (void);
/**
Obvious
**/
__rayapi void raydium_fog_disable (void);
/**
Obvious
**/
__rayapi void raydium_fog_color_update (void);
/**
If you have modified ##raydium_background_color## array, you must
call this function, applying the specified color to hardware.
See also: ##raydium_background_color_change##
**/
__rayapi void raydium_fog_mode(GLuint mode);
/**
The fog mode can be change with this function. There are 3 different ways
to apply the fog:
1. ##RAYDIUM_FOG_MODE_LINEAR## - Used by default, the fog is directly applied
according the distance. Not real world fog, but used to avoid drawing
too distant objects.
##IMPORTANT##: EXP mode ignores the ##density## value,
only uses ##near## and ##far##.
2. ##RAYDIUM_FOG_MODE_EXP## - The fog grows exponentially with the distance.
Usual mist in the real world.
##IMPORTANT##: EXP mode ignores the ##near## and ##far## values,
only uses the ##density##.
3. ##RAYDIUM_FOG_MODE_EXP2## - The fog grows twice exponentially with the
distance. Used when the observer is inside a cloud/mist.
##IMPORTANT##: EXP2 mode ignores the ##near## and ##far## values,
only uses the ##density##.
**/
__rayapi void raydium_fog_density(GLfloat density);
/**
Sets the density of the fog.
Useless if you are using LINEAR mode.
**/
__rayapi void raydium_fog_near(GLfloat near);
/**
Sets the near point to apply the fog.
Useless if you are using EXP or EXP2 modes.
**/
__rayapi void raydium_fog_far(GLfloat far);
/**
Sets the far point of the fog.
Useless if you are using EXP or EXP2 modes.
**/
__rayapi void raydium_fog_apply(void);
/**
Used to apply changes in your setup of fog.
Also is used to continue a previously stopped fog.
See: ##raydium_fog_wait()## below.
**/
__rayapi void raydium_fog_wait(void);
/**
With this function you can deactivate TEMPORALY the fog, but the internal state
of the fog in Raydium won't change, so when you use raydium_fog_apply, the fog
will continue like it was before being stoped.
It's very usefull for certain rendering effects that need to
stop the fog temporaly.
**/
__rayapi void raydium_fog_volumetric_support(void);
/**
With this function, you're saying to Raydium that you want a support
for volumetric fog in you application. Call this function as soon as possible
after engine init, since it will change the way Raydium renders objects (think
about display lists).
**/
__rayapi void raydium_fog_volumetric_enable(void);
/**
When you call this function, fog is no more applied using fragment depth,
but using ##RENDER_VOLUMETRIC_FOG_AXIS## (see config.h).
You must have called ##raydium_fog_volumetric_support()## before enabling
volumetric fog.
**/
__rayapi void raydium_fog_volumetric_disable(void);
/**
Reset fog sytem to default behavior (fragment depth).
**/
#endif

428
raydium/headers/gui.h Normal file
View File

@ -0,0 +1,428 @@
#ifndef _GUI_H
#define _GUI_H
#include "../gui.h"
/*=
Graphic User Interfaces
3200
**/
// Introduction
/**
Raydium provides a support for simple GUI definitions thru a set of
functions (RayPHP interface is available).
Raydium's GUI are themable, using ".gui" theme text files. A default "full"
theme is provided as "theme-raydium2.gui" (and suitable ".tga" file) on the
data repository.
Complete informations about theme building are readable in this file.
**/
// Vocabulary
/**
This API will allow declaration of:
- "widgets" (label, button, edit box, track bar, check box, combo box, zone)
- "windows" (containers for widgets)
"Focus" is supported for windows and widgets. The final user will not have
any control on windows focus. "Tab" key is used for widget focus cycling.
Widgets and windows are identified by a name or by a unique numeric id.
**/
// Building
/**
The idea is simple: build a window (position and size), and create
widgets over this window.
All widgets are created using the current sizes (x,y and font). See
suitable function).
Buttons provides a simple callback, and all other widgets (but label)
provides an unified "read" function. Window deletion is also possible.
You must set current theme before any of this operations (see below).
A void(void) callback is available if you want to draw something **over**
the GUI, named ##raydium_gui_AfterGuiDrawCallback##.
**/
__rayapi void raydium_gui_window_init(int window);
/**
Internal use. Will reset ##window##.
**/
__rayapi void raydium_gui_init(void);
/**
Internal use. Will init all GUI API. Called once by Raydium.
**/
__rayapi void raydium_gui_theme_init(void);
/**
Internal use. Will init theme.
**/
__rayapi int raydium_gui_theme_load(char *filename);
/**
This function will load and set current theme (".gui" files). You must load
a theme by yourself, since Raydium will never do it for you.
This function must be called before GUI building.
**/
__rayapi signed char raydium_gui_window_isvalid(int i);
/**
Mostly internal. Will check if ##i## window is valid.
**/
__rayapi int raydium_gui_window_find(char *name);
/**
Will search ##name## window's numeric id.
**/
__rayapi void raydium_gui_window_OnDelete(int window, void *OnDelete);
/**
This function sets OnDelete callback for ##window## deletion.
This callback must follow void f(void) prototype. The call is done **before**
window deletion.
**/
__rayapi void raydium_gui_window_OnDelete_name(char *window, void *OnDelete);
/**
Same as above, but using ##window## name.
**/
__rayapi signed char raydium_gui_widget_isvalid(int i, int window);
/**
Mostly internal. Will check if ##i## widget of ##window## is valid.
**/
__rayapi int raydium_gui_widget_find(char *name, int window);
/**
Will search ##name## widget numeric id (for ##window##).
**/
__rayapi void raydium_gui_widget_next(void);
/**
Mostly internal. Cycle focus.
**/
__rayapi void raydium_gui_widget_draw_internal(GLfloat *uv, GLfloat *xy);
/**
Internal use. Generic drawing function.
**/
__rayapi void raydium_gui_button_draw(int w, int window);
/**
Internal use.
**/
__rayapi void raydium_gui_track_draw(int w, int window);
/**
Internal use.
**/
__rayapi void raydium_gui_label_draw(int w, int window);
/**
Internal use.
**/
__rayapi void raydium_gui_edit_draw(int w, int window);
/**
Internal use.
**/
__rayapi void raydium_gui_check_draw(int w, int window);
/**
Internal use.
**/
__rayapi void raydium_gui_combo_draw(int w, int window);
/**
Internal use.
**/
__rayapi void raydium_gui_zone_draw(int w, int window);
/**
Internal use.
**/
__rayapi void raydium_gui_window_draw(int window);
/**
Internal use.
**/
__rayapi void raydium_gui_draw(void);
/**
Internal use. GUI drawing callback.
**/
__rayapi int raydium_gui_button_read(int window, int widget, char *str);
/**
Internal use. Button read accessor (dummy).
**/
__rayapi int raydium_gui_button_write(int window, int widget, char *str);
/**
Internal use. Button write accessor.
**/
__rayapi int raydium_gui_label_read(int window, int widget, char *str);
/**
Internal use. Label read accessor (dummy).
**/
__rayapi int raydium_gui_label_write(int window, int widget, char *str);
/**
Internal use. Label write accessor.
**/
__rayapi int raydium_gui_track_read(int window, int widget, char *str);
/**
Internal use. Track read accessor.
**/
__rayapi int raydium_gui_track_write(int window, int widget, int value);
/**
Internal use. Track write accessor.
**/
__rayapi int raydium_gui_edit_read(int window, int widget, char *str);
/**
Internal use. Edit read accessor.
**/
__rayapi int raydium_gui_edit_write(int window, int widget, char *str);
/**
Internal use. Edit write accessor.
**/
__rayapi int raydium_gui_check_read(int window, int widget, char *str);
/**
Internal use. Check read accessor.
**/
__rayapi int raydium_gui_check_write(int window, int widget, int value);
/**
Internal use. Check write accessor.
**/
__rayapi int raydium_gui_combo_read(int window, int widget, char *str);
/**
Internal use. Combo read accessor.
**/
__rayapi int raydium_gui_combo_write(int window, int widget, int value);
/**
Internal use. Combo write accessor.
**/
__rayapi int raydium_gui_zone_read(int window, int widget, char *str);
/**
Internal use. Zone read accessor.
**/
__rayapi void raydium_gui_show(void);
/**
Will show current built GUI.
**/
__rayapi void raydium_gui_hide(void);
/**
Will hide current built GUI. This is the default state.
**/
__rayapi signed char raydium_gui_isvisible(void);
/**
Will return current visibility of GUI.
**/
__rayapi void raydium_gui_window_delete(int window);
/**
Will delete ##window##. No further access to widgets is possible.
**/
__rayapi void raydium_gui_window_delete_name(char *window);
/**
Same as above, but using ##window##'s name.
**/
__rayapi void raydium_gui_widget_sizes(GLfloat sizex, GLfloat sizey, GLfloat font_size);
/**
Each widget is created using 3 size: X size, Y size and font size. This
function will allow you to set all sizes for a widget or a group of widget.
Unit: percents (screen)
**/
__rayapi int raydium_gui_window_create(char *name, GLfloat px, GLfloat py, GLfloat sizex, GLfloat sizey);
/**
Obviously, this function will create a new window. This window will take focus
and overlap any previous window.
##px## and ##py## for X and Y position on the screen, and ##sizex## and ##sizey##
for sizes, obviously.
Unit: percents (screen)
**/
__rayapi int raydium_gui_internal_object_create(char *name, int window, signed char type, GLfloat px, GLfloat py, GLfloat sizex, GLfloat sizey, GLfloat font_size);
/**
Internal use.
Small (and ugly) tip: you can build many widgets with the same name, prefixing
the name with '*'.
**/
__rayapi int raydium_gui_button_create(char *name, int window, GLfloat px, GLfloat py, char *caption, void *OnClick);
/**
This function will create a new button, with ##name## and with ##window## for
parent.
You need to provide a ##caption## ("title") and a OnClick callback function.
This callback must follow this prototype:
%%(c)void btnButtonClick(raydium_gui_Object *w)%%
You can find ##raydium_gui_Object## structure declaration in ##raydium/gui.h##,
if needed.
Unit for position (##px## and ##py##): percents (**window**)
**/
__rayapi int raydium_gui_button_create_simple(char *name, int window, GLfloat px, GLfloat py, char *caption);
/**
Same as above, but no OnClick callback function is asked. This type of button
is "readable" thru ##raydium_gui_button_clicked()##.
**/
__rayapi int raydium_gui_label_create(char *name, int window, GLfloat px, GLfloat py, char *caption, GLfloat r, GLfloat g, GLfloat b);
/**
This function will create a new label, with ##name## and with ##window## for
parent.
You need to provide a ##caption## ("title") and an RGB color (0..1 interval)
Unit for position (##px## and ##py##): percents (**window**)
**/
__rayapi int raydium_gui_track_create(char *name, int window, GLfloat px, GLfloat py, int min, int max, int current);
/**
This function will create a new trackbar, with ##name## and with ##window## for
parent.
You need to provide a ##min## interger value, a ##max## and ##current## value.
Unit for position (##px## and ##py##): percents (**window**)
**/
__rayapi int raydium_gui_edit_create(char *name, int window, GLfloat px, GLfloat py, char *default_text);
/**
This function will create a new edit box, with ##name## and with ##window##
for parent.
You may provide a default text (or an empty string), if needed. Unless all
others Raydium's data, max string length is ##RAYDIUM_GUI_DATASIZE## and
not ##RAYDIUM_MAX_NAME_LEN##, since this component may handle bigger strings.
See ##raydium/gui.h## for more informations.
Unit for position (##px## and ##py##): percents (**window**)
**/
__rayapi int raydium_gui_check_create(char *name, int window, GLfloat px, GLfloat py, char *caption, signed char checked);
/**
This function will create a new check box, with ##name## and with ##window##
for parent.
You need to provide a ##caption## ("title") and a boolean state (checked or not).
Unit for position (##px## and ##py##): percents (**window**)
**/
__rayapi int raydium_gui_combo_create(char *name, int window, GLfloat px, GLfloat py, char *items, int current);
/**
This function will create a new edit box, with ##name## and with ##window##
for parent.
##items## is a string, using '\n' as a separator. It's allowed to create an
empty item.
##current## is the default selected item in ##items##. (first = 0)
Unless all others Raydium's data, max string length is ##RAYDIUM_GUI_DATASIZE##
and not ##RAYDIUM_MAX_NAME_LEN##, since this component may handle bigger
strings. See ##raydium/gui.h## for more informations.
Unit for position (##px## and ##py##): percents (**window**)
**/
__rayapi int raydium_gui_zone_create(char *name, int window, GLfloat px, GLfloat py, GLfloat sx, GLfloat sy, int tag, void *OnClick);
/**
This function will create a "zone" with ##name## and with ##window## for
parent. A zone will act like a button, but will highlight a rectangular area
of the window.
This widget will return its ##tag## when you'll read it, and will
update ##raydium_gui_button_clicked()## value when clicked.
Unit for position/size (##px##, ##py##, ##sx## and ##sy##): percents (**window**)
**/
__rayapi int raydium_gui_read(int window, int widget, char *str);
/**
Use this function to get ##widget##'s state (for ##window##).
This function will always return this information thru two variable:
an integer (returned value) and a string (##str##).
This information is specific to ##widget##'s type (checked or not for a
checkbox, current choice for a combo, current string for an edit box, ...)
Please, note ##str## must be allocated before function call. This is also
the case for PHP scripts :
%%(php)
$str=str_pad("",256); // "pre-alloc"
$val=raydium_gui_read_name("main","track",$str);
echo "value=$val, string='$str'";
%%
**/
__rayapi int raydium_gui_read_name(char *window, char *widget, char *str);
/**
Same as above, but ##window## and ##widget## are resolved thru names, and
not numeric id.
**/
__rayapi int raydium_gui_read_widget(raydium_gui_Object *w, char *str);
/**
Same as ##raydium_gui_read()##, but using a ##raydium_gui_Object## pointer.
Useful for button callbacks, for example.
**/
__rayapi signed char raydium_gui_write(int window, int widget, char *str, int value);
/**
With this function, you can change the value of a ##widget## on a ##window##.
- With buttons, you must use ##str## to change caption.
- With labels, you must use ##str## to change caption.
- With tracks, you must use ##value## to change the current value.
- With edits, you must use ##str## to change text.
- With cheks, you must use ##value##: ##1## means "checked", ##0## "unchecked".
- With combos, you must use ##value## as an ID to change wich entry is selected.
Returns 1 when all is OK, 0 when it fails and -1 when nothing was changed.
**/
__rayapi int raydium_gui_write_name(char *window, char *widget, char *str, int value);
/**
Same as above, but ##window## and ##widget## are resolved thru names, and
not numeric id.
**/
__rayapi int raydium_gui_button_clicked(void);
/**
This function will return the id of the last clicked button,
or -1 if none were clicked.
The id is built like this : ##window * 1000 + widget_id##
Usefull for PHP scripts, since it's not possible to create callback for
buttons with RayPHP.
**/
__rayapi int raydium_gui_list_id(char *item, char *list);
/**
This function will return ##item##'s id in ##list##. Returns -1 if not found.
Useful for combo index, for example.
**/
__rayapi void raydium_gui_widget_focus(int widget, int window);
/**
Sets focus on ##widget## for ##window##.
**/
__rayapi void raydium_gui_widget_focus_name(char *widget, char *window);
/**
Same as above, but using widget and window names
**/
#endif

77
raydium/headers/hdr.h Normal file
View File

@ -0,0 +1,77 @@
#ifndef _HDR_H
#define _HDR_H
/*=
Pseudo HDR
4300
**/
// Introduction
/**
**/
__rayapi void raydium_hdr_init(void);
/**
Internal use.
**/
__rayapi void raydium_hdr_enable(void);
/**
**/
__rayapi void raydium_hdr_disable(void);
/**
**/
__rayapi void raydium_hdr_internal_window_malloc(void);
/**
Internal use.
**/
__rayapi void raydium_hdr_block(signed char blocking);
/**
**/
__rayapi void raydium_hdr_blur(unsigned char *in, unsigned char *out);
/**
**/
__rayapi void raydium_hdr_map(void);
/**
**/
__rayapi void raydium_hdr_map_apply(void);
/**
**/
__rayapi void raydium_hdr_settings_color_local(GLfloat r, GLfloat g, GLfloat b, GLfloat a);
/**
**/
__rayapi void raydium_hdr_settings_color_ambient(GLfloat r, GLfloat g, GLfloat b, GLfloat a);
/**
**/
__rayapi void raydium_hdr_settings_eye(float speed, float alpha_max);
/**
**/
__rayapi void raydium_hdr_settings(GLfloat *color_local, GLfloat *color_ambient, float eye_speed, float alpha_max);
/**
**/
__rayapi signed char raydium_hdr_texture(int texture, signed char hdr); // display lists !!
/**
**/
__rayapi signed char raydium_hdr_texture_name(char *texture, signed char hdr);
/**
Same as above, but using ##texture## name.
**/
__rayapi void raydium_hdr_texture_reset(void); // display lists !!
/**
**/
#endif

50
raydium/headers/init.h Normal file
View File

@ -0,0 +1,50 @@
#ifndef _INIT_H
#define _INIT_H
/*=
Initialization
2400
**/
// Introduction
/**
This file is mainly designed for internal uses, but there's anyway
some interesting functions.
**/
__rayapi char *raydium_version(void);
/**
Return Raydium Engine version as a static string. Format is "x.yyy".
You can also find defines for this, named ##RAYDIUM_MAJOR## (x)
and ##RAYDIUM_MINOR## (yyy).
**/
__rayapi void raydium_init_lights (void);
/**
Internal use. Must be moved to light.c.
**/
__rayapi void raydium_init_objects (void);
/**
Internal use. Must be moved to object.c.
**/
__rayapi void raydium_init_key (void);
/**
Internal use. Must be moved to key.c.
**/
__rayapi void raydium_init_reset (void);
/**
This function is supposed to reset the whole Raydium engine:
textures, vertices, lights, objects, ...
Never tested yet, and probaly fails for many reasons when called more than
one time.
**/
__rayapi void raydium_init_engine (void);
/**
Internal use. **Never** call this function by yourself, it may cause
huge memory leaks.
**/
#endif

View File

@ -0,0 +1,26 @@
#ifndef _INTERNAL_H
#define _INTERNAL_H
/*=
"Internal" informations access
2000
**/
__rayapi void raydium_internal_dump (void);
/**
This function is now systematically called by Raydium at application's exit,
displaying some informations about loaded textures, objects, registered data,
network statistics.
**/
__rayapi void raydium_internal_dump_matrix (int n);
/**
Dumps matrix to console.
##n## values are:
%%
0 for GL_PROJECTION_MATRIX
1 for GL_MODELVIEW_MATRIX
%%
**/
#endif

71
raydium/headers/joy.h Normal file
View File

@ -0,0 +1,71 @@
#ifndef _JOY_H
#define _JOY_H
/*=
Joysticks, pads and force feedback
3100
**/
// Introduction
/**
Raydium supports Joysticks, joypads, steering wheels, force feedback devices,
keyboard emulation, for Linux only.
Since API could change during Win32 integration, there is no particular
documentation about this subject.
Interesting variables:
%%(c)
signed char raydium_joy_button[RAYDIUM_BUTTONS_MAX_BUTTONS];
signed char raydium_joy_click;
GLfloat raydium_joy_x;
GLfloat raydium_joy_y;
GLfloat raydium_joy_z;
int raydium_joy;
char raydium_joy_n_axes;
char raydium_joy_n_buttons;
GLfloat raydium_joy_axis[RAYDIUM_JOY_MAX_AXIS]; // "raw" axes data
%%
Buttons are booleans, joy x,y and z are -1 <= (x,y,z) <= 1 and 0 means "center".
**/
/*
#define JS_EVENT_BUTTON 0x01
#define JS_EVENT_AXIS 0x02
#define JS_EVENT_INIT 0x80
extern char number_of_axes, number_of_buttons;
extern int raydium_joy_event_handle;
#ifndef WIN32
struct ff_effect effect_tremble;
#endif
extern struct ff_effect effect_tremble;
extern char effect_tremble_state;
extern clock_t last_event;
*/
__rayapi void raydium_joy_init_vars (void);
__rayapi void raydium_joy_key_emul (void);
/**
Emulate keyboard (directional pad) with joy, if any.
**/
#ifndef WIN32
__rayapi int raydium_joy_process_event (struct js_event e);
#endif
__rayapi void raydium_joy_callback (void);
__rayapi void raydium_joy_ff_autocenter (int perc);
/**
Set Force Feedback autocenter factor.
**/
__rayapi void raydium_joy_init (void);
__rayapi void raydium_joy_close (void);
__rayapi void raydium_joy_ff (void);
__rayapi void raydium_joy_ff_tremble_set (GLfloat period, GLfloat force);
/**
Send tremble effect to Force Feedback device for a determined period,
at a particular force. (no units yet).
**/
#endif

36
raydium/headers/key.h Normal file
View File

@ -0,0 +1,36 @@
#ifndef _KEY_H
#define _KEY_H
/*=
Keyboard & keys
1000
**/
// Introduction
/*=
Keyboard API is already described at the top of this guide,
see section "keyboard input".
**/
__rayapi void raydium_key_normal_callback (GLuint key, int x, int y);
/**
Internal callback.
**/
__rayapi void raydium_key_special_callback (GLuint key, int x, int y);
/**
Internal callback.
**/
__rayapi void raydium_key_special_up_callback (GLuint key, int x, int y);
/**
Internal callback.
**/
__rayapi int raydium_key_pressed (GLuint key);
/**
Will return state of ##key## in the ##raydium_keys[]## array.
This function is usefull to test keyboard from PHP, since RayPHP doest not
support array for now.
**/
#endif

19
raydium/headers/land.h Normal file
View File

@ -0,0 +1,19 @@
#ifndef _LAND_H
#define _LAND_H
/*=
Land
1800
**/
// Introduction
/**
Historically, this file was quite complex, since Raydium was using
his own physic. Now, this file is almost empty, since ODE integration
now provides new landscape functions.
**/
__rayapi GLfloat raydium_land_internal_landtmp (GLfloat x, GLfloat y, GLfloat phase, GLfloat ampl, GLfloat periode);
__rayapi void raydium_land_draw_water (GLfloat phase, GLfloat ampl, GLfloat periode, int sub, GLfloat pas, char *texture);
__rayapi GLfloat raydium_land_surface (GLfloat x, GLfloat y, GLfloat * nx, GLfloat * ny, GLfloat * nz);
#endif

130
raydium/headers/light.h Normal file
View File

@ -0,0 +1,130 @@
#ifndef _LIGHT_H
#define _LIGHT_H
/*=
Lights
900
**/
// Introduction to Raydium light system
/**
When we starts Raydium development, the main idea was to use native OpenGL
lights, and not lightmaps or another method.
This method (native lights) provides 8 simultaneous movable lights,
and is quite effective with recent OpenGL hardware.
You can modify intensity, position, color, you can turn on any light at
any time, make them blinking... Mixing all theses features can result
many effects, as realtime sunset, flashing lights for cars, explosions, ...
Usage is very easy: no need to create lights, just turn them on.
See also: LightMaps
**/
__rayapi void raydium_light_enable (void);
/**
Obvious.
**/
__rayapi void raydium_light_disable (void);
/**
Obvious.
**/
__rayapi signed char raydium_light_texture(int texture, signed char enable);
/**
Texture ##l## will not use lighting if ##enable## is set to 0. Call this
function **before** loading any object using this texture, because
of display lists. Same way, it's not possible to change back this value
after the first object drawing without disabling display lists.
**/
__rayapi signed char raydium_light_texture_name(char *name, signed char enable);
/**
Same as above, but using texture ##name##.
**/
__rayapi GLuint raydium_light_to_GL_light (GLuint l);
/**
Probably useless for end user. (internal uses)
**/
__rayapi void raydium_light_on (GLuint l);
/**
Turns ##l## light on ( 0 <= l <= RAYDIUM_MAX_LIGHTS )
**/
__rayapi void raydium_light_off (GLuint l);
/**
Turns ##l## light off
**/
__rayapi void raydium_light_switch (GLuint l);
/**
Will swith ##l## light state (from "on" to "off", for example).
**/
__rayapi void raydium_light_update_position (GLuint l);
/**
Updates ##raydium_light_position[l]## array changes to hardware.
This function is now used internaly by Raydium,
so you have no reasons to call it by yourself.
**/
__rayapi void raydium_light_update_position_all (void);
/**
See above.
**/
__rayapi void raydium_light_update_intensity (GLuint l);
/**
See above.
**/
__rayapi void raydium_light_update_all (GLuint l);
/**
See above.
**/
__rayapi void raydium_light_move (GLuint l, GLfloat * vect);
/**
Moves light to position ##vect## for light ##l## (vect is GLfloat[4]: x,y,z,dummy).
Just move your lights before camera placement, or your changes
will be applied to the next frame only.
**/
__rayapi void raydium_light_move_3f(GLuint l,GLfloat px, GLfloat py, GLfloat pz);
/*
Same as above, but using 3 GLfloat values
*/
__rayapi void raydium_light_conf_7f(GLuint l,GLfloat px, GLfloat py, GLfloat pz, GLfloat intensity, GLfloat r, GLfloat g, GLfloat b);
/*
Full settings for light ##l##: position, intensity and color, using GLfloat
values.
*/
__rayapi void raydium_light_reset (GLuint l);
/**
This function will restore all defaults for ##l## light.
**/
__rayapi void raydium_light_blink_internal_update (GLuint l);
/**
Useless for end-user.
**/
__rayapi void raydium_light_blink_start (GLuint l, int fpc);
/**
Makes ##l## light blinking at ##fpc## (frames per cycle) rate.
This function will use timecalls soon ("fpc" -> "hertz")
**/
__rayapi void raydium_light_callback (void);
/**
Useless for end-user.
**/
#endif

204
raydium/headers/live.h Normal file
View File

@ -0,0 +1,204 @@
#ifndef _LIVE_H
#define _LIVE_H
#include "../live.h"
/*=
Live textures and videos API
3800
**/
// Introduction
/**
Live API features two distinct parts:
1 - It provides an easy way to create and manage dynamic textures, since you
just have to give a pointer to your image data, and call suitable function
each time this image is changing.
2 - This API also supports video4linux (aka V4L), as an extension of
the Live API. The main goal is to link a video4linux device (webcam,
tv card, ...) to a texture. A callback is also available if you want to
get (and transform) data of every capture.
You'll find detailed informations for each domain below.
**/
// Color conversion
/**
Live API used to work with RGB and RGBA color formats. Since some V4L
devices use other patterns, Live API needs conversion functions.
You've no need to do color conversion by yourself, consider all this
as internal functions.
**/
void v4l_copy_420_block (int yTL, int yTR, int yBL, int yBR, int u, int v, int rowPixels, unsigned char *rgb, int bits);
/**
YUV420P block copy.
This code is not native.
**/
int v4l_yuv420p2rgb (unsigned char *rgb_out, unsigned char *yuv_in, int width, int height, int bits);
/**
YUV420P to RGB conversion.
This code is not native.
**/
// Live Video API
/**
This part of the Live API id dedicated to video devices. For now, the
support is limited to Linux thru V4L API. Every V4L compatible device
should work with Live Video, but for any advanced setup of your video
device (tuner configuration, source, FPS, ...), you must use an external
tool.
By default, Live API supports up to 4 simultaneous devices.
**/
__rayapi signed char raydium_live_video_isvalid(int i);
/**
Internal use, but you can call this function if you want to verify if a
live video device id is valid (in bounds, open, and ready to capture).
**/
__rayapi int raydium_live_video_find_free(void);
/**
Internal use.
Finds a free live video device slot.
**/
__rayapi int raydium_live_video_open(char *device, int sizex, int sizey);
/**
This is where you should start. This function opens ##device## (something
like "/dev/video0"), requesting ##sizex## x ##sizey## resolution.
If ##device## is ##RAYDIUM_LIVE_DEVICE_AUTO##, Raydium will use a default device,
hardcoded or given thru commande line (##--video-device##).
Same story for sizes, with ##RAYDIUM_LIVE_SIZE_AUTO##.
This function will try to detect a compatible palette (grayscale, rgb,
yuv420p, with 4, 6, 8, 15, 16 and 24 bits per pixel) and capture
method (##read()## or ##mmap()##).
Returns -1 in case or error, device id otherwise.
**/
__rayapi int raydium_live_video_open_auto(void);
/**
Same as above, but with full autodetection.
**/
__rayapi int raydium_live_video_read(raydium_live_Device *dev);
/**
Internal V4L read function.
**/
__rayapi void raydium_internal_live_video_callback(void);
/**
internal frame callback.
**/
// Live API Core
/**
the main goal of the Live API is to allow you to create your own
dynamic textures. The first method is to provide your own picture data thru a
pointer, the second method is to use a Live Video device (see above) as
data source.
**/
__rayapi void raydium_internal_live_close(void);
/**
Internal close function.
**/
__rayapi void raydium_live_init(void);
/**
Internal init function.
**/
__rayapi signed char raydium_live_texture_isvalid(int i);
/**
Internal use, but you can call this function if you want to verify if a
live texture id is valid (in bounds, open, and ready to capture).
**/
__rayapi int raydium_live_texture_find_free(void);
/**
Internal use.
Finds a free live texture slot.
**/
__rayapi int raydium_live_texture_find(int original_texture);
/**
Resolvs ##original_texture## id (native Raydium texture id) to a
live texture id, if any.
**/
__rayapi int raydium_live_texture_create(char *as, unsigned char *data_source, int tx, int ty, int bpp);
/**
Create a new Live Texture with ##as## name. You must provide a ##data_source##
with RGB or RGBA format, with ##tx## and ##ty## size.
Possible bpp values are 24 (RGB) and 32 (RGBA).
Returns the live texture id, or -1 when it fails.
**/
__rayapi int raydium_live_texture_video(int device_id, char *as);
/**
This is another way to create a Live Texture, but using a Live Video device
for data source. Provide texture name (##as##) and Live ##device_id##.
**/
__rayapi void raydium_live_texture_refresh(int livetex);
/**
When your data source have changed, call this function to refresh new
data to hardware. Obviously, this function is useless for Live Video textures
since Raydium will automatically refresh data.
**/
__rayapi void raydium_live_texture_refresh_name(char *texture);
/**
Same as above, but using ##texture## name.
**/
__rayapi void raydium_live_texture_refresh_callback_set(int livetex, void *callback);
/**
You can create a "OnRefresh" callback for any Live Texture (##livetex## is an
id to this texture). This is mostly usefull for Live Video texture.
Your callback must follow this prototype :
##int refresh_callback(unsigned char *data, int tx, int ty, int bpp)##
You have full write access to ##data##, allowing you to draw over
the provided picture (warning: for non video Live textures, ##data## pointer
is not owned by Raydium and may be "read only")
You must return 1 to confirm data flushing, or 0 to cancel this refresh.
**/
__rayapi void raydium_live_texture_refresh_callback_set_name(char *texture, void *callback);
/**
Same as above, but using ##texture## name.
**/
__rayapi void raydium_live_texture_mask(int livetex, GLfloat alpha);
/**
This function will draw a fullscreen mask using ##livetex## Live Texture id and
##alpha## opacity (0 means transparent, 1 means fully opaque, allowing any
intermediate value). Use this function at any place of your rendering
function AFTER camera call and obviously before ##raydium_rendering_finish##.
**/
__rayapi void raydium_live_texture_mask_name(char *texture, GLfloat alpha);
/**
Same as above, but using ##texture## name.
**/
__rayapi void raydium_live_texture_draw(int livetex, GLfloat alpha,GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2);
/**
This function is a clone of ##raydium_osd_draw()##, dedicated to live textures.
This function will draw the video ##livetex## on the screen, from (x1,y1) to
(x2,y2).
**/
__rayapi void raydium_live_texture_draw_name(char *texture, GLfloat alpha,GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2);
/**
Same as above, but using ##texture## name.
**/
#endif

31
raydium/headers/log.h Normal file
View File

@ -0,0 +1,31 @@
#ifndef _LOG_H
#define _LOG_H
/*=
Logging
300
**/
// Introduction to log.c
/**
Raydium uses and provides his own logging system,
hidden behind a single function, as shown below.
**/
#ifndef RAYDIUM_NETWORK_ONLY
__rayapi void raydium_console_line_add (char *format, ...);
#endif
__rayapi void raydium_log (char *format, ...);
/**
This function must be used like "printf", using a format
("%s, %i, %x, ...") and then, suitable variables,
but without the end-line char ('\n')
%%(c)
raydium_log("You are player %i, %s",player_number,player_name);
%%
For now, this function writes to the parent terminal and the in-game console, with "Raydium: " string prefix.
The user can force logging to a file, using ##--logfile## command line switch.
**/
#endif

369
raydium/headers/main.h Normal file
View File

@ -0,0 +1,369 @@
/*=
Introduction to Raydium
100
**/
// About
/**
Well, first of all, let me talk about [[Raydium]] goals: this project
aims to be simple, easy to use, portable, and quite fast.
[[Raydium]] is a C written abstract layer, on top of OpenGL,
and [[GLU]]: this means you can write an entire 3D
application without calling any OpenGL function.
Want to draw an object ? call the suitable [[Raydium]] function,
and all textures and vertices will be loaded, and your object drawn.
Want to make an explosion ? Same thing: call the right function.
Note that you can call OpenGL functions anyway, if necessary.
About portability, I can say a few things: [[Raydium]] was initially
planned for Linux only, but with a "clean" (nearly [[ANSI]]) code,
and, in facts, we have been able to compile Raydium under Visual Studio (Windows)
and mingw with a very few modifications.
So you can expect a correct result on any system providing
OpenGL (at least 1.2), [[GLU]] and a C compiler. Using Raydium as a shared
library (.so or DLL), you can also use C++ language for you own applications
As we ([[CQFD Corp]].) needed a library for our own games, demos,
and... and things like that, and as I was interested by OpenGL,
I starts to write [[Raydium]].
Raydium is perfect for outdoors spaces, integrating a landscape engine,
with suitable physic, supports dynamic lighting, fog, blending, water
and waves, reflections, and more, but also provides everything for indoor,
with radiosity lightmaps for example.
Some other advanced features are available : physics, scripting,
live video, transparent networking, GUI, shaders, ...
This features list will probably grow up during Raydium developpement, see
Raydium website: http://raydium.org/
You'll find, in this document, a list of many functions and possibilities
of [[Raydium]], but if it's your first view of Raydium, you should
start with tutorials ( http://wiki.raydium.org/wiki/RaydiumTutorials ) and
packaged demo programs.
After this short introduction, let's talk about the [[API]] itself,
starting with the main file (from the programmer's point of vue)
of [[Raydium]]: common.c
**/
// Defines
/**
As mentioned above, the file common.c is quite interesting,
for several reasons: first, as this file includes all others [[Raydium]]'s
files, you can have an overview of the whole project, just by looking at this.
It can also be used as a "quick help", since all variables are declared
here, and not in the corresponding files. I mean, for example,
that "##raydium_light_intensity...##" will be declared in common.c,
not in light.c . There's many reasons for using such "style",
but you must only retain that it is simpler for you :)
Ok, after this little disclaimer, we can have a look to the first part
of our file.
After usual #include (nothing interesting here), we find some #defines.
===generic limits===
The first #define block determine limits of your application,
and here you are the actual values for basic defines:
%%(c)
#define RAYDIUM_MAX_VERTICES 500000
#define RAYDIUM_MAX_TEXTURES 256
#define RAYDIUM_MAX_LIGHTS 8
#define RAYDIUM_MAX_NAME_LEN 255
#define RAYDIUM_MAX_OBJECTS 1024
%%
- As you may expect, ##MAX_VERTICES## defines the amount of memory you'll
waste with vertex tables. These tables will contain all loaded objects,
then remember each time you draw something (object),
[[Raydium]] loads it (if not already done). Currently, there is no "delete"
mechanism implemented (except by deleting all objects).
Let me give you a scale: with an Athlon XP1900+, [[GeForce]] 3,
actual [[Raydium]] devel. version 0.31, with around 100 000 vertices,
losts of options (sky, blending, 2 lights, 15 textures, ...),
Raydium renders ~ 45 FPS. Beyond this, a very correct object uses less
than 10 000 vertices. So 500 000 vertices, the actual default,
is quite large. It's also important to talk about memory: Linux is
very efficient on this point, and allocates only "really used" memory.
Under Linux, with the above scene, Raydium used about 20 MB (data only),
instead of "much more" (~ 5x). I haven't made any test about this under
Windows, but we can expect worse results.
- There's nothing really important to say about ##MAX_TEXTURES##,
since that doesn't influence the amount of memory used. You are not
limited to 8 bits values, but 256 seems very comfortable (and you must
pay attention to the capacities of your 3D hardware !)
- The next define, ##MAX_LIGHTS## is very important: OpenGL, for now
(version 1.3 and lower), impose 8 lights at least, and all current
hardware doesn't manage more. If this situation is likely to evolve,
we will move this #define to a variable, and will ask hardware for its
capacities at initialization, but, for the moment, do not exceed 8.
- Next, ##NAME_LEN##, limits the maximum length of strings (textures and
objects names) used by Raydium. Default value should be perfect.
(avoid higher values, since it could slow down name searches)
- ##MAX_OBJECTS## use the same mechanism as ##MAX_TEXTURES##, and addition
with the fact that hardware is not concerned, it can be ignored.
===Options and parameters===
This is the next part of our #define section, I will not explain these
constants here, but in respective sections, so you'll have just you to
remember they're declared here.
**/
// Basic vars
/**
This section aims to describe each variable [[Raydium]] use, one by one.
Some (most ?) of them are used internaly only, but you could need to access
it. Moreover, you'll better understand how Raydium works by looking at
these variables.
===Keyboard input===
Following variables can be found:
##raydium_key_last## will always contains the last key (normal or special)
pressed down. You'll find a explanation about normal and special keys above.
##raydium_key[]## hosts all special keys state. Currently, you must use
[[GLUT]] define's (Raydium aliases will come soon), limited to
following keys:
- ##GLUT_KEY_F1## to ##GLUT_KEY_F12##
- ##GLUT_KEY_LEFT##, ##GLUT_KEY_RIGHT##, ##GLUT_KEY_UP##, ##GLUT_KEY_DOWN##
- ##GLUT_KEY_PAGE_UP##, ##GLUT_KEY_PAGE_DOWN##
- ##GLUT_KEY_HOME##, ##GLUT_KEY_END##, ##GLUT_KEY_INSERT##
These are "special" keys: they have 2 states. released (0),
and pressed (non zero). It means you can do something
(move an object, turn on a light) **UNTIL** user stops to press the key.
"Normal" keys have a different behavior: you can do something **IF** user
press a key (exit from application if ESC is pressed, for example).
You'll have no information about key's release.
A normal key is sent through ##raydium_key_last##, a special one through
##raydium_key[]## AND ##raydium_key_last##.
You must see ##raydium_key_last## as an "event", fired when the user press
a key (ANY key: special or not). When a normal key is pressed, you'll get
the ASCII value + 1000 assigned to ##raydium_key_last##. (1027 for "ESC", for
example)
Here is a method to use special keys:
%%(c) if(raydium_key[GLUT_KEY_UP]) move_car(); %%
Yes, it's easy. You can also use
%%(c) if(raydium_key_last""==""GLUT_KEY_UP) explose(); %%
for example, if you need to carry out a specific action.
It's ok for you ? use ##raydium_key[]## to keep the car moving until
user release UP key, or use ##raydium_key_last## to explode the car
when the user tries to start it :)
===Mouse input===
Easy.
You can get actual mouse position on the window (relative to window's
position on screen, I mean) with ##raydium_mouse_x## and ##raydium_mouse_y##
(GLuint), starting at (0,0) for upper left
(Warning: some [[GLUT]] implementations can give mouse position even
when mouse is out of the window ! Check boundaries before using these values).
Raydium use: 1 for left button, 2 for right button, and 3 for
middle button (0 for none) with ##raydium_mouse_click## for the last click
value. (generated one time per click)
Raydium will now use 4 (up) and 5 (down) for mouse wheel, if any.
You can permanently get a button's state, up (0) or down (non zero),
using ##raydium_mouse_button[x]##, where x is 0 for left button, 1 for right
one, and 2 for middle button.
===Textures===
##raydium_texture_index## and ##raydium_texture_current_main## (GLuint) are used
internaly to determine repectively how many textures are loaded,
wich is the current one.
The next variable, ##raydium_texture_filter##, is very important. You can
assign ##RAYDIUM_TEXTURE_FILTER_NONE## (default), ##RAYDIUM_TEXTURE_FILTER_BILINEAR##
or ##RAYDIUM_TEXTURE_FILTER_TRILINEAR## (recommended).
Using no texture filter can gives you higher framerate on old 3D hardware,
but this is quite ugly.
You can activate bilinear filtering without any framerate impact on
most recent video cards, and get a much more attractive rendering.
Trilinear filtering uses Bilinear filtering and MipMaps. A MipMaped
texture is a duplicated texture (3 times, with Raydium), but at different
sizes. A 512x512 texture will generate, for example, a (smoothed)
256x256 texture, and a (smoothed) 128x128 one. Your video card will
use these textures according to distance from POV (point of vue),
reducing flickering effect.
This is the best filtering Raydium can use, for a great rendering quality.
Good and recent 3D hardware can do trilinear filtering in a single pass,
so it must be the default setting for your application.
About ##raydium_texture_filter## itself: changing this variable will not modify
the rendering, but the way to load textures. It means you can (for example)
use trilinear only for landscape textures, and bilinear for others.
It also means you must reload (erase) a texture to change it's filter.
Note that Raydium will never use trilinear filter with blended (transparent)
textures, for good reasons :)
Let's talk quickly about next (internal) texture variables:
##raydium_texture_blended[]## is a flag table, where each element is
non zero for a blended (RGBA) texture, and 0 for an RGB one.
For Raydium, when a texture does not contain a "bitmap" (texture file,
for example), it contains a plain color, and this color is stored in
##raydium_texture_rgb[][4]## (4 is for RGBA, values between 0 and 1).
You can load an rgb texture with "rgb" keyword. For example, instead of
loading "red.tga", you can load "rgb(0.8,0.1,0.1)".
##raydium_texture_name[]## table simply contains texture filenames.
Last thing, ##raydium_texture_to_replace##,
can be used to erase an already loaded texture.
Set the variable to n, and load a new texture: texture number "n" will be
replaced in memory.
===Projection===
Raydium supports 2 types of projection: ##RAYDIUM_PROJECTION_ORTHO##
(orthographic) and ##RAYDIUM_PROJECTION_PERSPECTIVE##.
First of all, let us point out what "projection" is. Using a "perspective"
projection, closest objects will looks larger than the orthers. It is
typically used in video games (since human eye runs like that),
by opposition to orthographic projection, wich is mostly used by 3D
modeling tools. The principle is simple, discover it by yourself :)
Raydium reads ##raydium_projection## to determine wich method to use.
Each projection is configured with ##raydium_projection_*## variables.
Some of these variables are used both by "perspective" and "orthographic"
projections.
Here is what common.c says:
%%(c)
GLFLOAT RAYDIUM_PROJECTION_FOV; // PERSPECTIVE ONLY
GLFLOAT RAYDIUM_PROJECTION_NEAR; // PERSPECTIVE & ORTHO
GLFLOAT RAYDIUM_PROJECTION_FAR; // PERSPECTIVE & ORTHO
GLFLOAT RAYDIUM_PROJECTION_LEFT; // ORTHO ONLY
GLFLOAT RAYDIUM_PROJECTION_RIGHT; // ORTHO ONLY
GLFLOAT RAYDIUM_PROJECTION_BOTTOM; // ORTHO ONLY
GLFLOAT RAYDIUM_PROJECTION_TOP; // ORTHO ONLY
%%
You've probably noticed that orthographic projection defines a "box"
with your screen: near, far, left, right, bottom. Everything out ouf
this box will never be displayed.
Perspective projection is based on FOV: Field Of Vision, given in degrees.
A common "human" fov is 60<36>, up to 90<39> without any noticeable deformation.
"near" and "far" are used for many things: Z-Buffer precision is affected,
and clipping too: as with "orthographic", nothing will be displayed beyond
"far", and fog, if enabled, will hide this "limit". This is right for "near",
too, but without fog, obviously :)
Also remember that decreasing FOV will zoom in.
You must call ##raydium_window_view_update()## after any modification on one
(or more) of these variables (see "Window Managment" section for more
information)
===Frame size and color===
##raydium_window_tx## and ##raydium_window_ty## are read-only variables,
providing you actual frame size.
##raydium_background_color[4]## is a RGBA table, and will be used for
frame clearing, and fog color. You can change this variable, and call
respective update functions (frame and fog), or simply use
##raydium_background_color_change(GLfloat r, GLfloat g, GLfloat b, GLfloat a)##.
More informations in corresponding sections.
===Vertices===
Vertices data structure is distributed in 4 parts:
- ##raydium_vertex_*## : these tables will simply contains vertices coordinates
- ##raydium_vertex_normal_*## : vertices normals. Raydium will maintain
two distinct normal tables, and this one will be used for calculations.
- ##raydium_vertex_normal_visu_*## : the other normal table, used for
lighting. Smoothing "visu" normals will provides a better rendering, and Raydium includes
all necessary functions to automate this task.
- ##raydium_vertex_texture_u##, ##*raydium_vertex_texture_v##,
##*raydium_vertex_texture## contains, for each vertex stored
in the vertices data structure, u and v mapping information,
and associated texture number. U and V are texture mapping coordinates.
Raydium can automatically generates some of these data
(normals and uv coords, that is), Read "Vertices" section above
for more information.
PLEASE, do not write directly in these tables, use dedicated functions.
===Objects===
Objects are loaded in Vertices stream, identified by a "start" and an "end"
(##raydium_object_start[]## and ##raydium_object_end[]##) in this stream.
An index is incremented each time you load an object
(##GLuint raydium_object_index##). Filename is also stored in
##raydium_object_name[][]##. Go to "Objects" section to know more.
===Lights===
First of all, ##raydium_light_enabled_tag## contains 0 when light is
disabled, non-zero otherwise. This is a read-only variable, so use
suitable functions.
Currently, for Raydium, a light can have 3 states: on, off, or blinking.
##raydium_light_internal_state[]## stores this.
Next comes all light's features: position, color, intensity. You can
modify directly these variables, and call update fonctions,
if needed (not recommended).
Next, ##raydium_light_blink_*## are used internaly for blinking lights,
setting lowest, higher light intensity, and blinking speed.
Do noy modify these variables, use suitable functions.
You should read the chapter dedicated to lights for more information.
===Fog===
Only one variable, here: ##raydium_fog_enabled_tag##, switching from zero
to non zero if fog is enabled. Do NOT use this variable to enable or
disable fog, but suitable functions, this variable is just a tag.
===Camera===
Since many calls to camera functions are done during one frame,
Raydium must track if any call to these functions was already done,
using ##raydium_frame_first_camera_pass## boolean.
##raydium_camera_pushed##, also used as a boolean, stores stack state.
When you place your camera in the scene with Raydium, it pushes matrix
on top of the stack, so you can modify it (the matrix), placing an object
for example, an restore it quickly after, by popping matrix off.
**/

60
raydium/headers/misc.h Normal file
View File

@ -0,0 +1,60 @@
// This file is a footer for Raydium documention
// No compilation is required.
/*=
Miscalleneous
9000
**/
// License
/**
Raydium engine and provided applications are released under GPL version 2.
You can found the original text of this license here :
http://www.gnu.org/licenses/gpl.txt
**/
// About CQFD Corp Raydium Team
/**
Alphabetical order:
batcox, Blue Prawn, Cocorobix, FlexH, Jimbo, manproc, Mildred, neub, RyLe,
vicente, whisky, willou, Xfennec, Yoltie.
**/
// Todo
/**
No particular order:
- rendering core rewrite
- self-running demo
- (idea from RyLe) 'rayphp/' scripts integration into the binary (and why
not, a "PACK style" support).
- more network stack optimisations (UDP reads, mainly)
- better organisation of comp.sh and ocomp.sh files (separate options
and build process)
See also my todo: http://wiki.raydium.org/wiki/XfenneC
Please, if you start working on a feature, say it on the Wiki.
**/
// Links
/**
http://raydium.org (Raydium home)
svn://raydium.org/raydium/trunk (SVN trunk)
http://raydium.org/svn.php (SVN "live" changelog)
http://memak.raydium.org (MeMak forum: "a game using Raydium", french)
http://www.cqfd-corp.org (CQFD homesite)
mailto:xfennec -AT- cqfd-corp.org
**/
// Greets
/**
**RyLe**: original implementation of sound.c (OpenAL core sound API)
**BatcoX**: export of RayODE functions into RayPHP (reg_api.c)
and additional PHP wrappers (wrappers.c)
**Mildred**: header and Makefile generator, dynamic version of
Raydium (.so and .a) for Linux.
**/
// The end !

58
raydium/headers/mouse.h Normal file
View File

@ -0,0 +1,58 @@
#ifndef _MOUSE_H
#define _MOUSE_H
/*=
Mouse
1100
**/
// Introduction
/**
Mouse API is almost explainded at the top of this guide, but here it
is some other usefull functions (macros, in facts)
**/
#define raydium_mouse_hide() glutSetCursor(GLUT_CURSOR_NONE);
/**
Hides mouse cursor.
**/
#define raydium_mouse_show() glutSetCursor(GLUT_CURSOR_LEFT_ARROW);
/**
Shows mouse cursor.
**/
#define raydium_mouse_move(x,y) glutWarpPointer((x),(y))
/**
Moves cursor to (##x##,##y##) position (in pixel).
Example if you want to move cursor at window's center:
%%(c)raydium_mouse_move(raydium_window_tx/2, raydium_window_ty/2);%%
**/
__rayapi signed char raydium_mouse_isvisible(void);
/**
Returns true or false (0 or 1), if the mouse is visible or not.
See ##raydium_mouse_show()## and ##raydium_mouse_hide()## above.
**/
__rayapi void raydium_mouse_init (void);
/**
Internal use.
**/
__rayapi void raydium_mouse_click_callback (int but, int state, int x, int y);
/**
Internal callback.
**/
__rayapi void raydium_mouse_move_callback (int x, int y);
/**
Internal callback.
**/
__rayapi int raydium_mouse_button_pressed (int button);
/**
returns ##button## state. (See first part of this document)
**/
#endif

94
raydium/headers/myglut.h Normal file
View File

@ -0,0 +1,94 @@
/*
Raydium - CQFD Corp.
http://raydium.org/
License: GPL - GNU General Public License, see "gpl.txt" file.
*/
// avoid "real GLUT"
#ifndef GLUT_API_VERSION
#ifndef MYGLUT
#define MYGLUT
#include <GL/gl.h>
#include <GL/glu.h>
#define GLUT_LEFT_BUTTON 0
#define GLUT_MIDDLE_BUTTON 1
#define GLUT_RIGHT_BUTTON 2
#define GLUT_DOWN 0
#define GLUT_UP 1
#define GLUT_KEY_F1 1
#define GLUT_KEY_F2 2
#define GLUT_KEY_F3 3
#define GLUT_KEY_F4 4
#define GLUT_KEY_F5 5
#define GLUT_KEY_F6 6
#define GLUT_KEY_F7 7
#define GLUT_KEY_F8 8
#define GLUT_KEY_F9 9
#define GLUT_KEY_F10 10
#define GLUT_KEY_F11 11
#define GLUT_KEY_F12 12
#define GLUT_KEY_LEFT 100
#define GLUT_KEY_UP 101
#define GLUT_KEY_RIGHT 102
#define GLUT_KEY_DOWN 103
#define GLUT_KEY_PAGE_UP 104
#define GLUT_KEY_PAGE_DOWN 105
#define GLUT_KEY_HOME 106
#define GLUT_KEY_END 107
#define GLUT_KEY_INSERT 108
#define GLUT_WINDOW_WIDTH 102
#define GLUT_WINDOW_HEIGHT 103
#define GLUT_WINDOW_DEPTH_SIZE 106
#define GLUT_WINDOW_CURSOR 122
#define GLUT_CURSOR_LEFT_ARROW 1
#define GLUT_CURSOR_NONE 101
#define GLUT_RGB 0
#define GLUT_DOUBLE 2
#define GLUT_DEPTH 16
#define GLUT_GAME_MODE_POSSIBLE 1
// ------------------- variables
// callbacks:
void (*glutReshapeFuncCB)(int width, int height);
void (*glutKeyboardFuncCB)(unsigned char key, int x, int y);
void (*glutSpecialUpFuncCB)(int key, int x, int y);
void (*glutSpecialFuncCB)(int key, int x, int y);
void (*glutMotionFuncCB)(int x, int y);
void (*glutPassiveMotionFuncCB)(int x, int y);
void (*glutMouseFuncCB)(int button, int state, int x, int y);
void (*glutDisplayFuncCB)(void);
void (*glutIdleFuncCB)(void);
// protos
__rayapi void glutInit(int *argc, char **argv);
__rayapi int glutGet(int enu);
__rayapi void glutSetCursor(int cursor);
__rayapi void glutWarpPointer(int x, int y);
__rayapi void glutSwapBuffers(void);
__rayapi void glutIgnoreKeyRepeat(int ignore);
__rayapi void glutReshapeFunc(void *func);
__rayapi void glutKeyboardFunc(void *func);
__rayapi void glutSpecialUpFunc(void *func);
__rayapi void glutSpecialFunc(void *func);
__rayapi void glutMotionFunc(void *func);
__rayapi void glutPassiveMotionFunc(void *func);
__rayapi void glutMouseFunc(void *func);
__rayapi void glutDisplayFunc(void *func);
__rayapi void glutIdleFunc(void *func);
__rayapi int glutExtensionSupported(const char *name);
__rayapi void glutMainLoop(void);
__rayapi void glutWireSphere(GLdouble radius, GLint slices, GLint stacks);
__rayapi void myglutCreateWindow(GLuint tx, GLuint ty, signed char rendering, char *name);
#endif
#endif

514
raydium/headers/network.h Normal file
View File

@ -0,0 +1,514 @@
#ifndef _NETWORK_H
#define _NETWORK_H
/*=
Network
2800
**/
// Bases of Raydium's networking API
/**
Raydium supports networking via UDP/IP, providing high level functions
for multiplayer game development.
Raydium servers are limited to 256 clients for now.
You will find in network.c a set of "low level" functions and vars dedicated to
networked games: players names, event callbacks, UDP sockets,
broadcasts, ...
See a few chapters below for higher level functions.
All this is ready to use. As it's not done in the introduction of this
guide, We will explain here some variables defined in common.h.
%%(c)
#define RAYDIUM_NETWORK_PORT 29104
#define RAYDIUM_NETWORK_PACKET_SIZE 230
#define RAYDIUM_NETWORK_TIMEOUT 5
#define RAYDIUM_NETWORK_PACKET_OFFSET 4
#define RAYDIUM_NETWORK_MAX_CLIENTS 8
#define RAYDIUM_NETWORK_MODE_NONE 0
#define RAYDIUM_NETWORK_MODE_CLIENT 1
#define RAYDIUM_NETWORK_MODE_SERVER 2
%%
Here, we can find network port declaration (Raydium will use only one
port, allowing easy port forwarding management, if needed), default timeout
(unit: second), and the three mode possible for a Raydium application.
But there is also two other very important defines: packet size
(unit: byte) and max number of clients.. This is important because
Raydium uses UDP sockets, and UDP sockets required fixed
length packets, and as you need to set packet size as small as possible
(for obvious speed reasons), you must calculate you maximum
information packet size (players position, for example), multiply
it by ##RAYDIUM_NETWORK_MAX_CLIENTS##,and add ##RAYDIUM_NETWORK_PACKET_OFFSET##
wich represent the required header of the packet.
It's more easy than it seems, look:
//
My game will support 8 players.
I will send players state with 3 floats (x,y,z).
My packet size must be: 8*3*sizeof(float)+RAYDIUM_NETWORK_PACKET_OFFSET = 100 bytes.
//
Please, do not change packet offset size, since Raydium will use it
for packet header.
%%(c)
#define RAYDIUM_NETWORK_DATA_OK 1
#define RAYDIUM_NETWORK_DATA_NONE 0
#define RAYDIUM_NETWORK_DATA_ERROR -1
%%
This three defines are used as network functions result:
%%(c)
if(raydium_network_read_flushed(&id,&type,buff)==RAYDIUM_NETWORK_DATA_OK)
{
...
%%
%%(c) #define RAYDIUM_NETWORK_PACKET_BASE 20 %%
In most network functions, you will find a "type" argument, used to
determine packet goal. This type is 8 bits long (256 possible values),
but Raydium is already using some of them. So you can use
##RAYDIUM_NETWORK_PACKET_BASE## as a base for your own types:
%%(c)
#define NORMAL_DATA RAYDIUM_NETWORK_PACKET_BASE
#define BALL_TAKEN (NORMAL_DATA+1)
#define SCORE_INFO (NORMAL_DATA+2)
#define HORN (NORMAL_DATA+3)
...
%%
===Variables:===
Your own player id (0<= id < RAYDIUM_NETWORK_MAX_CLIENTS),
read only: ##int raydium_network_uid;##
Special value "-1" means that you're not connected (see below).
Current network mode (none, client, server),
read only: ##signed char raydium_network_mode;##
Boolean used to determine client state (connected or not), read only:
##signed char raydium_network_client[RAYDIUM_NETWORK_MAX_CLIENTS];##
example:
%%(c)
if(raydium_network_client[4])
draw_player(4);
%%
Can be used by a server to send data to his clients. Read only:
##struct sockaddr raydium_network_client_addr[RAYDIUM_NETWORK_MAX_CLIENTS];##
Players names, read only:
##char raydium_network_name[RAYDIUM_NETWORK_MAX_CLIENTS][RAYDIUM_MAX_NAME_LEN];##
##OnConnect## and ##OnDisconnect## events (server only):
##void * raydium_network_on_connect;
void * raydium_network_on_disconnect;##
You can place your owns callbacks (##void(int)##) on these events, as in
this example:
%%(c)
void new_client(int client)
{
raydium_log("New player: %s", raydium_network_nameclient);
}
...
int main(int argc, char **argv)
{
...
raydium_network_on_connect=new_client;
...
%%
**/
// Reliablility versus Speed
/**
As explained above, Raydium is using UDP network packets, and as
you may know, UDP is not a reliable protocol, aiming speed before all.
This system is interesting for sending non-sensible data, as player positions,
for example.
But Raydium can handle more important data, using some of methods of TCP
protocol, as Timeouts, ACK, resending, ...
This TCP style packets are available thru "Netcalls".
**/
// High level API: "Netcalls" and "Propags"
/**
Netcalls provides you a good way to handle network exchanges using
callbacks functions, like a simple RPC system.
The idea is simple, built over the notion of "type". See suitable functions for
more information about this system.
Another available mechanism is called Propags, and allows you to "share"
variables over the network (scores, game state, ...) in a very few steps.
You only need to "create" a type, and link a variable to it (any C type or
structure is allowed). After each modification of this (local copy of the)
variable, just call ##raydium_network_propag_refresh*## and that's it. If
any other client (or the server) is applying a modification to this "type",
your local copy is automatically updated.
**/
__rayapi int raydium_network_propag_find (int type);
/**
Lookups a "propag" by his ##type##. Returns -1 is no propag is found.
**/
__rayapi void raydium_network_propag_recv (int type, char *buff);
/**
Internal callback for "propag" receiving.
**/
__rayapi void raydium_network_propag_refresh_id (int i);
/**
Will refresh a propag by his ##id##.
**/
__rayapi void raydium_network_propag_refresh (int type);
/**
Will refresh a propag by his ##type##.
**/
__rayapi void raydium_network_propag_refresh_all (void);
/**
Will refresh all propags
**/
__rayapi int raydium_network_propag_add (int type, void *data, int size);
/**
This function will "register" a new propag. You need to provide the address
of your variable/structure (##data##), ans its ##size##. A dedicated ##type##
is also required (see at the top of this chapter).
**/
__rayapi void raydium_network_queue_element_init (raydium_network_Tcp * e);
/**
Internal use. (TCP style packets)
**/
__rayapi unsigned short raydium_network_queue_tcpid_gen (void);
/**
Internal use. (TCP style packets)
**/
__rayapi void raydium_network_queue_tcpid_known_add (int tcpid, int player);
/**
Internal use. (TCP style packets)
**/
__rayapi signed char raydium_network_queue_tcpid_known (unsigned short tcpid, unsigned short player);
/**
Internal use. (TCP style packets)
**/
__rayapi signed char raydium_network_queue_is_tcpid (int type);
/**
Internal use. (TCP style packets)
**/
__rayapi void raydium_network_queue_element_add (char *packet, struct sockaddr *to);
/**
Internal use. (TCP style packets)
**/
__rayapi unsigned long *raydium_network_internal_find_delay_addr (int player);
/**
Internal use. (TCP style packets)
**/
__rayapi void raydium_network_queue_check_time (void);
/**
Internal use. (TCP style packets)
**/
__rayapi void raydium_network_queue_ack_send (unsigned short tcpid, struct sockaddr *to);
/**
Internal use. (TCP style packets)
**/
__rayapi void raydium_network_queue_ack_recv (int type, char *buff);
/**
Internal use. (TCP style packets)
**/
__rayapi void raydium_network_player_name (char *str);
/**
This function will returns the current player name.
Raydium will ask the OS for "current logged user", but player name may
be provided thru ##--name## command line argument.
**/
// internal hack, no doc provided
__rayapi signed char raydium_network_set_socket_block_internal(int socket, int block);
__rayapi signed char raydium_network_set_socket_block (int block);
/**
This function will sets ##block## (true or false) status to the network stack.
A blocking socket will wait indefinitely an incoming packet. A non blocking one
will return "no data" instead.
You've almost no reason to call this function by yourself.
**/
__rayapi int raydium_network_socket_close(int fd);
/**
Portable socket closing function. See "man 2 close" or closesocket (win32)
docs.
**/
__rayapi signed char raydium_network_socket_is_readable(int fd);
/**
Will return true (1) if there is some data ready on ##fd## socket,
false (0) otherwise.
**/
__rayapi signed char raydium_network_netcall_add (void *ptr, int type, signed char tcp);
/**
This function will register a new Network Callback ("netcall").
With Raydium, you can read the main data stream with
##raydium_network_read_flushed()##, and configure netcalls on random
events (using packet type).
Netcalls signature is: ##void(int type, char *buff)##
As you may configure the same callback function for multiples packet types,
this type is passed to your function, with the temporary ##buff## buffer.
You can extract from field from packet if needed.
If you sets the ##tcp## flag to true (1), your packet will use "TCP style"
network protocol (see a the top of this chapter).
**/
__rayapi void raydium_network_netcall_exec (int type, char *buff);
/**
Internal callback for "netcall" receiving.
**/
__rayapi signed char raydium_network_timeout_check (void);
/**
Internal use.
**/
__rayapi void raydium_network_init_sub(void);
/**
Internal use.
**/
__rayapi signed char raydium_network_init (void);
/**
Nothing interesting unless you're creating a console server (using the
##RAYDIUM_NETWORK_ONLY## directive), since in this case you must do all
inits by yourself...
example :
%%(c)
#define RAYDIUM_NETWORK_ONLY
#include "raydium/index.c"
...
int main(int argc, char **argv)
{
setbuf(stdout,NULL);
signal(SIGINT,quit);
raydium_php_init(); // only if you need PHP support
raydium_network_init();
raydium_network_server_create();
...
%%
**/
__rayapi void raydium_network_write (struct sockaddr *to, int from, signed char type, char *buff);
/**
Obviously, this function will send data.
If you're a client, you don't need to determine to field, as the only
destination is the server, so you can use ##NULL##, for example. If you're
a server, you can use ##raydium_network_client_addr[]## array.
As a client, ##from## argument is generally your own uid (##raydium_network_uid##),
but you can use any other player number if needed.
As a server, ##from## field is useless, since you are the only machine able
to send data to clients.
As you may expect, ##type## field is used to determine packet's type.
You can use any (8 bits) value greater or equal to ##RAYDIUM_NETWORK_PACKET_BASE##.
Finally, ##buff## is a pointer to data's buffer. This buffer
must be ##RAYDIUM_NETWORK_PACKET_SIZE## long, and can be cleared
or re-used after this call.
**/
__rayapi void raydium_network_broadcast (signed char type, char *buff);
/**
Sends data over network.
Obviously, from network point of vue, only a server can broadcast
(to his clients).
When a client needs to broadcast (from the game point of vue) some
informations (his own position, for example), he must send this information
to server, and the server will broadcast it.
This function uses the same arguments as previous one, except ##to## and
##from##, not needed here.
**/
__rayapi signed char raydium_network_read (int *id, signed char *type, char *buff);
/**
Reads next packet from network (FIFO) stack.
This function uses the same arguments as previous ones, and returns
data availability: ##RAYDIUM_NETWORK_DATA_OK##, ##RAYDIUM_NETWORK_DATA_NONE##
or ##RAYDIUM_NETWORK_DATA_ERROR##.
**/
__rayapi signed char raydium_network_read_flushed (int *id, signed char *type, char *buff);
/**
Reads last packet from network stack.
All previous packets will be ignored, only the newest packet will
be read (if any).
As you may miss some important informations, you can use netcalls
(see above) if you want to capture packets with a particular
type, even with flushed reading.
**/
__rayapi void raydium_network_read_faked(void);
/**
Reads from network, but do not care of received data. This is useful for
listen to internal packets (server "beacon" broadcasts, for example).
Reading is done thru ##raydium_network_read_flushed##.
Mostly for internal use.
**/
__rayapi signed char raydium_network_server_broadcast(char *name, char *app_or_mod, int version);
/**
This function will start to broadcast a server to the LAN.
You must provide a party ##name##, the application or mod name (##app_or_mod##)
and a "protocol" version of you choice.
The server is going to broadcast a "beacon" packet to the LAN
every ##RAYDIUM_NETWORK_BEACON_DELAY##.
Any client in "discovery mode" with the same ##app_or_mod## and ##version##
will see this beacon.
**/
__rayapi void raydium_network_server_broadcast_info(char *info);
/**
Update "information" field of this server (current track or map, for example).
Size cannot exceed ##RAYDIUM_NETWORK_BEACON_INFO_MAX_LEN##.
**/
__rayapi void raydium_network_server_broadcast_check(void);
/**
Internal use.
**/
__rayapi signed char raydium_network_server_create (void);
/**
Will transform you application into a server, accepting new clients
instantaneously.
See also the ##RAYDIUM_NETWORK_ONLY## directive if you want to create console
servers.
**/
__rayapi signed char raydium_network_client_connect_to (char *server);
/**
This function will try to connect your application to ##server## (hostname or
ip address).
WARNING: For now, this call could be endless ! (server failure while connecting).
This function will succed returning 1 or 0 otherwise.
You are connected instantaneously, and you must start sending data
before server timeout (defined by ##RAYDIUM_NETWORK_TIMEOUT##).
You player number can be found with ##raydium_network_uid## variable,
as said before.
**/
__rayapi signed char raydium_network_client_discover(char *game,int version);
/**
This function will set client in ##RAYDIUM_NETWORK_MODE_DISCOVER## mode.
While using this mode, a client will search every LAN server with the
same ##game## (or mod name) and ##version## as itself.
Then, you can access to this server list using [undocumented yet].
**/
__rayapi int raydium_network_discover_numservers(void);
/**
While the client is in ##RAYDIUM_NETWORK_MODE_DISCOVER## mode, you
can fetch all "detected" servers in the LAN.
This function will return :
- -1 : "not in discovery mode". See ##raydium_network_client_discover()##.
- 0 : no server detected (yet ... try during next frame)
- more : total number of compatible servers (same game/application
and protocol version)
**/
__rayapi signed char raydium_network_discover_getserver(int num, char *name, char *ip, char *info, int *player_count, int *player_max);
/**
Use this function with the help of ##raydium_network_discover_numservers()##,
with something like :
%%(c)
int i;
char name[RAYDIUM_MAX_NAME_LEN];
char ip[RAYDIUM_MAX_NAME_LEN];
char info[RAYDIUM_MAX_NAME_LEN];
int player_count;
int player_max;
...
for(i=0;i<raydium_network_discover_numservers();i++)
{
raydium_network_discover_getserver(i,name,ip,info,&player_count,&player_max);
raydium_log("server %02i: %s (%s)",i,name,ip);
}
No memory allocation is done for ##name## and ##ip##. It's your job.
This function will return :
- -1 : "not in discovery mode". See ##raydium_network_client_discover()##.
- 0 : invalid ##num##.
- 1 : OK.
%%
**/
__rayapi void raydium_network_client_disconnect(void);
/**
This function will disconnect client from server, if connected.
**/
__rayapi signed char raydium_server_accept_new (struct sockaddr *from, char *name);
/**
Internal server callback for new clients.
**/
__rayapi void raydium_network_close (void);
/**
Obvious. Raydium will do it for you, anyway.
**/
__rayapi void raydium_network_internal_server_delays_dump (void);
/**
Dumps "TCP Style" timeouts for all clients to console.
**/
__rayapi void raydium_network_internal_dump (void);
/**
Dumps various stats about network stack to console.
**/
__rayapi signed char raydium_network_internet_test(void);
/**
This function will test if direct internet connection is available,
using Raydium webiste. This function supports proxies.
**/
#ifdef linux
__rayapi signed char raydium_network_linux_find_broadcast_interfaces(void);
/**
Internal use. Linux only.
**/
#endif
#endif

47
raydium/headers/normal.h Normal file
View File

@ -0,0 +1,47 @@
#ifndef _NORMAL_H
#define _NORMAL_H
/*=
Normals
1600
**/
// Introduction
/**
This file provides some usefull functions for normal generation and smoothing.
You can find some more informations about normals at the top of this guide.
**/
__rayapi void raydium_normal_generate_lastest_triangle (int default_visu);
/**
Generate normal for the last created triangle (see ##raydium_vertex_index##)
if ##default_visu## is true ( != 0 ), this function will restore "visu"
normals too.
**/
__rayapi void raydium_normal_restore_all (void);
/**
This function restore visu normals with standard ones (##raydium_vertex_normal_*##)
**/
__rayapi void raydium_normal_regenerate_all (void);
/**
This function will regenerate standard and visu normals for the whole
scene (ground, objects, ...).
**/
__rayapi void raydium_normal_smooth_all (void);
/**
This function will smooth the whole scene, using adjacent vertices.
Note this function can take a lot of time.
**/
void raydium_normal_smooth_from_to(GLuint from, GLuint to);
/**
Same as above, but only from ##from## vertex to ##to## vertex (excluded).
In other words: will smooth [from;to[
**/
#endif

204
raydium/headers/object.h Normal file
View File

@ -0,0 +1,204 @@
#ifndef _OBJECT_H
#define _OBJECT_H
/*=
Objects
2300
**/
// Introduction
/**
With the following functions, you can easily draw and manage
mesh objects (.tri file).
**/
__rayapi GLint raydium_object_find (char *name);
/**
Lookups an object by its ##name##. This function will return -1 if the
object's not found, and will not try to load the .tri file.
**/
__rayapi signed char raydium_object_isvalid(int obj);
/**
Internal use, but you can call this function if you want to verify if an
object id is valid (in bounds).
**/
__rayapi GLint raydium_object_find_load (char *name);
/**
Same as above (##raydium_object_load##), but will try to load object.
**/
__rayapi void raydium_object_reset (GLuint o);
/**
Internal use. Do not call.
**/
__rayapi int raydium_object_load (char *filename);
/**
Load ##filename## as a .tri file, and returns corresponding id, or
-1 in case of error.
**/
__rayapi void raydium_object_draw (GLuint o);
/**
Draws ##o## (index) object, using current matrixes.
**/
__rayapi void raydium_object_draw_name (char *name);
/**
Same as above, but you only have to provide object's ##name## (".tri file").
If this object was not already loaded, this function will do it for you.
**/
__rayapi void raydium_object_deform (GLuint obj, GLfloat ampl);
/**
Early devel state. Useless as is.
**/
__rayapi void raydium_object_deform_name (char *name, GLfloat ampl);
/**
Early devel state. Useless as is.
**/
__rayapi GLfloat raydium_object_find_dist_max (GLuint obj);
/**
This function will return will return the distance form (0,0,0)
to the farest point of ##obj## object.
**/
__rayapi void raydium_object_find_axes_max (GLuint obj, GLfloat * tx, GLfloat * ty, GLfloat * tz);
/**
This function returns the (maximum) size of the bounding box
of ##obj## (relative to (0,0,0)).
**/
__rayapi void raydium_object_find_minmax(GLuint obj, GLfloat *min, GLfloat *max);
/**
Returns min and max values for ##obj##. No memory allocation is done, you must
provide two GLfloat[3] array.
**/
__rayapi void raydium_object_find_center_factors(GLuint obj, GLfloat *tx, GLfloat *ty, GLfloat *tz);
/**
Returns "centering" factors for ##obj##. A centered object will return (0,0,0).
**/
__rayapi void raydium_object_callback(void);
/**
Internal (frame callback).
**/
// Animations
/**
Raydium now supports mesh animation, thru MD2 (Quake 2) files. Raydium file
format was extended to version 2. If you want to create an animated mesh
for Raydium from a MD2 file, you may use Blender with "import-md2-0.14.py"
script ( by Bob Holcomb, http://67.22.114.230:8082/programming/blender/index.html )
and export it back to a tri file using provided "triEXP-MD2-*.py" script.
All other tasks (loading, transformations, ...) are done the same way as
regular static mesh.
For Raydium, an animation is a set of "anims", and each "anim" is a set
of "frames". Each "anim" gets its own name (see header of a version 2 file
for more informations), and since an animated object may be use for many
players, Raydium provides an "instances" based system: setting things like
anim and frame for an object is done only for one instance of this object.
Instances are always available, no need to create or declare them.
That's all you need to use animation simple API.
**/
__rayapi GLint raydium_object_anim_find(int object, char *name);
/**
Lookups an animation by its ##name##. This function will return -1 if the
animation's not found. Mostly for internal use.
**/
__rayapi void raydium_object_anim_generate_internal(int object, int instance);
/**
Internal. Transformed mesh generation.
**/
__rayapi void raydium_object_anim_frame(int object, int instance, GLfloat frame);
/**
Sets current ##frame## for one ##instance## of ##object##. ##frame## is
automatically bounded and looped.
Warning, change anim **before** anim's frame.
**/
__rayapi void raydium_object_anim_frame_name(char *object, int instance, GLfloat frame);
/**
Same as above, but using ##object##'s name.
**/
__rayapi void raydium_object_anim(int object, int instance, int anim);
/**
Sets current ##anim## for one ##instance## of ##object##.
Again, change anim **before** anim's frame.
**/
__rayapi void raydium_object_anim_name(char *object, int instance, char *anim);
/**
Same as above, but using ##object##'s name and ##anim##'s name.
**/
__rayapi void raydium_object_anim_instance(int object, int instance);
/**
With this function, you must set what instance will be drawn when
##raydium_object_draw()## will be called with ##object## argument.
Default is set to instance 0.
**/
__rayapi void raydium_object_anim_instance_name(char *object, int instance);
/**
Same as above, but using ##object##'s name.
**/
__rayapi void raydium_object_anim_automatic(int object, int anim, GLfloat factor);
/**
With this function, you can set an automatic frame increment for a specific
##anim## of an ##object##. This increment is based on frame time and ##factor##.
**/
__rayapi void raydium_object_anim_automatic_name(char *object, char *anim, GLfloat factor);
/**
Same as above, but using ##object##'s name and ##anim##'s name.
**/
// "Punctually" anims
/**
When using animations, you're switching for an "anim" to another, and an
"anim" will loop forever. "Punctually" support will allow you to set a
default "anim" for an object and to do switch punctually to another "anim",
and automatically return back to default value when this "anim" is finished,
usefull for animations like jumps, kick, ...
**/
__rayapi void raydium_object_anim_default(int object, int anim);
/**
This function will set default ##anim## for ##object##.
**/
__rayapi void raydium_object_anim_punctually(int object, int anim, int instance);
/**
This function will trigger a punctually ##anim## for ##object##'s ##instance##.
**/
__rayapi void raydium_object_anim_punctually_name(char *object, char *anim, int instance);
/**
Same as above, but with object's name.
**/
__rayapi signed char raydium_object_anim_ispunctually(int object, int instance);
/**
Will return true (1) if ##object## is currently running a punctually animation,
or false (0) otherwise.
**/
__rayapi signed char raydium_object_anim_ispunctually_name(char *object, int instance);
/**
Same as above, but with object's name.
**/
#endif

1560
raydium/headers/ode.h Normal file

File diff suppressed because it is too large Load Diff

182
raydium/headers/ode_net.h Normal file
View File

@ -0,0 +1,182 @@
#ifndef _ODE_NET_H
#define _ODE_NET_H
/*=
RayODE network layer
4000
**/
// Introduction
/**
Physics engines are extremely powerful tools, but it turns to nightmares when
the application must be networked. RayODE API provides its own network layer,
using Raydium lower level network API. And the great thing is that you've
almost anything to do !
Just choose the best "send" function and let Raydium do the rest.
RayODE Net will use udp streams, netcall (RPC), smart timeouts, predictions,
dead reckoning, and many others voodoo things. Just trust.
A few things about internals:
- NID: Network ID. Every networked element have a NID.
- Distant elements are localy created using static elements, owned by
an object called "##DISTANT##".
- ##raydium_ode_network_maxfreq## defines the paquet sending frequency. By
default, this value is ##RAYDIUM_ODE_NETWORK_MAXFREQ##, but you can use
##--ode-rate## command line switch.
- No rotation prediction is done.
- See ##config.h## if you want to disable prediction (##ODE_PREDICTION##) or
to debug RayODE Net (##DEBUG_ODENET##, **very** verbose !).
- Explosions are also automatically managed by RayODE Net.
- **Do NOT use** Raydium lower level network API when using RayODE Net. Use
netcalls, propags and so on.
Nothing is said here about how to create a RayODE Net server. There's only
a few more things to do if you already have a standard server, but since it's
unsupported for now, you must have a look to existing RayODE Net servers.
**/
__rayapi int raydium_ode_network_MaxElementsPerPacket (void);
/**
This function will return how many elements may be sent with
current packet size (see ##common.h##).
**/
__rayapi int raydium_network_nid_element_find (int nid);
/**
Internal. Find wich element have ##nid##.
**/
__rayapi void raydium_ode_network_newdel_event (int type, char *buff);
/**
Internal. NEWDEL netcall event.
NEWDEL is fired when a new element is created or deleted somewhere in the
network.
**/
__rayapi void raydium_ode_network_nidwho_event (int type, char *buff);
/**
Internal. NIDWHO netcall event.
NIDWHO is sent when someone received some "update" informations about a
nid, but didn't received previous NEWDEL informations for this nid.
The nid owner will send a reply.
Most reasons for this are:
- We are a new client and we dont known anything about the whole scene.
- The NEWDEL packet was lost ("TCP style" packets may be lost too ...)
NIDWHO answer will be used by every peer to refresh its own copy of the
element informations (geometry type, mesh, size and tag).
**/
__rayapi void raydium_ode_network_explosion_event (int type, char *buff);
/**
Internal explosion netcall event.(##RAYDIUM_ODE_NETWORK_EXPLOSION_EXPL## and
##RAYDIUM_ODE_NETWORK_EXPLOSION_BLOW##).
**/
__rayapi void raydium_ode_network_init (void);
/**
Internal. Will initialize all RayODE Net layer and register netcalls.
**/
__rayapi signed char raydium_ode_network_TimeToSend (void);
/**
Almost internal. Will return 1 (true) if it's time to send a new packet, using
##raydium_ode_network_maxfreq## value.
**/
__rayapi void raydium_ode_network_element_send (short nelems, int *e);
/**
Will send all elements of ##e## array to network. You must provide array lenght
using ##nelems##.
To "time to send ?" test is done, you'll probably have to do it yourself.
**/
__rayapi void raydium_ode_network_element_send_all (void);
/**
Will try to send all elements to network. Warning, packet size may be to
small to send all elements !..
**/
__rayapi void raydium_ode_network_element_send_random (int nelems);
/**
Will send randomly chosen elements to network. You must provide how many
elements you want with ##nelems##, but RAYDIUM_ODE_NETWORK_OPTIMAL is
available.
**/
__rayapi void raydium_ode_network_element_send_iterative (int nelems);
/**
Will send elements to network, iteratively chose. You must provide how many
elements you want with ##nelems##, but RAYDIUM_ODE_NETWORK_OPTIMAL is
available.
**/
__rayapi void raydium_ode_network_nidwho (int nid);
/**
Internal. Will ask for informations for ##nid## (see above).
NID sending frequency is now limited, since a lot of overhead was generated
when new clients were joining a "big" network.
**/
__rayapi void raydium_ode_network_apply (raydium_ode_network_Event * ev);
/**
Internal. This callback is fired when new data is received. A lot of things
are done here (timeouts, dead reckoning, ...)
**/
__rayapi void raydium_ode_network_read (void);
/**
Internal. Reads new packets, if any.
**/
__rayapi void raydium_ode_network_element_new (int e);
/**
Internal. Send a new element to network.
**/
__rayapi void raydium_ode_network_element_delete (int e);
/**
Internal. Send "delete event" to network, since we're deleting one of "our" elements.
**/
__rayapi void raydium_ode_network_explosion_send (raydium_ode_network_Explosion * exp);
/**
Internal. Send a new explosion event.
**/
__rayapi signed char raydium_ode_network_element_isdistant (int elem);
/**
Will return true (1) if element ##elem## is "distant", or false (0) if it's
one of "our" elements.
**/
__rayapi signed char raydium_ode_network_element_isdistant_name (char *elem);
/**
Same as above, but using element's name.
**/
__rayapi signed char raydium_ode_network_element_distantowner(int elem);
/**
Returns UID (peer "user" ID) for the distant element owner. See ##network.c##
documentation for more informations about UID.
**/
__rayapi signed char raydium_ode_network_element_distantowner_name(char *elem);
/**
Same as above, but using element's name.
**/
__rayapi void raydium_ode_network_element_trajectory_correct (int elem);
/**
Internal. Applies dead reckoning values to element.
**/
__rayapi void raydium_ode_network_elment_next_local(void);
/**
Call this function when you don't want that the next created element is sent
to network ("local only" element).
**/
#endif

228
raydium/headers/osd.h Normal file
View File

@ -0,0 +1,228 @@
#ifndef _OSD_H
#define _OSD_H
/*=
OSD (On Screen Display)
2900
**/
// Introduction
/**
Raydium provides some high level function for "On Screen Display",
as string drawing (2D and 3D), application's logo, mouse cursor, and other
various 2D displaying tools.
In most cases, these functions must be called after any other object
drawing function, to avoid overlapping problems.
Most functions will use a percentage system, and origin is at lower-left corner.
**/
__rayapi void raydium_osd_color_change (GLfloat r, GLfloat g, GLfloat b);
/**
This function will change the font color for the next ##raydium_osd_printf*##
calls.
As usual: 0 <= (##r##,##g## and ##b##) <= 1.
**/
__rayapi void raydium_osd_alpha_change (GLfloat a);
/**
Same as above, but will change font transparency.
**/
__rayapi void raydium_osd_color_rgba (GLfloat r, GLfloat g, GLfloat b, GLfloat a);
/**
This is a mix of ##raydium_osd_color_change## and ##raydium_osd_alpha_change##.
**/
__rayapi void raydium_osd_color_ega (char hexa);
/**
This function will change font color with the corresponding
##hexa##decimal code (as a char: '0' to 'F') in the standard EGA palette.
Here is this palette:
""
<div class="table" align="center">
<table class="tableListing" summary=" " cellspacing="0" cellpadding="3" border="1">
<tr class="wiki"><td class="wiki"> <b>Hexa</b> </td><td class="wiki"> <b>Color</b> </td></tr>
<tr class="wiki"><td class="wiki"> 0 </td><td class="wiki"> Black </td></tr>
<tr class="wiki"><td class="wiki"> 1 </td><td class="wiki"> Blue </td></tr>
<tr class="wiki"><td class="wiki"> 2 </td><td class="wiki"> Green </td></tr>
<tr class="wiki"><td class="wiki"> 3 </td><td class="wiki"> Cyan </td></tr>
<tr class="wiki"><td class="wiki"> 4 </td><td class="wiki"> Red </td></tr>
<tr class="wiki"><td class="wiki"> 5 </td><td class="wiki"> Purple </td></tr>
<tr class="wiki"><td class="wiki"> 6 </td><td class="wiki"> Brown </td></tr>
<tr class="wiki"><td class="wiki"> 7 </td><td class="wiki"> White </td></tr>
<tr class="wiki"><td class="wiki"> 8 </td><td class="wiki"> Grey </td></tr>
<tr class="wiki"><td class="wiki"> 9 </td><td class="wiki"> Light Blue </td></tr>
<tr class="wiki"><td class="wiki"> A </td><td class="wiki"> Light Green </td></tr>
<tr class="wiki"><td class="wiki"> B </td><td class="wiki"> Light Cyan </td></tr>
<tr class="wiki"><td class="wiki"> C </td><td class="wiki"> Light Red </td></tr>
<tr class="wiki"><td class="wiki"> D </td><td class="wiki"> Light Purple </td></tr>
<tr class="wiki"><td class="wiki"> E </td><td class="wiki"> Light Yellow </td></tr>
<tr class="wiki"><td class="wiki"> F </td><td class="wiki"> Light White </td></tr>
</table>
</div>
""
**/
__rayapi void raydium_osd_start (void);
/**
Mostly for internal uses. (will configure screen for OSD operations)
**/
__rayapi void raydium_osd_stop (void);
/**
Mostly for internal uses. (see above)
**/
__rayapi void raydium_osd_draw (int tex, GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2);
/**
Will draw ##tex## texture using (##x1##,##y1##) and (##x2##,##y2##) points.
**/
__rayapi void raydium_osd_draw_name (char *tex, GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2);
/**
Same as above, but using texture filename.
**/
__rayapi void raydium_osd_printf (GLfloat x, GLfloat y, GLfloat size, GLfloat spacer, char *texture, char *format, ...);
/**
This function is an OpenGL equivalent to the standard "printf" C function.
- (##x##,##y##) is the position of the text's beginning, as a screen
percentage, with origin at lower left.
- ##size## is the font size, using an arbitrary unit. This size is always
proportionnal to frame size (font size will grow up with screen size,
in other words).
- ##spacer## is the factor of spacing between 2 consecutive letters. With
standard fonts, 0.5 is a correct value (relatively condensed text).
- ##texture## is obviously the texture filename to use (font*.tga are
often provided with Raydium distribution, and by R3S).
- ##format## is the standard printf format string, followed by
corresponding arguments: ##"^9Player ^Fname is: %10s", player_name##
This format can use '^' char to change color text, followed by a color,
indicated by a hexadecimal letter (EGA palette). See ##raydium_osd_color_ega##
function, above.
Here you are a simple example:
%%(c)
strcpy(version,"^Ctest 0.1^F");
raydium_osd_printf(2,98,16,0.5,"font2.tga","- %3i FPS - tech demo %s for Raydium %s, CQFD Corp.",
raydium_render_fps,version,raydium_version);
%%
**/
__rayapi void raydium_osd_printf_3D (GLfloat x, GLfloat y, GLfloat z, GLfloat size, GLfloat spacer, char *texture, char *format, ...);
/**
Same as above, but you can place your text in your application 3D space,
using ##x##, ##y## and ##z## values.
**/
__rayapi void raydium_osd_logo (char *texture);
/**
Will draw a logo for the current frame with texture filename.
For now, you've no control over rotation speed of the logo.
**/
__rayapi void raydium_osd_cursor_set (char *texture, GLfloat xsize, GLfloat ysize);
/**
This function will set mouse cursor with texture filename and
with (##xsize##,##ysize##) size (percent of screen size).
You should use a RGB**A** texture for better results.
example:
%%(c)
raydium_osd_cursor_set("BOXcursor.tga",4,4);
%%
You can set ##texture## to NULL or empty string to cancel OSD cursor texture.
**/
__rayapi void raydium_osd_cursor_draw (void);
/**
Internal use.
**/
__rayapi void raydium_osd_internal_vertex (GLfloat x, GLfloat y, GLfloat top);
/**
Internal use.
**/
__rayapi void raydium_osd_network_stat_draw (GLfloat px, GLfloat py, GLfloat size);
/**
Will draw network stats (if available) in a box.
%%(c) raydium_osd_network_stat_draw(5,30,20); %%
**/
__rayapi void raydium_osd_mask (GLfloat * color4);
/**
Will draw a uniform mask using ##color4## (RGBA color) for this frame.
**/
__rayapi void raydium_osd_mask_texture(int texture,GLfloat alpha);
/**
Will draw a textured mask, with ##alpha## opacity (1 is full opacity).
**/
__rayapi void raydium_osd_mask_texture_name(char *texture,GLfloat alpha);
/**
Same as above, but resolving texture by name.
**/
__rayapi void raydium_osd_mask_texture_clip(int texture,GLfloat alpha, GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2);
/**
Same as ##raydium_osd_mask_texture##, but (x1,y1),(x2,y2) will be used as
texture coords, in a [0,100] range.
**/
__rayapi void raydium_osd_mask_texture_clip_name(char *texture,GLfloat alpha, GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2);
/**
Same as above, but resolving texture by name.
**/
__rayapi void raydium_osd_fade_callback (void);
/**
Internal use.
**/
__rayapi void raydium_osd_fade_init (void);
/**
Internal use.
**/
__rayapi void raydium_osd_fade_from (GLfloat * from4, GLfloat * to4, GLfloat time_len, void *OnFadeEnd);
/**
This function will configure a fading mask from ##from4## color to ##to4##.
This fade will last ##time_len## seconds, and will call ##OnFadeEnd## callback
when finished.
This callback signature must be ##void callback(void)##.
A standard fade-to-black-and-restore example:
%%(c)
// back to normal rendering
void restorefade(void)
{
GLfloat from[4]={0,0,0,2};
GLfloat to[4]={0,0,0,0};
raydium_osd_fade_from(from,to,1,NULL);
// do things (like moving camera to another place, for example).
}
...
// If space key : fade to black
if(raydium_key_last==1032)
{
GLfloat from[4]={0,0,0,0};
GLfloat to[4]={0,0,0,1};
raydium_osd_fade_from(from,to,0.3,restorefade);
}
%%
**/
#endif

113
raydium/headers/parser.h Normal file
View File

@ -0,0 +1,113 @@
#ifndef _PARSER_H
#define _PARSER_H
/*=
Text file parsing
3700
**/
// Introduction
/**
Raydium provides a set of functions dedicated to text files parsing. These
files must follow a simple syntax:
%%(c)
// strings
variable_s="string value";
// float (or integer, i.e.)
variable_f=10.5;
// float array
variable_a={1,2,10.5,};
// raw data
variable_r=[
xxxxxxxx
# oo #
# #
# oo #
xxxxxxxx
];
%%
Semi-colon are purely esthetic.
**/
__rayapi void raydium_parser_trim (char *org);
/**
Strip whitespace (or other characters) from the beginning and end of a string.
So far, ' ', '\n' and ';' are deleted.
**/
__rayapi signed char raydium_parser_isdata (char *str);
/**
Returns true (1) if ##str## contains data, false (0) otherwise (comments and
blank lines).
**/
__rayapi signed char raydium_parser_cut (char *str, char *part1, char *part2, char separator);
/**
This function will cut ##str## in two parts (##part1## and ##part2##) on
##separator##. No memory allocation will be done by this functions.
First occurence of ##separator## is used (left cut).
Return true (##i##+1) if ##str## was cut, where ##i## is the separator position.
**/
__rayapi void raydium_parser_replace (char *str, char what, char with);
/**
Will replace all occurence of ##what## with ##with##.
**/
__rayapi int raydium_parser_read (char *var, char *val_s, GLfloat *val_f, int *size, FILE *fp);
/**
Reads a new data line in ##fp##.
##var## will contain variable name. You'll find associated value in ##val_s##
if it's a string, or ##val_f## if it's a float (or a float array). In this last
case, ##size## will return the number of elements if the array.
%%(c)
FILE *fp;
int ret;
char var[RAYDIUM_MAX_NAME_LEN];
char val_s[RAYDIUM_MAX_NAME_LEN];
GLfloat val_f[MY_ARRAY_SIZE];
int size;
fp=raydium_file_fopen("foobar.txt","rt");
while( (ret=raydium_parser_read(var,val_s,val_f,&size,fp))!=RAYDIUM_PARSER_TYPE_EOF)
{
if(!strcasecmp(var,"foobar_variable"))
{
if(ret!=RAYDIUM_PARSER_TYPE_FLOAT || size!=2)
{
raydium_log("error: foobar_variable is not float array");
continue;
}
memcpy(...);
}
...
}
%%
**/
__rayapi signed char raydium_parser_db_get(char *key, char *value, char *def);
/**
This function will copy the value of ##key## from Raydium's database to
##value##. If ##key## is not found, ##def## is used as a default value.
If you do not want to use a default value, give ##NULL## to ##def##,
and the function will return 0 when ##key## was not found.
No memory allocation is done for you.
**/
__rayapi signed char raydium_parser_db_set(char *key, char *value);
/**
Sets ##key## in the Raydium's database to ##value##.
This function will return 0 if failed.
**/
#endif

190
raydium/headers/particle2.h Normal file
View File

@ -0,0 +1,190 @@
#ifndef _PARTICLE__H
#define _PARTICLE__H
#include "../particle2.h"
/*=
Particle engine
1400
**/
// Introduction
/**
This is the second version of Raydium's particle engine. This engine is build
on top of a dedicated file format (.prt and .sprt files), describing most
(up to all, in facts) properties of generators.
It probably better to start by an example (fountain.prt) :
%%(c)
// Simple blue fountain (change 'vector' if needed)
ttl_generator=5;
ttl_particles=1.5;
ttl_particles_random=0;
particles_per_second=200;
texture="flare_nb.tga";
size=0.1;
size_inc_per_sec=0.1;
gravity={0,0,-5};
vector={0,0,4};
vector_random={0.2,0.2,0.2};
// RGBA
color_start={0.6,0.6,1,0.5};
color_start_random={0,0,0.2,0};
color_end={1,1,1,0.1};
// end of file.
%%
.prt files are readed using parsing functions (see appropriate chapter, if
needed), and the list of all available properties can be found in particle2.c
source file. A full toturial is also available on Raydium's Wiki.
Once the particle file is written, you only need to load the file using the
suitable function (see below). Some anchor are available to link generators to
physic entities, if needed, as callbacks for a few events (one, for now).
.sprt files are used to create a "snapshot" of particles, used for example by
3D captures, and are not meant to be edited by hand.
**/
__rayapi void raydium_particle_name_auto (char *prefix, char *dest);
/**
Will generate a unique string using ##prefix##. The string is created using
space provided by ##dest##.
You can use this function when building a new generator.
**/
__rayapi void raydium_particle_init (void);
/**
Internal use.
**/
__rayapi signed char raydium_particle_generator_isvalid (int g);
/**
Internal use, but you can call this function if you want to verify if a
generator's id is valid (in bounds, and loaded).
**/
__rayapi int raydium_particle_generator_find (char *name);
/**
Lookups a generator using is name. Returns -1 if ##name## is not found.
**/
__rayapi int raydium_particle_find_free (void);
/**
Finds a free **particle** slot.
**/
__rayapi void raydium_particle_generator_delete (int gen);
/**
Deletes a generator.
**/
__rayapi void raydium_particle_generator_delete_name (char *gen);
/**
Same as above, but using generator's name.
**/
__rayapi void raydium_particle_generator_enable (int gen, signed char enabled);
/**
Activate a disabled generator (see below).
**/
__rayapi void raydium_particle_generator_enable_name (char *gen, signed char enable);
/**
Disable a generator (TTL is still decremented).
**/
__rayapi void raydium_particle_preload (char *filename);
/**
Loads .prt file and associated textures into suitable caches.
Call this function if you want to avoid (small) jerks caused by "live"
loading a generator.
**/
__rayapi void raydium_particle_generator_load_internal (int generator, FILE * fp, char *filename);
/**
Internal use.
**/
__rayapi int raydium_particle_generator_load (char *filename, char *name);
/**
Loads generator from ##filename## as ##name##. This ##name## will be used for
future references to this generator, as the returned interger id.
**/
__rayapi void raydium_particle_generator_update (int g, GLfloat step);
/**
Internal use.
**/
__rayapi void raydium_particle_update (int part, GLfloat step);
/**
Internal use.
**/
__rayapi void raydium_particle_callback (void);
/**
Internal use.
**/
__rayapi int raydium_particle_state_dump(char *filename);
/**
Dumped current particles to ##filename## (.sprt [static particles]).
**/
__rayapi int raydium_particle_state_restore(char *filename);
/**
Append .sprt ##filename## to current scene.
**/
__rayapi void raydium_particle_draw (raydium_particle_Particle * p, GLfloat ux, GLfloat uy, GLfloat uz, GLfloat rx, GLfloat ry, GLfloat rz);
/**
Internal use.
**/
__rayapi void raydium_particle_draw_all (void);
/**
Internal use.
**/
__rayapi void raydium_particle_generator_move (int gen, GLfloat * pos);
/**
Moves ##gen## generator to ##pos## position (3 * GLfloat array).
**/
__rayapi void raydium_particle_generator_move_name (char *gen, GLfloat * pos);
/**
Same as above, but using generator's name.
**/
__rayapi void raydium_particle_generator_move_name_3f (char *gen, GLfloat x, GLfloat y, GLfloat z);
/**
Same as above, using 3 different GLfloat values.
**/
__rayapi void raydium_particle_generator_particles_OnDelete (int gen, void *OnDelete);
/**
Sets a callback for ##gen##, fired when any particle of this generator is
deleted, providing a easy way to create "cascading" generators.
The callback must respect the following prototype:
%%(c) void cb(raydium_particle_Particle *) %%
Do not free the provided particle.
**/
__rayapi void raydium_particle_generator_particles_OnDelete_name (char *gen, void *OnDelete);
/**
Same as above, but using generator's name.
**/
__rayapi void raydium_particle_scale_all(GLfloat scale);
/**
Will scale all particles with ##scale## factor. Use with caution.
Default is obviously 1.
**/
#endif

26
raydium/headers/path.h Normal file
View File

@ -0,0 +1,26 @@
#ifndef _PATH__H
#define _PATH__H
#include "../path.h"
/*=
File path
2110
**/
// Introduction
/**
No doc yet.
**/
__rayapi int raydium_path_find_free(void);
__rayapi signed char raydium_path_ext(char *dir, char *ext);
__rayapi signed char raydium_path_add(char *dir);
__rayapi signed char raydium_path_write(char *dir);
__rayapi signed char raydium_path_string_from(char *str);
__rayapi int raydium_path_string_to(char *out);
__rayapi void raydium_path_resolv(char *in, char *out, char mode);
__rayapi void raydium_path_dump(void);
__rayapi void raydium_path_reset(void);
__rayapi void raydium_path_init(void);
#endif

37
raydium/headers/php.h Normal file
View File

@ -0,0 +1,37 @@
//!NOBINDINGS
#ifndef _PHP_H
#define _PHP_H
/*=
PHP scripting engine
5000
**/
// Introduction
/**
This is the internal part of the RayPHP API, where Raydium
deals with Zend engine.
All this is for internal use, so no documentation is provided.
**/
#include "../php_wrappers.c"
// use this macro when registering your functions
#define C2PHP ZEND_FN
// Dirty globals... (needed for WIN32 PHP support)
#ifdef ZTS
extern zend_compiler_globals *compiler_globals;
extern zend_executor_globals *executor_globals;
extern php_core_globals *core_globals;
extern sapi_globals_struct *sapi_globals;
extern void ***tsrm_ls;
#endif
__rayapi void raydium_php_error (int type, const char *msg, ...);
__rayapi int raydium_php_uwrite (const char *str, uint str_length TSRMLS_DC);
__rayapi void raydium_php_init_request (char *filename);
__rayapi int raydium_php_exec (char *name);
__rayapi void raydium_php_close (void);
__rayapi void raydium_php_init (void);
#endif

29
raydium/headers/profile.h Normal file
View File

@ -0,0 +1,29 @@
#ifndef _PROFILE_H
#define _PROFILE_H
#ifdef DEBUG_PROFILE
/*=
Profiling (sort of ...)
3500
**/
// Introduction
/**
You will find here a few functions for a **very simple** profiling.
For anything else than a quick time measure, use real profiling tools.
Note: Use only one "profiler" at a time.
**/
__rayapi unsigned long raydium_profile_timer;
__rayapi void raydium_profile_start(void);
/**
Starts measure.
**/
__rayapi void raydium_profile_end(char *tag);
/**
Stops measure and displays result using ##tag## string.
**/
#endif
#endif

52
raydium/headers/random.h Normal file
View File

@ -0,0 +1,52 @@
#ifndef _RANDOM_H
#define _RANDOM_H
/*=
Random
400
**/
// Introduction
/**
These functions deals with random numbers generation.
**/
__rayapi void raydium_random_randomize (void);
/**
This function initialize the random number generator
with current time for seed.
**Note: ** You are not supposed to use this function.
**/
__rayapi GLfloat raydium_random_pos_1 (void);
/**
"positive, to one": 0 <= res <= 1
**/
__rayapi GLfloat raydium_random_neg_pos_1 (void);
/**
"negative and positive, one as absolute limit": -1 <= res <= 1
**/
__rayapi GLfloat raydium_random_0_x (GLfloat i);
/**
"zero to x": 0 <= res <= x
**/
__rayapi GLfloat raydium_random_f (GLfloat min, GLfloat max);
/**
min <= res <= max (float)
**/
__rayapi int raydium_random_i (int min, int max);
/**
min <= res <= max (integer)
**/
__rayapi signed char raydium_random_proba (GLfloat proba);
/**
Returns true or false (0 or 1) depending of "proba" factor.
##proba## must be: 0 <= proba <=1
ex: 50% = 0.5
**/
#endif

292
raydium/headers/raydoc.php Normal file
View File

@ -0,0 +1,292 @@
#!/usr/bin/php
<?
/*
Raydium - CQFD Corp.
http://raydium.org/
License: GPL - GNU General Public License, see "gpl.txt" file.
*/
// This script generates a Wiki(ni) style documentation from comments of
// all header files of Raydium (raydium/header/*.h)
$page="http://wiki.raydium.org/wiki/RaydiumApiReference";
$intro="
======Raydium API Reference======
=====CQFD Corp.=====
This document is the most up-to-date version. **This is a work in progress**:
there's again some errors and wrong informations. Try, wait, or contribute ;)
\"\"<a href=$page#chapters>Index of chapters</a>\"\"
\"\"<a href=$page#index>Index of all Raydium functions</a>\"\"
----
This document is autogenerated, any change will be lost,
use RaydiumApiReferenceComments for any need.
{DATE}, for Raydium **{VERSION}**
----
";
function getTagLine($tag,$lines,$from=0)
{
for($i=$from;$i<count($lines);$i++)
{
$l=$lines[$i];
if(substr(trim($l),0,strlen($tag))==$tag)
return $i;
}
return -1;
}
function getVersion()
{
$file="../common.h";
$f=file($file);
$maj=getTagLine("#define RAYDIUM_MAJOR",$f);
$min=getTagLine("#define RAYDIUM_MINOR",$f);
$maj=str_replace("\t"," ",trim($f[$maj]));
$min=str_replace("\t"," ",trim($f[$min]));
$maj=explode(" ",$maj);
$min=explode(" ",$min);
$maj=$maj[count($maj)-1];
$min=$min[count($min)-1];
return sprintf("%d.%03d",$maj,$min);
}
function getMain($filename,$offset)
{
$f=file($filename);
$l=getTagLine("/*=",$f);
if($l==-1)
return -1;
$res=trim($f[$l+$offset]);
return $res;
}
function getPriority($filename)
{
$res=trim(getMain($filename,2));
if(is_numeric($res))
return $res;
else
return -1;
}
function getTitle($filename)
{
return trim(getMain($filename,1));
}
function getHeaders($directory)
{
$res=array();
if (is_dir($directory))
{
if ($dh = opendir($directory))
{
while (($file = readdir($dh)) !== false)
{
if(substr($file,-2)==".h")
{
$res[]=$file;
}
}
closedir($dh);
}
}
else echo "'$directory' is not a directory";
return $res;
}
$chapters=array();
function h1($str,$addchap=true)
{
global $chapters;
static $i=1;
if($addchap)
{
echo '""'."<a name=chap$i></a>".'""';
$chapters[$i]=$str;
$i++;
}
echo "\n=====$str:=====\n";
}
function h2($str)
{
echo "====$str:====\n";
}
function body($str)
{
echo $str."\n\n";
}
function intro($str)
{
$str=str_replace("{DATE}","Generated: ".date("Y-m-d H:i:s"),$str);
$str=str_replace("{VERSION}",getVersion(),$str);
echo $str;
}
$index=array();
function addToIndex($f)
{
static $i=0;
global $index;
$p=strpos($f,"raydium_");
if($p!==false)
$f=substr($f,$p);
else
$f="unsupported - $f";
$index[$i]=$f."|$i";
return $i++;
}
// Main
$id="";
$files=getHeaders(".");
//var_dump($files);
if($files==-1)
die("No header found");
unset($sorted);
for($i=0;$i<count($files);$i++)
{
$file=$files[$i];
$p=getPriority($file);
if($p==-1)
$p=999000+$i;
while(isset($sorted[$p]))
$p++;
$sorted[$p]=$file;
}
ksort($sorted);
$sorted=array_values($sorted);
//var_dump($sorted);
// Files are sorted, now
intro($intro);
for($i=0;$i<count($sorted);$i++)
{
$file=$sorted[$i];
$title=getTitle($file);
if($title==-1)
{
h1(($i+1)." no documentation for $file");
continue;
}
h1(($i+1)." $title");
$f=file($file);
$last=0;
$n=0;
while(($l=getTagLine("/**",$f,$last))!=-1)
{
$title=trim($f[$l-1]);
if($title=="")
$title="// unknown item";
// types:
// 1 - Comment (//)
// 2 - Macro (#)
// 3 - Code (...)
$type=3;
if($title[0]=="/")
{
$type=1;
$title=trim(substr($title,2));
}
if($title[0]=="#")
{
$type=2;
$pos=strpos($title,")");
if($pos)
{
$title=substr($title,0,$pos+1);
}
$title=trim(str_replace("#define ","",$title))." (macro)";
}
if($type==3)
{
if(substr($title,0,7)=="extern ")
$title=trim(substr($title,7));
if(substr($title,0,9)=="__rayapi ")
$title=trim(substr($title,9));
if($title[strlen($title)-1]==";")
$title=substr($title,0,-1);
$title=trim(str_replace("**","* *",$title));
}
if($type==2 || $type==3)
$id=addToIndex($title);
h2('""'."<a name=$id></a>".'""'.($i+1).".".($n+1)." $title");
$last=$l+1;
$end=getTagLine("**/",$f,$last);
if($end==-1)
die("expected '**/' (started line $l)");
unset($body);
/* for($j=$l+1;$j<$end;$j++)
{
$lj=trim($f[$j]);
if($lj=="")
$lj="\n\n";
else
$lj.=" ";
$body[]=$lj;
}
$str=implode("",$body);*/
for($j=$l+1;$j<$end;$j++)
{
$lj=trim($f[$j]);
$body[]=$lj;
}
$str=@implode("\n",$body);
body($str);
$last=$end+1;
$n++;
}
}
h1('""<a name=chapters></a>""Chapters',false);
foreach($chapters as $key => $val)
{
echo('====""'."<a href=$page#chap$key>$val</a>".'""====')."\n";
}
sort($index);
h1('""<a name=index></a>""Index');
for($i=0;$i<count($index);$i++)
{
$j=explode("|",$index[$i]);
$k=$j[0];
$l=$j[1];
echo '""'."<a href=$page#$l><tt>$k</tt></a>".'""'."\n";
}

64
raydium/headers/rayphp.h Normal file
View File

@ -0,0 +1,64 @@
//!NOBINDINGS
#ifndef _RAYPHP_H
#define _RAYPHP_H
/*=
RayPHP (internals)
3600
**/
// Introduction
/**
Raydium also use RayPHP (Raydium/PHP interface) for its own needs.
For PHP part of these functions, see "rayphp/" directory.
So far, RayPHP is dedicated to R3S (Raydium Server Side Scripts) access.
All this is mostly usefull for internal uses, since Raydium provides ##fopen##
wrappers, thru ##raydium_file_fopen##.
R3S is able to work with HTTP and FTP, and supports proxy using ##raydium.db##
configuration database. Example : %%Generic-Proxy;http://proxy:3128/%%
The trailing ##/## (slash) must be present.
**/
__rayapi void raydium_php_rayphp_path_change(char *path);
/**
By default, Raydium search for a "rayphp/" subdirectory in the application
directory. It's possible to change this using a --rayphp command line
switch, or using this function. You must call the function as soon as possible,
before any use of RayPHP.
**/
__rayapi int raydium_rayphp_repository_file_get (char *path);
/**
Will contact R3S servers for downloading ##path## file.
**/
__rayapi int raydium_rayphp_repository_file_put (char *path, int depends);
/**
Will contact R3S servers for uploading ##path## file. Set ##depends## to
true (1) if you also want to upload dependencies, false (0) otherwise.
**/
__rayapi int raydium_rayphp_repository_file_list(char *filter);
/**
Will contact R3S servers to get file list, using ##filter## (shell-like
syntax). Default ##filter## is ##*##.
**/
__rayapi signed char raydium_rayphp_http_test(void);
/**
Test if Internet connection is available using Raydium website.
(0 means 'not available', 1 means 'OK')
**/
__rayapi signed char raydium_rayphp_repository_defaults(char *def);
/**
Gives the default repositories for this applications
This function will create two files, ##repositories.list## and
##repositories.upload## in game user home directory, if these files
don't alreay exist, and will fill the files with ##def##.
This argument is an URL, or a list of URLs (use \n separator). See R3S doc.
**/
#endif

21
raydium/headers/reg_api.h Normal file
View File

@ -0,0 +1,21 @@
#ifndef _REGAPI_H
#define _REGAPI_H
/*=
RegAPI
4100
**/
// Introduction
/**
RegAPI is an internal system that exports some Raydium's API functions to
scripting engine, creating bindings.
See RayPHP chapter for more informations anout scripting.
**/
__rayapi void raydium_register_api(void);
/**
Internal. Will register Raydium API.
**/
#endif

View File

@ -0,0 +1,73 @@
#ifndef _REGISTER_H
#define _REGISTER_H
/*=
Data registration
3400
**/
// Introduction
/**
Raydium supports scripting, for example using PHP in the current implementation.
All ##raydium_register_*## functions are provided as a "bridge" between
your applications and PHP scripts, allowing you to "export" native variables
and functions to PHP scripts.
For more informations, see PHP chapters.
**/
__rayapi int raydium_register_find_name (char *name);
/**
Lookups a **variable** by ##name##. Search is not possible (yet) for
registered functions.
Mostly used internally.
**/
__rayapi signed char raydium_register_name_isvalid (char *name);
/**
Tests ##name##, and returns his viability as a boolean.
Accepted intervals for variables and functions: [a-z], [A-Z] and '_'
Numerics are not allowed.
**/
__rayapi int raydium_register_variable (void *addr, int type, char *name);
/**
Will register a new variable. You must provide variable's address (##addr##),
##type## and ##name##.
Current available types are: ##RAYDIUM_REGISTER_INT##, ##RAYDIUM_REGISTER_FLOAT##,
and ##RAYDIUM_REGISTER_STR##.
**/
__rayapi int raydium_register_variable_const_f(float val, char *name);
/**
Will register a new ##float## constant.
**/
__rayapi int raydium_register_variable_const_i(int val, char *name);
/**
Will register a new ##int## constant.
**/
__rayapi void raydium_register_variable_unregister_last (void);
/**
Variable are registered on a stack. As you may want to create "temporary"
variables (usefull for building script's arguments, for example), this function
allows you to unregister last registered variable. Multiple calls are possible.
**/
__rayapi int raydium_register_modifiy (char *var, char *args);
/**
Deprecated.
**/
__rayapi void raydium_register_function (void *addr, char *name);
/**
Will register a function. You only need to provide an address (##addr##)
and a name.
**/
__rayapi void raydium_register_dump (void);
/**
Will dump to console all registered variables and functions.
**/
#endif

108
raydium/headers/render.h Normal file
View File

@ -0,0 +1,108 @@
#ifndef _RENDER_H
#define _RENDER_H
/*=
Rendering
1300
**/
// Introduction
/*=
render.c contains Raydium rendering core, so only "public" and
interesting function will be documented.
It' obvious for me that many parts of this code have to be
rewritten (tips: slow, buggy, old, ... :)
**/
__rayapi void raydium_render_lightmap_color(GLfloat *color);
/**
You may force a new lightmap rendering color "filter" anytime with this
function, allowing advanced lighting effects.
HUGE WARNING: You must turn off display lists if you change this value after
first object's render.
See ##raydium_rendering_displaylists_disable()## if needed.
**/
__rayapi void raydium_render_lightmap_color_4f(GLfloat r, GLfloat g, GLfloat b, GLfloat a);
/**
Same as above, using 4 values.
**/
__rayapi int raydium_rendering_prepare_texture_unit (GLenum tu, GLuint tex);
/**
This function will "prepare" hardawre texture unit ##tu## to render ##tex## texture.
There almost no reason to call this function by yourself.
**/
__rayapi void raydium_rendering_internal_prepare_texture_render (GLuint tex);
/**
Same as above, but for texture unit #0 only.
**/
__rayapi void raydium_rendering_internal_restore_render_state (void);
/**
Internal. Deprecated.
**/
// DO NOT DOCUMENT THIS ... THING !
__rayapi char infov (GLfloat x, GLfloat y);
__rayapi void raydium_rendering_from_to_simple(GLuint from, GLuint to);
/**
Same as ##raydium_rendering_from_to()##, but only with vertices (no
UV, no normals, no textures, no colors, ...).
Mostly used for internal shadow maps creation.
**/
__rayapi void raydium_rendering_from_to (GLuint from, GLuint to);
/**
Renders vertices from ##from## to ##to##.
Using object management functions is a better idea.
**/
__rayapi void raydium_rendering (void);
/**
Renders all vertices (probably useless, now).
**/
__rayapi void raydium_rendering_finish (void);
/**
You must call this function at the end of each frame. This will flush all
commands to hardware, fire a lot off callbacks, and prepare next frame.
**/
__rayapi void raydium_rendering_wireframe (void);
/**
Switch to wireframe rendering.
**/
__rayapi void raydium_rendering_normal (void);
/**
Switch back to standard rendering.
**/
__rayapi void raydium_rendering_rgb_force (GLfloat r, GLfloat g, GLfloat b);
/**
Force all RGB colored vertices to take ##(r,g,b)## color. One example of this
use is for making "team colored" cars : Do not apply textures to some faces
while modelling, and force to team color each time you render a car.
**/
__rayapi void raydium_rendering_rgb_normal (void);
/**
Disable "rgb force" state. See above.
**/
__rayapi void raydium_rendering_displaylists_disable(void);
/**
Disable display lists usage.
Some old video cards and broken drivers may get better performances WITHOUT
display lists (on large objects, mainly).
**/
__rayapi void raydium_rendering_displaylists_enable(void);
/**
Enable display lists usage. default state.
**/
#endif

159
raydium/headers/shader.h Normal file
View File

@ -0,0 +1,159 @@
#ifndef _SHADER__H
#define _SHADER__H
#include "../shader.h"
/*=
Shaders
4500
**/
// Introduction
/**
Raydium provides a support for OpenGL Shading Language (GLSL).
This documentation talks only about Raydium Shader API, and not about
the Shading Language itself. With Raydium, shaders works by two: you must
provide a vertex shader and a fragment shader each time. This is a very
usual way to do.
You must know that **only one** shader can be active at a time.
Once a shader is loaded, Raydium API allows you to attach this shader to
a texture, so you don't have to deal manually with activation/deactivation.
You can also change all "uniform" variables from shaders
using ##raydium_shader_var_...()## functions.
Into this set, all functions that does **not** contain the **_name**
suffix **are only able to deal with current shader !**.
You can use the global variable ##raydium_shader_support## to detect if
current hardware supports GLSL or not (1=OK 0=no shader support).
**/
__rayapi void raydium_shader_init(void);
/**
Internal use. Init all shader subsystem.
**/
__rayapi signed char raydium_shader_isvalid(int shader);
/**
Internal use. Returns true (1) if ##shader## slot is in bounds and filled.
**/
__rayapi int raydium_shader_find(char *name);
/**
Returns shader's ID using its ##name##.
**/
__rayapi void raydium_shader_infolog(GLhandleARB shader);
/**
Internal use.
Reports full driver error message when shader compilation or linking fails.
**/
__rayapi int raydium_shader_load(char *name, char *file_vert, char *file_frag);
/**
Loads the vertex shader ##file_vert## and the fragment shader ##file_frag##.
The shader is stored with the provided ##name##. This function returns the
shader ID or -1 in case of failure.
**/
__rayapi int raydium_shader_variable(int shader, char *name);
/**
Returns an ID for the variable "##name## of the provided ##shader##.
**/
__rayapi signed char raydium_shader_var_i(int var_id, int value);
/**
This function will change the ##value## of the variable ##var_id## of
the current shader.
Value is an integer.
**/
__rayapi signed char raydium_shader_var_i_name(char *shader, char *variable, int value);
/**
Same as above, but using shader's name and variable's name. This function is
able to change the ##variable##'s ##value## even is the ##shader## is not
the current one.
**/
__rayapi signed char raydium_shader_var_f(int var_id, float value);
/**
This function will change the ##value## of the variable ##var_id## of
the current shader.
Value is a float.
**/
__rayapi signed char raydium_shader_var_f_name(char *shader, char *variable, float value);
/**
Same as above, but using shader's name and variable's name. This function is
able to change the ##variable##'s ##value## even is the ##shader## is not
the current one.
**/
__rayapi signed char raydium_shader_var_2f(int var_id, float value1, float value2);
/**
This function will change the ##value## of the variable ##var_id## of
the current shader.
Value is an "array" of 2 floats (vec2).
**/
__rayapi signed char raydium_shader_var_2f_name(char *shader, char *variable, float value1, float value2);
/**
Same as above, but using shader's name and variable's name. This function is
able to change the ##variable##'s ##value## even is the ##shader## is not
the current one.
**/
__rayapi signed char raydium_shader_var_3f(int var_id, float value1, float value2, float value3);
/**
This function will change the ##value## of the variable ##var_id## of
the current shader.
Value is an "array" of 3 floats (vec3).
**/
__rayapi signed char raydium_shader_var_3f_name(char *shader, char *variable, float value1, float value2, float value3);
/**
Same as above, but using shader's name and variable's name. This function is
able to change the ##variable##'s ##value## even is the ##shader## is not
the current one.
**/
__rayapi signed char raydium_shader_var_4f(int var_id, float value1, float value2, float value3, float value4);
/**
This function will change the ##value## of the variable ##var_id## of
the current shader.
Value is an "array" of 4 floats (vec4).
**/
__rayapi signed char raydium_shader_var_4f_name(char *shader, char *variable, float value1, float value2, float value3, float value4);
/**
Same as above, but using shader's name and variable's name. This function is
able to change the ##variable##'s ##value## even is the ##shader## is not
the current one.
**/
__rayapi signed char raydium_shader_current(int shader);
/**
This function will change the current active shader with ##shader##.
To disable a shader and get back to regular OpenGL fixed function pipeline,
set ##shader## value to ##-1##.
**/
__rayapi signed char raydium_shader_current_name(char *shader);
/**
Same as above, but using shader's name.
**/
__rayapi signed char raydium_shader_attach_texture(int shader, int texture);
/**
During rendering, each time the ##texture## will be used by any object,
the ##shader## will be activated.
**/
__rayapi signed char raydium_shader_attach_texture_name(char *shader, char *texture);
/**
Same as above, but using shader's name and texture's name.
**/
#endif

16
raydium/headers/shadow.h Normal file
View File

@ -0,0 +1,16 @@
#ifndef _SHADOW__H
#define _SHADOW__H
#include "../shadow.h"
__rayapi void raydium_shadow_init(void);
__rayapi void raydium_shadow_enable(void);
__rayapi void raydium_shadow_disable(void);
__rayapi signed char raydium_shadow_isenabled(void);
__rayapi void raydium_shadow_light_main(GLuint l);
__rayapi void raydium_shadow_ground_change(int object);
__rayapi void raydium_shadow_map_generate(void);
__rayapi void raydium_shadow_map_render(void);
__rayapi void raydium_shadow_object_draw(GLuint o);
#endif

17
raydium/headers/signal.h Normal file
View File

@ -0,0 +1,17 @@
#ifndef _HEADERS_SIGNAL_H
#define _HEADERS_SIGNAL_H
/*=
Signals
2500
**/
// Quickview
/**
There almost nothing to said about signals management, except that Raydium
will try to catch SIGINT signal (sended by CTRL+C sequence, for example).
There's nothing else for now, but we plan a user callback for this signal.
**/
__rayapi void raydium_signal_handler (int sig);
__rayapi void raydium_signal_install_trap (void);
#endif

80
raydium/headers/sky.h Normal file
View File

@ -0,0 +1,80 @@
#ifndef _SKY_H
#define _SKY_H
/*=
Sky and environement boxes
1900
**/
// Introduction
/**
Skyboxes are mostly automated.
For now, Raydium will use ##BOXfront.tga##, ##BOXback.tga##, ##BOXleft.tga##,
##BOXright.tga##, ##BOXbottom.tga## and ##BOXtop.tga## and will draw a
skybox only if fog is disabled (this is not for technical reasons,
but only for realism, just think about it ;)... but you can force
skybox with fog using ##raydium_sky_force## if you really want).
**/
__rayapi void raydium_sky_box_cache (void);
/**
As skybox texture are sometimes large files, you can pre-load skybox
with this function. If you don't do it, Raydium will load textures
during the first frame of your application.
Calling this function will automatically define sky as a HDR emitter.
See HDR chapter for more information.
**/
__rayapi void raydium_sky_box_render (GLfloat x, GLfloat y, GLfloat z);
/**
Internal use.
**/
__rayapi void raydium_sky_sphere_render(GLfloat x, GLfloat y, GLfloat z, int detail);
/**
Internal use.
Calculates and draw the sphere. Also rotate it according the angles or orbit.
**/
//Atmosphere
/**
Atmosphere are series of effects that intend to make the sky and the atmosphere
of the game more realistic. As this is quite-beta state, only a orbital sky
effect is available right now.
To activate/deactivate this series of effects, you should use:
##raydium_sky_atmosphere_enable## and ##raydium_sky_atmosphere_disable##
respectively.
If you need to check if the atmosphere is activated or not, use
##raydium_sky_atmosphere_check##. The rest of the functions are internal
and should not used by normal programs.
**/
__rayapi void raydium_sky_atmosphere_enable(void);
/**
turn on the use of atmosphere effects.
This one and _disable function a program should use, the other
##raydium_sky_atmosphere_## are internal ones.
**/
__rayapi void raydium_sky_atmosphere_disable(void);
/**
turn off the use of atmosphere effects.
**/
__rayapi void raydium_sky_atmosphere_render(GLfloat x, GLfloat y, GLfloat z,int detail);
/**
Internal use. This internal function draws the atmosphere effects. Right
now only draws a rotating sphere with a gradient of color (from black to white).
In a future, it will draw multiples layers of sky (with and without textures),
stars, satellites... Maybe rain and snow could be included here also.
**/
__rayapi signed char raydium_sky_atmosphere_check(void);
/**
This functions only check if the atmosphere features are been used.
Returns 1 if they are used, else 0.
**/
#endif

292
raydium/headers/sound.h Normal file
View File

@ -0,0 +1,292 @@
#ifndef _SOUND_H
#define _SOUND_H
/*=
Sound and music
2600
**/
// Introduction
/**
The Raydium sound API is pretty easy to use and there's only need to use a
few functions to make your program ouput sounds or music.
On top of this, there are a bunch of functions to modify the sound behavior.
Raydium uses OpenAL and OggVorbis for its sounds and musics, for a basic
use of our sound API you only need to know one thing: OpenAL uses buffers
for its sounds and you need to be able to address the sounds separately.
For this we use ALuint in our code. Each buffer is associated to a source,
we have an array of all available sources and then, you only need to have
a simple int that acts as an index in this array. See below for more
informations.
Music is readed thru libogg, streamed from disk. If you want to play an
OGG audio track, the only thing you've to do is to call the suitable function.
You can use ##raydium_sound_music_eof_callback## if needed. This event is
fired when sound track ends, allowing you to switch to another file.
Prototype for this callback is ##int callback(char *new_track)##, allowing
you to do something like ##strcpy(new_track,"foobar.ogg"); return 1;##.
Return 0 if you do not want to switch to another audio file (this will stops
music playback).
Another callback is available, ##raydium_sound_music_changed_callback##, fired
just after a music track switch, allowing you to get new informations from the
new stream, such as artist, album and title. See ##raydium_sound_load_music()##
for more informations about this.
This document is not an alternative to OpenAL papers, and only provides
informations about Raydium's interface to OpenAL.
See specifications here: http://www.openal.org/documentation.html
**/
__rayapi void raydium_sound_verify (char *caller);
/**
This functions checks if any error occured during last OpenAL operation.
You don't have to call this function by yourself, since every function of
this API will do it.
**/
__rayapi int raydium_sound_Array3IsValid(ALfloat *a);
/**
Since OpenAL is very sensitive to malformed values, this function is used
internally to check consistency of provided ALfloat arrays.
**/
__rayapi void raydium_sound_InitSource (int src);
/**
Internal use.
**/
__rayapi int raydium_sound_LoadWav (const char *fname);
/**
This function tries to load the ##fname## wav file into a buffer, if
successful, it returns the source id, else 0.
**/
__rayapi int raydium_sound_SourceVerify (int src);
/**
Internal id checks.
**/
__rayapi int raydium_sound_SetSourceLoop (int src, signed char loop);
/**
Modifies the ##loop## property of the ##src## source (loops if loop is non-zero,
default value for a source is "true").
Returns 0 if ok, -1 if error.
**/
__rayapi int raydium_sound_GetSourcePitch (int src, ALfloat * p);
/**
Returns current pitch for ##src## source.
**/
__rayapi int raydium_sound_SetSourcePitch (int src, ALfloat p);
/**
Sets pitch for ##src## source.
Current OpenAL spec is not clear about pitch's limits. Raydium will
clamp values to to ]0,2] interval.
**/
__rayapi int raydium_sound_GetSourceGain (int src, ALfloat * g);
/**
Returns current gain ("volume") for ##src## source.
**/
__rayapi int raydium_sound_SetSourceGain (int src, ALfloat g);
/**
Sets gain ("volume") for ##src## source.
Current OpenAL spec is not clear about pitch's limits. Raydium do not allows
negative values, but no upper limit is set.
Warning: some OpenAL implementations will provide strange gain curves. More
work is needed on this issue.
**/
__rayapi int raydium_sound_SetSourcePos (int src, ALfloat Pos[]);
/**
Sets 3D position of ##src## source.
##Pos## is a 3 * ALfloat array.
**/
__rayapi int raydium_sound_SetSourcePosCamera(int src);
/**
Sets 3D position of ##src## source on the current camera position.
**/
__rayapi int raydium_sound_GetSourcePos (int src, ALfloat * Pos[]);
/**
Returns current 3D position of ##src## source.
##Pos## is a 3 * ALfloat array.
**/
__rayapi int raydium_sound_SetSourceDir (int src, ALfloat Dir[]);
/**
Sets 3D direction of ##src## source.
##Dir## is a 3 * ALfloat array.
**/
__rayapi int raydium_sound_GetSourceDir (int src, ALfloat * Dir[]);
/**
Returns current 3D direction of ##src## source.
##Dir## is a 3 * ALfloat array.
**/
__rayapi int raydium_sound_SetSourceVel (int src, ALfloat Vel[]);
/**
Sets 3D velocity of ##src## source.
##Vel## is a 3 * ALfloat array.
**/
__rayapi int raydium_sound_GetSourceVel (int src, ALfloat * Vel[]);
/**
Returns current 3D velocity of ##src## source.
##Vel## is a 3 * ALfloat array.
**/
__rayapi void raydium_sound_SetListenerPos (ALfloat Pos[]);
/**
Sets 3D position of listener.
This is done automatically by Raydium, each frame, using camera informations
##Pos## is a 3 * ALfloat array.
**/
__rayapi void raydium_sound_GetListenerPos (ALfloat * Pos[]);
/**
Returns current 3D position of listener.
##Pos## is a 3 * ALfloat array.
**/
__rayapi void raydium_sound_SetListenerOr (ALfloat Or[]);
/**
Sets 3D orientation of listener.
This is done automatically by Raydium, each frame, using camera informations
##Or## is a 3 * ALfloat array.
**/
__rayapi void raydium_sound_GetListenerOr (ALfloat * Or[]);
/**
Returns current 3D orientation of listener.
##Or## is a 3 * ALfloat array.
**/
__rayapi void raydium_sound_SetListenerVel (ALfloat Vel[]);
/**
Sets 3D velocity of Listener.
##Vel## is a 3 * ALfloat array.
**/
__rayapi void raydium_sound_GetListenerVel (ALfloat * Vel[]);
/**
Returns current 3D velocity of Listener.
##Vel## is a 3 * ALfloat array.
**/
__rayapi void raydium_sound_init (void);
/**
Internal use.
**/
__rayapi int raydium_sound_SourcePlay (int src);
/**
Plays the ##src## source.
If ##src## was already in "play" state, the buffer is rewinded.
Returns 0 if ok, -1 if error.
**/
__rayapi int raydium_sound_SourceStop (int src);
/**
Stops the ##src## source.
Returns 0 if ok, -1 if error.
**/
__rayapi int raydium_sound_SourcePause (int src);
/**
Will pause the ##src## source.
Returns 0 if ok, -1 if error.
**/
__rayapi int raydium_sound_SourceUnpause (int src);
/**
##src## will restart playback after being paused.
Returns 0 if ok, -1 if error.
**/
__rayapi signed char raydium_sound_IsPlaying(int src);
/**
Returns true (1) if ##src## is playing, false (0) if stopped or invalid.
**/
__rayapi void raydium_sound_close (void);
/**
Internal use.
**/
__rayapi int BufferData (ALuint buffer, OggVorbis_File * file, vorbis_info * ogginfo);
__rayapi void raydium_sound_internal_cleanstreambuffs (void);
__rayapi int StartMusic (ALuint musicsource, ALuint * buffers, OggVorbis_File * file, vorbis_info * ogginfo);
__rayapi int raydium_sound_load_music (char *fname);
/**
Opens fname **OGG** music file and prepairs Raydium for playing it.
The music will be automatically played after a call to this function.
This function will use R3S (data repositories) if needed.
To switch to another audio track, simply call again this function.
Send ##NULL## or an empty string to cancel music playback.
Returns 0 if ok, -1 if error
See also ##raydium_sound_music_eof_callback## at the top of this chapter.
You can get OGG informations from ##raydium_sound_music_info##, using
its members:
%%(c)
char artist[RAYDIUM_MAX_NAME_LEN];
char title [RAYDIUM_MAX_NAME_LEN];
char album [RAYDIUM_MAX_NAME_LEN];
%%
**/
__rayapi void raydium_sound_music_info_init(void);
/**
Internal use. Will reset infos.
**/
__rayapi void raydium_sound_music_info_refresh(void);
/**
Internal use. Will flush infos from disk to ##raydium_sound_music_info##.
**/
__rayapi void raydium_sound_music_callback (void);
/**
Internal use.
**/
__rayapi void raydium_sound_callback (void);
/**
Internal use.
**/
__rayapi void raydium_sound_source_fade(int src, ALfloat len);
/**
This function will fade down source ##src## over ##len## seconds.
Since gain is not linear, you may have to play a bit with ##len## to
find the correct value for you.
Use source 0 for music source.
**/
// Sound API Example
/**
%%(c)
int sound;
sound=raydium_sound_LoadWav("explo.wav");
raydium_sound_SetSourceLoop(sound,0);
[...]
if(explosion) raydium_sound_SourcePlay(sound);
%%
**/
__rayapi void raydium_sound_source_fade_to(int src, ALfloat len, char *to);
/**
Same as above, but plays ##to## file at the end of the fade.
Warning: Works only for "music" source (##src## = 0).
**/
#endif

99
raydium/headers/texture.h Normal file
View File

@ -0,0 +1,99 @@
#ifndef _TEXTURE_H
#define _TEXTURE_H
/*=
Textures
1200
**/
// Introduction
/**
For now, Raydium only handles TGA uncompressed texture.
As explainded in the first part of this guide, Raydium provides three
texture filters (none, bilinear, trilinear using MipMaps ).
Texture sizes must be a power of two, 8 (alpha mask), 24 (RGB) or 32 (RGBA) bits.
Raydium supports simple color materials, using a "rgb(r,g,b)" string
as texture name, where r, g and b are 0 <= x <= 1 (floats).
With 3 negative values, you will generate a "phantom texture". Phantom textures
are only drawn into the z-buffer (and not color buffer).
Texture clamping and advanced multitexturing effects are supported by Raydium,
but not documented here for now. If you're interested, have a look at source
code, or take a look at the Wiki. Tips: "BOX", "ENV", "HDR", ";", "|".
Effective environment mapping (one pass, two texture units) is available using
a special filename separator for texture field in TRI files : #
See this example:
##0.232258 0.225387 -0.149804 0.012198 -0.274925 0.961388 0.731411 0.980236 fiesta_diffuse.tga#ENV_map.tga##
Environment texture name must start with "ENV" to allow spherical mapping, wich
is needed for such effect. See also ##RAYDIUM_RENDER_REFLECTION_FACT## in
file ##common.h## if you want reflection to be more or less visible.
**/
__rayapi signed char raydium_texture_size_is_correct (GLuint size);
/**
Returns true if ##size## is a correct texture size, depending of
hardware capacities and "power of 2" constraint.
**/
__rayapi GLuint raydium_texture_load_internal(char *filename, char *as, signed char faked, int faked_tx, int faked_ty, int faked_bpp, int or_live_id_fake);
/**
Internal use.
**/
__rayapi GLuint raydium_texture_load (char *filename);
/**
Loads "filename" texture into hardware memory. Function results
texture index, but in most cases, you can identify later a texture
by his name, without providing his index, so you can probably ignore
this value.
0 is returned if texture loading have failed.
**/
__rayapi GLuint raydium_texture_load_erase (char *filename, GLuint to_replace);
/**
Same as above, but ##to_replace## texture (index) is erased with ##filename##.
**/
__rayapi signed char raydium_texture_current_set (GLuint current);
/**
Switch active texture to "current" index. Mostly used for runtime object
creation:
"set current texture, add vertices, set another texture,
add vertices, ... and save all to an objet"
(see below for vertices management).
**/
__rayapi signed char raydium_texture_current_set_name (char *name);
/**
Same as above, but using texture name. This function will load ##name##
if not alread done.
**/
__rayapi GLuint raydium_texture_find_by_name (char *name);
/**
Returns index for texture "name", and load it if not already done.
**/
__rayapi GLuint raydium_texture_exists(char *name);
/**
Same as above, but don't load texture if ##name## isn't already loaded and
then returns -1. Returns texture id otherwise.
**/
__rayapi void raydium_texture_filter_change (GLuint filter);
/**
Change texture filter. The new filter will apply on all "next" textures,
but will not change already loaded ones (this was the case in old Raydium
releases), since it may generate strange bugs with dynamic (aka "faked")
textures, and it was very slow.
%%(c)
// will switch to bilinear filter for next textures
raydium_texture_filter_change(RAYDIUM_TEXTURE_FILTER_BILINEAR)%%
**/
#endif

146
raydium/headers/timecall.h Normal file
View File

@ -0,0 +1,146 @@
#ifndef _TIMECALL_H
#define _TIMECALL_H
/*=
Timecalls
2700
**/
// Concept
/**
As you may already know, in a real time application (as a game), you need
to control in-game time evolution.
For example, you cannot increment a car position by 1 at each frame since
it will generate an irregular scrolling (a frame is never rendered within
the same time as the previous or the next one).
Raydium supports timecalls, wich are a great solution for this problem.
Usage is very simple: write a simple function, and ask Raydium to call it
at the desired rate.
**/
// Constraints
/**
There is an important risk with timecalls: infinite loops.
If a callback is long, it may take more CPU time than he would, as in this
very simple example:
foo() is a function, taking 200 ms for his own execution. If you ask for
a 6 Hz execution, Raydium will execute foo() six times on the first frame,
taking 1200 ms. On the next frame, Raydium will need to execute foo() 7
times (the asked 6 times, and one more for the 200 ms lost during the last
frame), taking 1400 ms, so 8 times will be needed for the next frame, then 9, ...
So you need to create callbacks as short as possible, since long callbacks
may cause a game freeze on slower machines than yours. (1 FPS syndrom)
**/
// Hardware devices and methods
/**
Raydium must use a very accurate system timer, and will try many methods:
##/dev/rtc## , ##gettimeofday()## (Linux only) and
##QueryPerformanceCounter## for win32.
##gettimeofday()## will use a CPU counter and is extremely accurate.
It's far the best method. (0.001 ms accuracy is possible)
##/dev/rtc## is quite good, and Raydium will try to configure RTC at
##RAYDIUM_TIMECALL_FREQ_PREFERED## rate (8192 Hz by default), but may
require a "##/proc/sys/dev/rtc/max-user-freq##" modification:
##echo 8192 > /proc/sys/dev/rtc/max-user-freq##
You may want to look at common.c for interesting defines about timecalls.
**/
#ifdef WIN32
#define __GETTIMEOFDAY_USEC 1000
#else
#define __GETTIMEOFDAY_USEC 1000000
#endif
__rayapi void raydium_timecall_raydium (GLfloat step);
/**
Internal Raydium callback.
**/
#ifdef WIN32
__rayapi float raydium_timecall_internal_w32_detect_modulo(int div);
/**
Internal, WIN32 only: Returns timer resolution for ##div## divisor.
**/
__rayapi int raydium_timecall_internal_w32_divmodulo_find(void);
/**
Internal, WIN32 only: Detects the best timer divisor for the current CPU.
**/
#endif
__rayapi unsigned long raydium_timecall_devrtc_clock (void);
/**
Internal, Linux only: Reads and return RTC clock.
**/
__rayapi unsigned long raydium_timecall_clock (void);
/**
Returns current "time".
**/
__rayapi signed char raydium_timecall_devrtc_rate_change (unsigned long new_rate);
/**
Internal, Linux only: Modifies RTC clock rate.
**/
__rayapi void raydium_timecall_devrtc_close (void);
/**
Internal, Linux only: Will close RTC clock.
**/
__rayapi unsigned long raydium_timecall_devrtc_init (void);
/**
Internal, Linux only: Will open RTC clock.
**/
__rayapi int raydium_timecall_detect_frequency (void);
/**
Internal: This function will find the best timer available for current
platform, and adjust properties to your hardware (rate, divisor, ...).
**/
__rayapi void raydium_timecall_init (void);
/**
Internal use.
**/
__rayapi int raydium_timecall_add (void *funct, GLint hz);
/**
There is two sort of timecalls with Raydium:
1. Standard ones:
%%(c)
raydium_timecall_add(function,800);
%%
##void function(void)## will be called 800 times per second.
2. Elastic timed ones:
%%(c)
raydium_timecall_add(function,-80);
%%
##void function(float step)## will be called for each frame, with a
"##step## factor" as argument. In the above example, a 160 Hz game will call
function with step = 0.5, but step = 2.0 for a 40 Hz game.
A standard timecall will use ##void(void)## function and a positive ##hertz##
argument, as an elasitc one will use ##void(float)## and negative ##hertz## argument.
**/
__rayapi void raydium_timecall_freq_change (int callback, GLint hz);
/**
This function changes the ##callback## frequency. See above for possibles
values of ##hz## (negative and positive values).
**/
__rayapi void raydium_timecall_callback (void);
/**
Internal use (frame fired callback).
**/
#endif

137
raydium/headers/trigo.h Normal file
View File

@ -0,0 +1,137 @@
#ifndef _TRIGO_H
#define _TRIGO_H
/*=
Maths
200
*/
// Little introduction to trigo.c
/**
This section is mostly designed for internal uses, but provides some
usefull maths functions, mostly for trigonometrical uses.
**/
__rayapi GLfloat raydium_trigo_cos (GLfloat i);
/**
Obvious (degrees)
**/
__rayapi GLfloat raydium_trigo_sin (GLfloat i);
/**
Obvious (degrees)
**/
__rayapi GLfloat raydium_trigo_cos_inv (GLfloat i);
/**
Obvious (degrees)
**/
__rayapi GLfloat raydium_trigo_sin_inv (GLfloat i);
/**
Obvious (degrees)
**/
#define raydium_trigo_abs(a) ( (a) < (0) ? (-a) : (a) )
/**
Obvious
**/
#define raydium_trigo_min(a,b) ( (a) < (b) ? (a) : (b) )
/**
Obvious
**/
#define raydium_trigo_max(a,b) ( (a) > (b) ? (a) : (b) )
/**
Obvious
**/
#define raydium_trigo_isfloat(a) ( (!isnan(a) && !isinf(a)) ? 1 : 0)
/**
Test two cases : "Not a Number" and "Infinite"
**/
#define raydium_trigo_round(a) ((int)((a)>0?((a)+0.5):((a)-0.5)))
/**
Will obviously "round" ##a## instead of the default C floor behaviour
**/
__rayapi void raydium_trigo_rotate (GLfloat * p, GLfloat rx, GLfloat ry, GLfloat rz, GLfloat * res);
/**
Rotate p (GLfloat * 3) by (rx,ry,rx) angles (degrees).
Result is stored in res (GLfloat * 3)
**/
__rayapi void raydium_trigo_pos_to_matrix (GLfloat * pos, GLfloat * m);
/**
Generates a ODE style matrix (16 Glfloat) from pos (GLfloat * 3)
**/
__rayapi void raydium_trigo_pos_get_modelview (GLfloat * res);
/**
Stores the current OpenGL MODELVIEW matrix in res (16 GLfloat)
**/
__rayapi int raydium_trigo_pow2_next(int value);
/**
Returns next power of two of ##value##. Ugly.
**/
//Matrix functions
/**
Here there are a few functions also designed for internal uses that aims
only at matrices. Really the main objective of these functions is give support
for the inverse function.
The data type matrix4x4 is really an 16 double array.
**/
__rayapi double raydium_matrix_determinant(matrix4x4 matrix);
/**
Returns the ##determinant## of the given matrix.
**/
__rayapi matrix4x4 raydium_matrix_adjoint(matrix4x4 matrix);
/**
Returns the ##adjoint matrix## of the given matrix.
**/
__rayapi matrix4x4 raydium_matrix_multiply(matrix4x4 matrix1, matrix4x4 matrix2);
/**
Returns the resulting matrix of the multiplication of 2 matrices.
Remeber that the multiplication of matrices doesn't have the conmutative
property, so is not equal ##matrix1 X matrix2## than ##matrix2 x matrix1##.
**/
__rayapi matrix4x4 raydium_matrix_inverse(matrix4x4 matrix);
/**
Returns the inverse matrix of a given matrix.
**/
__rayapi double raydium_matrix_internal_determinant(matrix4x4 matrix, int dimension);
/**
internal, don't use.
**/
__rayapi matrix4x4 raydium_matrix_internal_adjoint(matrix4x4 matrix, int dimension);
/**
internal, don't use.
**/
__rayapi matrix4x4 raydium_matrix_internal_multiply(matrix4x4 matrix_one, matrix4x4 matrix_two, int dimension);
/**
internal, don't use.
**/
__rayapi matrix4x4 raydium_matrix_internal_inverse(matrix4x4 adjoint_matrix,double det,int dimension);
/**
internal, don't use.
**/
__rayapi int _raydium_trigo_MatrixInverse(const float *m,float *out);
/*
Our matrix_inverse seems broken.
This code works, thanks to Alexander Zaprjagaev (frustum@public.tsu.ru)
This code is not native
*/
#endif

32
raydium/headers/vertex.h Normal file
View File

@ -0,0 +1,32 @@
#ifndef _VERTEX_H
#define _VERTEX_H
/*=
vertices
1700
**/
// Introduction
/**
You can create objets at runtime, if needed, using the following functions.
Each of theses functions adds only one vertex so, obviously, you need to
call three time the same function to add one triangle.
**/
__rayapi void raydium_vertex_add (GLfloat x, GLfloat y, GLfloat z);
/**
Adds a vertex at (##x,y,z##).
**/
__rayapi void raydium_vertex_uv_add (GLfloat x, GLfloat y, GLfloat z, GLfloat u, GLfloat v);
/**
Same as above, but providing texture mapping informations with ##u## and ##v##.
**/
__rayapi void raydium_vertex_uv_normals_add (GLfloat x, GLfloat y, GLfloat z, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat u, GLfloat v);
/**
Same as above, giving vertex's normal with (##nx,ny,nz##).
**/
#endif

111
raydium/headers/video.h Normal file
View File

@ -0,0 +1,111 @@
#ifndef _VIDEO_H
#define _VIDEO_H
#include "../video.h"
/*=
Video playback
4100
**/
// Introduction
/**
Raydium supports simple video playback, thru a special video codec (JPGS),
useful for menus enhancements, "speaking" thumbnails, ...
This codec only supports video, use sound API if needed.
You will find an small utility, ##mk_jpgs## in Raydium source tree, didacted to
movie creation.
**/
// How to create a movie ?
/**
First, compile ##mk_jpgs##: example: ##gcc mk_jpgs.c -o mk_jpgs## or any other
standard build command.
Then, generate JPEG pictures (using a temporary directory, if possible):
##mplayer movie.avi -vo jpeg:quality=50 -vf scale=256:256##, where you may
change quality factor and output size. Use "hardware friendly" sizes (64,
128,256,...) !
You can now build JPGS file:
##./mk_jpgs 25 256 256 video.jpgs## (fps, size x, size y, output file)
**/
__rayapi void raydium_video_init(void);
/**
Internal use.
**/
__rayapi signed char raydium_video_isvalid(int i);
/**
Internal use, but you can call this function if you want to verify if a
video id is valid (in bounds and open).
**/
__rayapi int raydium_video_find_free(void);
/**
Internal use.
Finds a free video slot.
**/
__rayapi int raydium_video_find(char *name);
/**
Resolvs video ##name##, returning video id.
Returns -1 when video is not found.
**/
__rayapi void raydium_video_jpeg_decompress(FILE *fp,unsigned char *to);
/**
Internal.
**/
__rayapi int raydium_video_open(char *filename, char *as);
/**
This function will open and prepare video ##filename##, and will attach
this video to a "live texture" (see Live API chapter, if needed).
**/
__rayapi void raydium_video_callback_video(int id);
/**
Internal use.
**/
__rayapi void raydium_video_callback(void);
/**
Internal use. Frame callback.
**/
__rayapi void raydium_video_delete(int id);
/**
Will delete video ##id##. Warning: this function will not delete
associated Live texture, so you may open a new video with the same
texture name, but video size must be the same a the previous one.
**/
__rayapi void raydium_video_delete_name(char *name);
/**
Same as above, using video name.
**/
__rayapi void raydium_video_loop(int id, signed char loop);
/**
Sets loop attribute for the video ##id##. By defaults, video loops. Call
this function with loop=0 to disable this behavior.
**/
__rayapi void raydium_video_loop_name(char *name, signed char loop);
/**
Same as above, using video name.
**/
__rayapi signed char raydium_video_isplaying(int id);
/**
Returns **1** is video ##id## is playing, **0** if this video is stopped,
and **-1** if function failed.
**/
__rayapi signed char raydium_video_isplaying_name(char *name);
/**
Same as above, using video name.
**/
#endif

20
raydium/headers/web.h Normal file
View File

@ -0,0 +1,20 @@
#ifndef _WEB_H
#define _WEB_H
#include "../web.h"
/*=
HTTP Web Tools
4200
**/
__rayapi void raydium_web_answer(char *message, int fd);
__rayapi void raydium_web_request(int fd);
__rayapi void raydium_web_start(char *title);
__rayapi void raydium_web_callback(void);
__rayapi void raydium_web_init(void);
__rayapi void raydium_web_extension_add(char *ext, char *mime, void *handler);
__rayapi signed char raydium_web_client_get(char *filename);
#endif

52
raydium/headers/window.h Normal file
View File

@ -0,0 +1,52 @@
#ifndef _WINDOW_H
#define _WINDOW_H
/*=
Window management
600
**/
// Introduction
/**
Some important functions, used for window creation and managment.
**/
__rayapi void raydium_window_close (void);
/**
This function is called by Raydium, do not use.
**/
__rayapi void raydium_window_create (GLuint tx, GLuint ty, signed char rendering, char *name);
/**
You must call this function once in your program, with following arguments:
1. ##tx##, ##ty##: window size, in pixel
2. ##rendering##: window mode: ##RAYDIUM_RENDERING_*## (NONE, WINDOW, FULLSCREEN)
3. ##name##: window's name
Raydium is using GLUT for window management, and GLUT fullscreen is not
the same between various implementations, and can fail,
so use a standard window size (640x480, 800x600, ...) for fullscreen mode.
Note that user can force fullscreen using ##--fullscreen## on the command line.
**/
__rayapi void raydium_window_resize_callback (GLsizei Width, GLsizei Height);
/**
This function is automaticaly called during a window resize,
and resize OpenGL rendering space.
There is almost no reason to call this function by yourself.
**/
__rayapi void raydium_window_view_update (void);
/**
If you've changed 3D window size (clipping: raydium_projection_*),
apply to hardware with this fonction.
**/
__rayapi void raydium_window_view_perspective(GLfloat fov, GLfloat fnear, GLfloat ffar);
/**
All-in-one function: sets all "perspective" variables, and updates.
**/
#endif

120
raydium/index.c Normal file
View File

@ -0,0 +1,120 @@
#ifndef FORCE_LIBRAYDIUM
/*
* Raydium - CQFD Corp.
* http://raydium.org/
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
// Include this file if you want to use "[o]comp*.sh" scripts, for
// a full compilation + run.
// Define "FORCE_LIBRAYDIUM" (-DFORCE_LIBRAYDIUM) if you want to
// force index.h (see dyncomp.sh).
#ifdef __cplusplus
extern "C" {
#endif
#define DONT_INCLUDE_HEADERS
#include "main.c"
// let's start "compile time static linking" ;)
#ifndef RAYDIUM_NETWORK_ONLY
#include "myglut.c"
#include "log.c"
#include "atexit.c"
#include "signal.c"
#include "trigo.c"
#include "random.c"
#include "timecall.c"
#include "profile.c"
#include "parser.c"
#include "fog.c"
#include "window.c"
#include "capture.c"
#include "clear.c"
#include "background.c"
#include "light.c"
#include "key.c"
#include "mouse.c"
#include "joy.c"
#include "texture.c"
#include "shadow.c"
#include "render.c"
#include "particle2.c"
#include "sound.c"
#include "callback.c"
#include "normal.c"
#include "vertex.c"
#include "osd.c"
#include "hdr.c"
#include "shader.c"
#include "register.c"
#ifdef PHP_SUPPORT
#include "php.c"
#include "rayphp.c"
#endif
#include "console.c"
#include "gui.c"
#include "land.c"
#include "sky.c"
#include "internal.c"
#include "file.c"
#include "path.c"
#include "file_tri.c"
#include "camera.c"
#include "object.c"
#include "cli.c"
#include "network.c"
#include "init.c"
#ifdef ODE_SUPPORT
#include "ode.c"
#endif
#include "live.c"
#include "video.c"
#include "web.c"
#include "reg_api.c"
#else
#include "atexit.c"
#include "network.h"
#include "log.c"
#include "trigo.c"
#include "random.c"
#include "timecall.c"
#include "parser.c"
#include "cli.c"
#include "network.c"
#include "file.c"
#include "path.c"
#include "register.c"
#ifdef PHP_SUPPORT
#include "php.c"
#include "rayphp.c"
#endif
#include "console.c"
#include "web.c"
#endif
#ifdef __cplusplus
} // close extern "C"
#endif
#else // FORCE_LIBRAYDIUM is defined
#include "index.h"
#endif
// EOF

112
raydium/index.h Normal file
View File

@ -0,0 +1,112 @@
/*
* Raydium - CQFD Corp.
* http://raydium.org/
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
// Include this file if you want to use Makefile and libraydium, for
// a quick compilation (use odyncomp.sh script, for example)
#ifdef __cplusplus
extern "C" {
#endif
#include "main.h"
#ifndef RAYDIUM_NETWORK_ONLY
#include "headers/myglut.h"
#include "headers/log.h"
#include "headers/atexit.h"
#include "headers/signal.h"
#include "headers/trigo.h"
#include "headers/random.h"
#include "headers/timecall.h"
#include "headers/profile.h"
#include "headers/parser.h"
#include "headers/fog.h"
#include "headers/window.h"
#include "headers/capture.h"
#include "headers/clear.h"
#include "headers/background.h"
#include "headers/light.h"
#include "headers/key.h"
#include "headers/mouse.h"
#include "headers/joy.h"
#include "headers/texture.h"
#include "headers/shadow.h"
#include "headers/render.h"
#include "headers/particle2.h"
#include "headers/sound.h"
#include "headers/callback.h"
#include "headers/normal.h"
#include "headers/vertex.h"
#include "headers/osd.h"
#include "headers/hdr.h"
#include "headers/shader.h"
#include "headers/register.h"
#ifdef PHP_SUPPORT
#include "headers/php.h"
#include "headers/rayphp.h"
#endif
#include "headers/console.h"
#include "headers/gui.h"
#include "headers/land.h"
#include "headers/sky.h"
#include "headers/internal.h"
#include "headers/file.h"
#include "headers/path.h"
#include "headers/file_tri.h"
#include "headers/camera.h"
#include "headers/object.h"
#include "headers/cli.h"
#include "headers/network.h"
#include "headers/init.h"
#ifdef ODE_SUPPORT
#include "headers/ode.h"
#endif
#include "headers/live.h"
#include "headers/video.h"
#include "headers/web.h"
#include "headers/reg_api.h"
#else
#warning "unless you know what you're doing, RAYDIUM_NETWORK_ONLY with \
dynamic linking is a bad idea. Use static linking instead (ex: comp.sh)"
#include "headers/atexit.h"
#include "network.h"
#include "headers/log.h"
#include "headers/trigo.h"
#include "headers/random.h"
#include "headers/timecall.h"
#include "headers/parser.h"
#include "headers/cli.h"
#include "headers/network.h"
#include "headers/file.h"
#include "headers/path.h"
#include "headers/register.h"
#ifdef PHP_SUPPORT
#include "headers/rayphp.h"
#include "headers/php.h"
#endif
#include "headers/console.h"
#include "headers/web.h"
#endif
#ifdef __cplusplus
} // close extern "C"
#endif
//EOF

267
raydium/init.c Normal file
View File

@ -0,0 +1,267 @@
/*
Raydium - CQFD Corp.
http://raydium.org/
License: GPL - GNU General Public License, see "gpl.txt" file.
*/
#ifndef DONT_INCLUDE_HEADERS
#include "index.h"
#else
#include "headers/init.h"
#endif
// proto
void raydium_ode_init(void);
void raydium_register_api(void);
#ifndef WIN32
void raydium_live_init(void);
#endif
void raydium_fog_init(void);
void raydium_video_init(void);
void raydium_internal_live_close(void);
void raydium_shadow_init(void);
void raydium_hdr_init(void);
void raydium_hdr_texture_reset(void);
void raydium_shader_init(void);
void raydium_web_init(void);
char *raydium_version(void)
{
static char version[RAYDIUM_MAX_NAME_LEN];
static signed char first=1;
if(first)
{
first=0;
sprintf(version,"%i.%03i",RAYDIUM_MAJOR,RAYDIUM_MINOR);
}
return version;
}
void raydium_init_lights(void)
{
GLuint i;
for(i=0;i<RAYDIUM_MAX_LIGHTS;i++)
raydium_light_reset(i);
raydium_log("lights: OK");
}
void raydium_init_objects(void)
{
GLuint i;
raydium_object_anim_time_factor=1.f;
for(i=0;i<RAYDIUM_MAX_OBJECTS;i++)
raydium_object_reset(i);
raydium_log("objects: OK");
}
void raydium_init_key(void)
{
if(raydium_window_mode==RAYDIUM_RENDERING_NONE)
return;
glutIgnoreKeyRepeat(1);
memset(raydium_key,0,RAYDIUM_KEYBOARD_SIZE);
raydium_key_last=0;
raydium_key_trace=0;
raydium_log("keyboard: OK");
}
// NEVER tested as it should be ! (used once only for now)
void raydium_init_reset(void)
{
GLuint i;
/*
for(i=1;i<raydium_texture_index;i++) // free all texture buffers
free(raydium_texture_ptr[i]);
*/
raydium_init_lights();
raydium_fog_init();
raydium_init_objects();
raydium_network_init();
raydium_timecall_init();
raydium_particle_init();
raydium_camera_path_init_all();
raydium_osd_fade_init();
raydium_console_init();
raydium_gui_init();
#ifndef WIN32
raydium_live_init();
#endif
raydium_video_init();
raydium_shadow_init();
raydium_hdr_init();
raydium_shader_init();
raydium_web_init();
// Must find a way to delete textures from video card's memory, too...
for(i=0;i<RAYDIUM_MAX_TEXTURES;i++) // reset all textures
{
raydium_texture_name[i][0]=0;
raydium_texture_blended[i]=0;
raydium_texture_nolight[i]=0;
raydium_texture_env[i]=0;
raydium_texture_islightmap[i]=0;
raydium_texture_shader[i]=-1;
raydium_texture_rgb[0][i]=-1.f;
raydium_texture_rgb[1][i]=-1.f;
raydium_texture_rgb[2][i]=-1.f;
raydium_texture_rgb[3][i]=1.f;
}
raydium_hdr_texture_reset();
raydium_vertex_index=0;
raydium_vertex_offset_triangle=0;
strcpy(raydium_texture_name[0],"dummy.null");
raydium_texture_index=1; // no more texture loaded (0 is not a texture)
raydium_texture_current_main=0; // sets an "invalid" current texture
raydium_texture_current_multi=0; // sets an "invalid" current texture
raydium_texture_current_multi_u=0;
raydium_texture_current_multi_v=0;
raydium_texture_current_env=0; // sets an "invalid" current texture
raydium_texture_to_replace=0; // No texture to erase.. just load it :)
raydium_texture_used_memory=0;
//raydium_texture_filter=RAYDIUM_TEXTURE_FILTER_NONE;
raydium_texture_filter_change(RAYDIUM_TEXTURE_FILTER_NONE);
raydium_rendering_rgb_normal();
raydium_rendering_displaylists_enable();
raydium_render_rgb_force_tag=0;
raydium_render_lightmap_color_value[0]=1;
raydium_render_lightmap_color_value[1]=1;
raydium_render_lightmap_color_value[2]=1;
raydium_render_lightmap_color_value[3]=1;
raydium_render_internal_light_previous_step=-1;
raydium_vertex_counter=0;
raydium_projection=RAYDIUM_PROJECTION_PERSPECTIVE;
raydium_projection_fov=60;
raydium_projection_near=1;
raydium_projection_far=1000;
raydium_projection_left=0;
raydium_projection_right=0;
raydium_projection_bottom=0;
raydium_projection_top=0;
raydium_camera_pushed=0;
raydium_camera_look_at_roll=0;
raydium_camera_path_reset_flag=1;
raydium_camera_rumble_amplitude=0;
raydium_camera_rumble_evolution=0;
raydium_camera_rumble_remaining=0;
raydium_window_view_update();
raydium_internal_vertex_next_extras=0;
raydium_sky_force=0;
raydium_osd_logo_angle=0;
raydium_osd_cursor_texture=0;
raydium_register_variable_index=0;
raydium_register_function_index=0;
raydium_file_log_fopen_index=0;
raydium_frame_time=0;
raydium_capture_asked=RAYDIUM_CAPTURE_NONE;
for(i=0;i<4;i++)
raydium_osd_color[i]=1.f;
raydium_background_color_change(1,1,1,1);
glEnable(GL_TEXTURE_2D);
glEnable(GL_DEPTH_TEST);
glEnable(GL_COLOR_MATERIAL);
glShadeModel(GL_SMOOTH);
glDepthFunc(GL_LEQUAL); // LESS only ? shadow maps loves lequal, so ..
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
raydium_light_enable();
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE); // mmmmm...
glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
raydium_log("Raydium engine reseted to original state");
}
void raydium_init_engine(void)
{
GLenum err;
#ifdef PHP_SUPPORT
char autoexec[RAYDIUM_MAX_NAME_LEN];
#endif
raydium_signal_install_trap();
err=glewInit();
if(err==GLEW_OK)
raydium_log("OpenGL extensions: OK");
else
raydium_log("OpenGL extensions: FAILED");
raydium_internal_size_vector_float_4=sizeof(GLfloat)*4;
raydium_log("Platform \"4xfloat\" vector size is: %i byte(s) long",raydium_internal_size_vector_float_4);
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &raydium_texture_size_max);
raydium_log("OpenGL implementation maximum texture size: %ix%i",raydium_texture_size_max,raydium_texture_size_max);
glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &raydium_texture_units);
raydium_log("OpenGL hardware providing %i texture unit(s)",raydium_texture_units);
raydium_vertex_x=malloc(RAYDIUM_MAX_VERTICES*sizeof(GLfloat));
raydium_vertex_y=malloc(RAYDIUM_MAX_VERTICES*sizeof(GLfloat));
raydium_vertex_z=malloc(RAYDIUM_MAX_VERTICES*sizeof(GLfloat));
raydium_vertex_normal_x=malloc(RAYDIUM_MAX_VERTICES*sizeof(GLfloat));
raydium_vertex_normal_y=malloc(RAYDIUM_MAX_VERTICES*sizeof(GLfloat));
raydium_vertex_normal_z=malloc(RAYDIUM_MAX_VERTICES*sizeof(GLfloat));
raydium_vertex_normal_visu_x=malloc(RAYDIUM_MAX_VERTICES*sizeof(GLfloat));
raydium_vertex_normal_visu_y=malloc(RAYDIUM_MAX_VERTICES*sizeof(GLfloat));
raydium_vertex_normal_visu_z=malloc(RAYDIUM_MAX_VERTICES*sizeof(GLfloat));
raydium_vertex_texture_u=malloc(RAYDIUM_MAX_VERTICES*sizeof(GLfloat));
raydium_vertex_texture_v=malloc(RAYDIUM_MAX_VERTICES*sizeof(GLfloat));
raydium_vertex_texture=malloc(RAYDIUM_MAX_VERTICES*sizeof(GLuint));
raydium_vertex_texture_multi=malloc(RAYDIUM_MAX_VERTICES*sizeof(GLuint));
raydium_vertex_texture_multi_u=malloc(RAYDIUM_MAX_VERTICES*sizeof(GLfloat));
raydium_vertex_texture_multi_v=malloc(RAYDIUM_MAX_VERTICES*sizeof(GLfloat));
raydium_vertex_texture_env=malloc(RAYDIUM_MAX_VERTICES*sizeof(GLuint));
raydium_vertex_tag=malloc(RAYDIUM_MAX_VERTICES);
// must test more than just the last "big" malloc result..
if(!raydium_vertex_texture) { raydium_log("Out of memory..."); exit(29); }
raydium_log("vertex arrays memory: OK");
raydium_path_init(); // do this ASAP, before any file is opened
raydium_random_randomize();
raydium_init_key();
raydium_mouse_init();
raydium_joy_init(); // and not init_joy, since defined in joy.c, not init.c
raydium_sound=0;
raydium_sound_init();
raydium_callback_set();
#ifdef PHP_SUPPORT
raydium_php_init();
#endif
raydium_atexit(raydium_sound_close);
raydium_atexit(raydium_joy_close);
raydium_atexit(raydium_network_close);
raydium_atexit(raydium_internal_dump);
raydium_atexit(raydium_console_history_save);
#ifndef WIN32
raydium_atexit(raydium_internal_live_close);
#endif
raydium_log("atexit functions: OK");
raydium_init_reset();
#ifdef ODE_SUPPORT
raydium_ode_init();
#endif
raydium_register_api();
raydium_log("Engine is now ready.\n\t -----------------------------------------------------------");
#ifdef PHP_SUPPORT
if(raydium_init_cli_option("autoexec",autoexec))
raydium_php_exec(autoexec);
#endif
}

75
raydium/internal.c Normal file
View File

@ -0,0 +1,75 @@
/*
Raydium - CQFD Corp.
http://raydium.org/
License: GPL - GNU General Public License, see "gpl.txt" file.
*/
#ifndef DONT_INCLUDE_HEADERS
#include "index.h"
#else
#include "headers/internal.h"
#endif
void raydium_file_log_fopen_display(void);
void raydium_network_internal_dump(void);
void raydium_internal_dump(void)
{
GLuint i,j,a;
if(raydium_init_cli_option("regs",NULL))
raydium_register_dump();
raydium_log("Internal buffers:");
raydium_log("-----------------");
raydium_log("Total of %i vertex(s) loaded:",raydium_vertex_index);
for(i=0;i<raydium_texture_index;i++)
{
for(j=0,a=0;j<raydium_vertex_index;j++)
if(raydium_vertex_texture[j]==i) a++;
raydium_log("Texture num %i: %i vertex(s) - loaded as \"%s\"",i,a,raydium_texture_name[i]);
}
raydium_log("Estimated total: %.2f MB used for textures.",raydium_texture_used_memory/1024.f/1024.f);
raydium_log("Using %i object(s):",raydium_object_index);
for(i=0;i<raydium_object_index;i++)
{
a=raydium_object_end[i]-raydium_object_start[i];
raydium_log("Object num %i: %i vertex(s) - loaded as \"%s\"",i,a,raydium_object_name[i]);
}
if(raydium_network_mode!=RAYDIUM_NETWORK_MODE_NONE)
raydium_network_internal_dump();
if(raydium_init_cli_option("files",NULL)) raydium_file_log_fopen_display();
// raydium_log(".end of dump");
}
// 0 : Projection
// 1 : Model
void raydium_internal_dump_matrix(int n)
{
GLfloat tmp[16];
char str[80];
char str2[80];
int i,j;
if(n==0) glGetFloatv(GL_PROJECTION_MATRIX,tmp);
if(n==1) glGetFloatv(GL_MODELVIEW_MATRIX,tmp);
raydium_log("Matrix [4x4] :");
str[0]=0;
for(i=j=0;i<16;i++,j++)
{
sprintf(str2,"| % 10.2f ",tmp[i]);
strcat(str,str2);
if(j>=3)
{
j=-1;
raydium_log("%s",str);
str[0]=0;
}
}
raydium_log(".end");
}

371
raydium/joy.c Normal file
View File

@ -0,0 +1,371 @@
/*
Raydium - CQFD Corp.
http://raydium.org/
License: GPL - GNU General Public License, see "gpl.txt" file.
*/
#ifndef DONT_INCLUDE_HEADERS
#include "index.h"
#else
#include "headers/joy.h"
#endif
// proto
int raydium_init_cli_option_default(char *option, char *value, char *default_value);
// This file needs a lot of work, again ...
// (will use Glut for windows joy support soon ...)
//#define joy_debug 1 //do we display debug infos ?
#define JS_EVENT_BUTTON 0x01 /* button pressed/released */
#define JS_EVENT_AXIS 0x02 /* joystick moved */
#define JS_EVENT_INIT 0x80 /* initial state of device */
/*
// function 3rd arg
#define JSIOCGAXES // get number of axes char
#define JSIOCGBUTTONS // get number of buttons char
#define JSIOCGVERSION // get driver version int
#define JSIOCGNAME(len) // get identifier string char
#define JSIOCSCORR // set correction values &js_corr
#define JSIOCGCORR // get correction values &js_corr
*/
//int joy; //file handle
//struct input_event play;
//struct input_event stop;
//struct ff_effect effect;
int raydium_joy_event_handle;
#ifndef WIN32
struct ff_effect effect_tremble;
#endif
char effect_tremble_state=0;
clock_t last_event;
void raydium_joy_init_vars(void)
{
memset(raydium_joy_button,0,RAYDIUM_JOY_MAX_BUTTONS);
raydium_joy_x=raydium_joy_y=raydium_joy_z=0.f;
raydium_joy_click=0;
}
void raydium_joy_key_emul(void)
{
if(raydium_joy) return;
if(raydium_key[GLUT_KEY_UP]) raydium_joy_y=1.f;
if(raydium_key[GLUT_KEY_DOWN]) raydium_joy_y=-1.f;
if(raydium_key[GLUT_KEY_LEFT]) raydium_joy_x=-1.f;
if(raydium_key[GLUT_KEY_RIGHT]) raydium_joy_x=1.f;
//buttons
}
#ifndef WIN32
int raydium_joy_process_event(struct js_event e)
{
switch(e.type)
{
case JS_EVENT_BUTTON:
if(e.number<RAYDIUM_JOY_MAX_BUTTONS)
{
if(e.value==1)
{
raydium_joy_click=e.number+1;
raydium_joy_button[e.number]=e.value;
#ifdef joy_debug
raydium_log("Button %d pushed",e.number);
#endif
}
else
{
// release
raydium_joy_button[e.number]=e.value;
}
}
break;
case JS_EVENT_AXIS:
if(e.number<RAYDIUM_JOY_MAX_AXIS)
{
#ifdef joy_debug
raydium_log("Axis Moved: %i",e.value);
#endif
raydium_joy_axis[e.number]=e.value/(float)32767;
//here we invert values from the y axis: we want
//1 for up and -1 for down
if(e.value<0)
{
#ifdef joy_debug
if(e.number==1)raydium_log("Up");
if(e.number==0)raydium_log("Left");
#endif
if(e.number==2)
{
raydium_joy_z=e.value/(float)32767*-1;
}
if(e.number==1)
{
raydium_joy_y=e.value/(float)32767*-1;
}
if(e.number==0)
{
raydium_joy_x=e.value/(float)32767;
}
}
if(e.value>0)
{
#ifdef joy_debug
if(e.number==1)raydium_log("Down");
if(e.number==0)raydium_log("Right");
#endif
if(e.number==2)
{
raydium_joy_z=e.value/(float)32767*-1;
}
if(e.number==1)
{
raydium_joy_y=e.value/(float)32767*-1;
}
if(e.number==0)
{
raydium_joy_x=e.value/(float)32767;
}
}
if(e.value==0)
{
if(e.number==1)
{
raydium_joy_y=0.0;
}
if(e.number==0)
{
raydium_joy_x=0.0;
}
}
}
break;
case JS_EVENT_INIT:
//raydium_log("Joystick returned its initial state\n");
break;
}
return(e.type);
}
#endif
void raydium_joy_callback(void)
{
#ifndef WIN32
struct js_event e; //structure for storing an event
if(!raydium_joy) { raydium_joy_init_vars(); return; }
raydium_joy_click=0;
while (read (raydium_joy, &e, sizeof(struct js_event)) > 0)
{
raydium_joy_process_event (e);
//raydium_log("joy_DEBUG number:%d, value:%d",e.number,e.value);
}
#else
raydium_joy_init_vars();
#endif
}
void raydium_joy_ff_autocenter(int perc)
{
#ifndef WIN32
struct input_event ie;
if(raydium_joy_event_handle<0) return;
ie.type = EV_FF;
ie.code = FF_AUTOCENTER;
ie.value = 0xFFFFUL * perc / 100;
if (write(raydium_joy_event_handle, &ie, sizeof(ie)) == -1)
perror("set auto-center");
#endif
}
void raydium_joy_init(void)
{
int ret; //test var for ioctls
char name[128]; //driver String (and temp things)
int autocenter=5; /* default value. between 0 and 100 */
raydium_joy_init_vars();
#ifndef WIN32
if(raydium_init_cli_option_default("joydev",name,"/dev/js0"))
raydium_joy=open(name,O_RDONLY|O_NONBLOCK);
else
{
raydium_joy=open("/dev/js0",O_RDONLY|O_NONBLOCK);
if(raydium_joy==-1)
raydium_joy=open("/dev/input/js0",O_RDONLY|O_NONBLOCK);
}
raydium_init_cli_option_default("evdev",name,"/dev/input/event0");
raydium_joy_event_handle = open(name, O_RDWR);
if(raydium_joy_event_handle==-1)
raydium_log("%s: cannot open (rw), no Force Feedback.",name);
last_event=clock();
raydium_joy_ff_autocenter(autocenter);
if(raydium_joy==-1)
{
raydium_log("joy: FAILED (cannot open /dev/js0 and /dev/input/js0)");
raydium_joy=0;
}
else
{
raydium_log("joy: OK (found)");
}
if(raydium_joy)
{
ret=ioctl (raydium_joy,JSIOCGNAME(sizeof(name)),name);
if(ret==-1)
{
raydium_log("Error reading joystick driver's signature");
strncpy(name,"Unknown",sizeof(name));
}
else
{
raydium_log("Joystick driver's signature: %s",name);
}
ret=ioctl (raydium_joy,JSIOCGAXES,&raydium_joy_n_axes);
if(ret==-1)
{
raydium_log("Error reading number of axes");
}
else
{
raydium_log("This joystick has %d axes",raydium_joy_n_axes);
}
ret=ioctl (raydium_joy,JSIOCGBUTTONS,&raydium_joy_n_buttons);
if(ret==-1)
{
raydium_log("Error reading number of buttons");
}
else
{
raydium_log("This joystick has %d buttons",raydium_joy_n_buttons);
}
}
#else
raydium_log("joy: FAILED\n\t No Joy support under Win32 yet");
#endif
}
void raydium_joy_close(void)
{
if(raydium_joy) close(raydium_joy);
}
void raydium_joy_ff(void)
{
//memset(&effect,0,sizeof(struct ff_effect));
// effect.type=FF_CONSTANT;
// effect.u.constant.level=0xEFF0;
// effect.u.constant.direction=0x2000;
// effect.replay.length=65535;
// effect.u.constant.shape.attack_length=40000;
// effect.u.constant.shape.attack_level=0x8888;
// effect.u.constant.shape.fade_length=20000;
// effect.u.constant.shape.fade_level=0x2222;
/* effect.type = FF_SPRING;
effect.u.interactive.direction=0x4000;
effect.u.interactive.right_saturation = 32767;
effect.u.interactive.left_saturation = 32767;
effect.u.interactive.right_coeff = 32767;
effect.u.interactive.left_coeff = 32767;
effect.u.interactive.deadband = 0x0;
effect.u.interactive.center = 0x0;*/
// effect.type = FF_PERIODIC;
/*
#define FF_SQUARE 0x58
#define FF_TRIANGLE 0x59
#define FF_SINE 0x5a
#define FF_SAW_UP 0x5b
#define FF_SAW_DOWN 0x5c
#define FF_CUSTOM 0x5d
*/
/* effect.u.periodic.waveform=FF_TRIANGLE;
effect.u.periodic.period=50;
effect.u.periodic.magnitude=16000;
effect.u.periodic.direction=0x4000;*/
// raydium_log("upload effect valeur=%d", ioctl(fd, EVIOCSFF, &effect));
// perror("merde:");
// play.type = EV_FF;
// play.code = effect.id;
//raydium_log("effect_id=%d",effect.id);
// play.value = 10000;
// write(fd, (const void*) &play, sizeof(play));
/* stop.type = EV_FF;
stop.code = effect.id;
stop.value = 0;
write(fd, (const void*) &play, sizeof(stop));*/
//raydium_log("remove effectvaleur=%d", ioctl(fd, EVIOCRMFF, effect.id));
}
void raydium_joy_ff_tremble_set(GLfloat period, GLfloat force)
{
#ifndef WIN32
struct input_event play;
struct input_event stop;
if (clock() < last_event + CLOCKS_PER_SEC/10)
return;
if(effect_tremble_state)
{
stop.type = EV_FF;
stop.code = effect_tremble.id;
stop.value = 0;
write(raydium_joy_event_handle, (const void*) &stop, sizeof(stop));
// perror("ff: stop tremble");
ioctl(raydium_joy_event_handle, EVIOCRMFF, effect_tremble.id);
// perror("ff: free tremble");
}
memset(&effect_tremble,0,sizeof(struct ff_effect));
effect_tremble.type = FF_PERIODIC;
effect_tremble.u.periodic.waveform=FF_TRIANGLE;
effect_tremble.u.periodic.period=period;
effect_tremble.u.periodic.magnitude=force;
//effect_tremble.u.periodic.direction=0x4000; // NEED SOME WORK HERE !!
effect_tremble.replay.length=65535;
ioctl(raydium_joy_event_handle, EVIOCSFF, &effect_tremble);
//perror("ff: upload tremble");
play.type = EV_FF;
play.code = effect_tremble.id;
play.value = 1;
write(raydium_joy_event_handle, (const void*) &play, sizeof(play));
//perror("ff: play tremble");
effect_tremble_state=1;
last_event=clock();
//printf("ff event refreshed\n");
#endif
}

119
raydium/key.c Normal file
View File

@ -0,0 +1,119 @@
/*
Raydium - CQFD Corp.
http://raydium.org/
License: GPL - GNU General Public License, see "gpl.txt" file.
*/
#ifndef DONT_INCLUDE_HEADERS
#include "index.h"
#else
#include "headers/key.h"
#endif
// proto
void raydium_console_event(void);
void raydium_console_line_add(char *format, ...);
void raydium_console_exec_last_command(void);
void raydium_console_complete(char *str);
void raydium_console_history_previous(void);
void raydium_console_history_next(void);
void raydium_key_normal_callback(GLuint key, int x, int y)
{
int i;
key%=65536;
// key below esc :
// 178 (ex: fr), 176 (ex: us), 186 (ex: spa)
if(key==178 || key==176 || key==186) raydium_console_event();
if(key==126) raydium_capture_frame_auto(); // glut@w32 won't return this key...
if(raydium_console_pos && ( (key>=32 && key<127)
|| key==8
|| key==9
|| key==13) )
{
i=strlen(raydium_console_get_string);
// printf("%s\n",raydium_console_get_string);
if(key==13)
{
if(!i) return;
raydium_console_get_string[i]=key; // lag from last frame...
raydium_console_get_string[i+1]=0;
// there is a bug: raydium_console_get_string '\n' is cleaned, but
// after being copied into raydium_console_get_string_last.
// Must take some time to clean all this (key, console, test4 and modler)
strcpy(raydium_console_get_string_last,raydium_console_get_string);
raydium_console_get_string[i]=0;
raydium_console_line_add("%s",raydium_console_get_string);
raydium_console_get_string[0]=0;
raydium_console_exec_last_command();
return;
}
if(key==8) // delete last char
{
if(i>0) i--;
key=0;
}
if(key==9) // completion
{
raydium_console_complete(raydium_console_get_string);
return;
}
if(i<RAYDIUM_MAX_NAME_LEN-3)
{
raydium_console_get_string[i]=key;
raydium_console_get_string[i+1]=0;
raydium_console_cursor_blink=1;
}
}
else
{
raydium_key_last=key+1000;
if(raydium_key_trace)
raydium_log("normal key %i pressed",key+1000);
}
}
void raydium_key_special_callback(GLuint key, int x, int y)
{
if(raydium_console_pos && key==GLUT_KEY_UP)
{
raydium_console_history_previous();
return;
}
if(raydium_console_pos && key==GLUT_KEY_DOWN)
{
raydium_console_history_next();
return;
}
key%=65536;
raydium_key[key]=2;
raydium_key_last=key;
if(raydium_key_trace)
raydium_log("special key %i down (normal key updated too)",key);
}
void raydium_key_special_up_callback(GLuint key, int x, int y)
{
key%=65536;
raydium_key[key]=0;
if(raydium_key_trace)
raydium_log("special key %i up",key);
}
// moslty used for php
int raydium_key_pressed(GLuint key)
{
return raydium_key[key];
}

131
raydium/land.c Normal file
View File

@ -0,0 +1,131 @@
/*
Raydium - CQFD Corp.
http://raydium.org/
License: GPL - GNU General Public License, see "gpl.txt" file.
*/
#ifndef DONT_INCLUDE_HEADERS
#include "index.h"
#else
#include "headers/land.h"
#endif
// mostly unusable functions (old Raydium's core) ...
GLfloat raydium_land_internal_landtmp(GLfloat x,GLfloat y,GLfloat phase,GLfloat ampl, GLfloat periode)
{
GLfloat a,b;
a=(x/periode)*360;
b=(y/periode)*360;
a+=phase;
b+=phase;
while(a>=360) a-=360;
while(b>=360) b-=360;
a=raydium_trigo_cos(a);
b=raydium_trigo_cos(b);
b=b*a;
b*=ampl;
return(b);
}
// must recode all this function
void raydium_land_draw_water(GLfloat phase, GLfloat ampl, GLfloat periode,
int sub, GLfloat pas, char *texture)
{
int ix,iy;
//GLfloat pas;
//GLfloat wpas,border,dep=0;
GLfloat x1,x2,y1,y2;
GLuint vertex_index_save;
//pas=(SUBDIV*FACT)/sub;
raydium_texture_current_set_name(texture);
vertex_index_save=raydium_vertex_index;
// angle=(x*ampl)/360
for(iy=0;iy<sub;iy++)
for(ix=0;ix<sub;ix++)
{
x1=(GLfloat)(ix)*pas;
x2=(GLfloat)(ix+1)*pas;
y1=(GLfloat)(iy)*pas;
y2=(GLfloat)(iy+1)*pas;
//#define FACTW (FACT/2)
#define FACTW 10
raydium_vertex_uv_add(x1,y1, raydium_land_internal_landtmp(x1,y1,phase,ampl,periode), 0,0);
raydium_vertex_uv_add(x2,y1, raydium_land_internal_landtmp(x2,y1,phase,ampl,periode), FACTW,0);
raydium_vertex_uv_add(x2,y2, raydium_land_internal_landtmp(x2,y2,phase,ampl,periode), FACTW,FACTW);
raydium_vertex_uv_add(x2,y2, raydium_land_internal_landtmp(x2,y2,phase,ampl,periode), FACTW,FACTW);
raydium_vertex_uv_add(x1,y2, raydium_land_internal_landtmp(x1,y2,phase,ampl,periode), 0,FACTW);
raydium_vertex_uv_add(x1,y1, raydium_land_internal_landtmp(x1,y1,phase,ampl,periode), 0,0);
}
/*
// expand water space
#define EXPAND 5000.f
#define EX_Z (-ampl)
border=SUBDIV*FACT;
raydium_vertex_uv_add(0,-EXPAND,EX_Z, 0,0);
raydium_vertex_uv_add(0,border+EXPAND,EX_Z, 0,(EXPAND*2+border)/FACT);
raydium_vertex_uv_add(-EXPAND,border+EXPAND,EX_Z, -EXPAND/FACT,(EXPAND*2+border)/FACT);
*/
raydium_rendering_from_to(vertex_index_save,raydium_vertex_index);
raydium_vertex_index=vertex_index_save;
}
// unsable
GLfloat raydium_land_surface(GLfloat x, GLfloat y, GLfloat *nx, GLfloat *ny, GLfloat *nz)
{
//int cx,cy;
GLint n;
GLfloat dx,dy;
GLfloat a,b,c,d;
//cx=x/FACT;
//cy=y/FACT;
//n=((cx*(SUBDIV-1))+cy)*6;
//dy=x-(float)(cx*FACT);
//dx=y-(float)(cy*FACT);
if(dy>=dx) n+=3;
#define Ax raydium_vertex_x[n]
#define Bx raydium_vertex_x[n+1]
#define Cx raydium_vertex_x[n+2]
#define Ay raydium_vertex_y[n]
#define By raydium_vertex_y[n+1]
#define Cy raydium_vertex_y[n+2]
#define Az raydium_vertex_z[n]
#define Bz raydium_vertex_z[n+1]
#define Cz raydium_vertex_z[n+2]
a = ((Az - Bz) * (Ay - Cy)) + ((Az - Cz) * (By - Ay));
b = ((Ax - Bx) * (Az - Cz)) + ((Ax - Cx) * (Bz - Az));
c = ((Bx - Ax) * (Ay - Cy)) + ((Ax - Cx) * (Ay - By));
d = - a*Ax - b*Ay - c*Az;
*nx=raydium_vertex_normal_x[n];
*ny=raydium_vertex_normal_y[n];
*nz=raydium_vertex_normal_z[n];
return(-(a*y+b*x+d)/c);
}

188
raydium/light.c Normal file
View File

@ -0,0 +1,188 @@
/*
Raydium - CQFD Corp.
http://raydium.org/
License: GPL - GNU General Public License, see "gpl.txt" file.
*/
#ifndef DONT_INCLUDE_HEADERS
#include "index.h"
#else
#include "headers/light.h"
#endif
GLuint raydium_texture_find_by_name(char *name);
void raydium_light_enable(void)
{
glEnable(GL_LIGHTING);
raydium_light_enabled_tag=1;
}
void raydium_light_disable(void)
{
glDisable(GL_LIGHTING);
raydium_light_enabled_tag=0;
}
GLuint raydium_light_to_GL_light(GLuint l)
{
return GL_LIGHT0+l;
}
void raydium_light_on(GLuint l)
{
raydium_light_internal_state[l]=RAYDIUM_LIGHT_ON;
glEnable(raydium_light_to_GL_light(l));
}
void raydium_light_off(GLuint l)
{
raydium_light_internal_state[l]=RAYDIUM_LIGHT_OFF;
glDisable(raydium_light_to_GL_light(l));
}
void raydium_light_switch(GLuint l)
{
if(raydium_light_internal_state[l]<0)
raydium_light_on(l);
else
raydium_light_off(l);
}
void raydium_light_update_position(GLuint l)
{
glLightfv(raydium_light_to_GL_light(l),GL_POSITION,raydium_light_position[l]);
}
void raydium_light_update_position_all(void)
{
int i;
for(i=0;i<RAYDIUM_MAX_LIGHTS;i++)
if(raydium_light_internal_state[i]!=RAYDIUM_LIGHT_OFF)
raydium_light_update_position(i);
}
void raydium_light_update_intensity(GLuint l)
{
glLightf(raydium_light_to_GL_light(l),GL_QUADRATIC_ATTENUATION,1.0/raydium_light_intensity[l]);
}
void raydium_light_update_all(GLuint l)
{
GLuint GLl=raydium_light_to_GL_light(l);
//GLfloat zero[4]={0.0,0.0,0.0,1.0};
//GLfloat one[4]={0.3,0.3,0.3,1.};
//glLightfv(GLl,GL_AMBIENT, /*raydium_light_color[l]*//*zero*/one);
glLightfv(GLl,GL_DIFFUSE, raydium_light_color[l]);
glLightfv(GLl,GL_SPECULAR,raydium_light_color[l]);
raydium_light_update_intensity(l);
raydium_light_update_position(l);
}
signed char raydium_light_texture(int texture, signed char enable)
{
if(texture>=0 && texture<raydium_texture_index)
{
raydium_texture_nolight[texture]=!enable;
return 1;
}
raydium_log("light: cannot set 'no light' attribute on texture: invalid name or index");
return 0;
}
signed char raydium_light_texture_name(char *name, signed char enable)
{
return raydium_light_texture(raydium_texture_find_by_name(name),enable);
}
void raydium_light_move(GLuint l,GLfloat *vect)
{
memcpy(raydium_light_position[l],vect,raydium_internal_size_vector_float_4);
//raydium_light_update_position(l);
}
void raydium_light_move_3f(GLuint l,GLfloat px, GLfloat py, GLfloat pz)
{
GLfloat pos[4];
pos[0]=px;
pos[1]=py;
pos[2]=pz;
pos[3]=0;
raydium_light_move(l,pos);
}
void raydium_light_conf_7f(GLuint l,GLfloat px, GLfloat py, GLfloat pz, GLfloat intensity, GLfloat r, GLfloat g, GLfloat b)
{
raydium_light_intensity[l]=intensity;
raydium_light_color[l][0]=r;
raydium_light_color[l][1]=g;
raydium_light_color[l][2]=b;
raydium_light_color[l][3]=1.0;
raydium_light_move_3f(l,px,py,pz);
raydium_light_update_all(l);
}
void raydium_light_reset(GLuint l)
{
GLfloat pos[]={0,0,0,1};
GLfloat color[]={1.0, 1.0, 1.0, 1.0};
GLfloat intensity=10000000;
memcpy(raydium_light_position[l],pos,raydium_internal_size_vector_float_4);
memcpy(raydium_light_color[l],color,raydium_internal_size_vector_float_4);
raydium_light_intensity[l]=intensity;
raydium_light_off(l);
raydium_light_update_all(l);
}
void raydium_light_blink_internal_update(GLuint l)
{
raydium_light_intensity[l]+=raydium_light_blink_increment[l];
if(raydium_light_intensity[l]>raydium_light_blink_high[l])
{
raydium_light_intensity[l]=raydium_light_blink_high[l];
raydium_light_blink_increment[l]*=-1.0;
}
if(raydium_light_intensity[l]<raydium_light_blink_low[l])
{
raydium_light_intensity[l]=raydium_light_blink_low[l];
raydium_light_blink_increment[l]*=-1.0;
}
raydium_light_update_intensity(l);
}
void raydium_light_blink_start(GLuint l,int fpc)
{
raydium_light_on(l);
raydium_light_internal_state[l]=RAYDIUM_LIGHT_BLINKING;
//fpc = frames per cycle
fpc/=2;
raydium_light_blink_low[l]=raydium_light_intensity[l]/fpc;
raydium_light_blink_high[l]=raydium_light_intensity[l];
raydium_light_blink_increment[l]=raydium_light_intensity[l]/fpc;
raydium_light_blink_internal_update(l);
}
void raydium_light_callback(void)
{
GLuint i;
for(i=0;i<RAYDIUM_MAX_LIGHTS;i++)
if(raydium_light_internal_state[i]==RAYDIUM_LIGHT_BLINKING)
raydium_light_blink_internal_update(i);
}

796
raydium/live.c Normal file
View File

@ -0,0 +1,796 @@
/*
Raydium - CQFD Corp.
http://raydium.org/
License: GPL - GNU General Public License, see "gpl.txt" file.
*/
#ifndef DONT_INCLUDE_HEADERS
#include "index.h"
#else
#include "headers/live.h"
#endif
#include "live.h"
// YUV420P to RGB code (next 2 functions) from:
// Peopletracking with an omnicamera
// Daniel Hammarin & Mihajlo Miladinovic
// !! Since this code is not native, no "raydium_" prefix is used !!
/* LIMIT: convert a 16.16 fixed-point value to a byte, with clipping. */
#define LIMIT(x) ((x)>0xffffff?0xff: ((x)<=0xffff?0:((x)>>16)))
void
v4l_copy_420_block (int yTL, int yTR, int yBL, int yBR,
int u, int v, int rowPixels, unsigned char *rgb, int bits)
{
const int rvScale = 91881;
const int guScale = -22553;
const int gvScale = -46801;
const int buScale = 116129;
const int yScale = 65536;
int r, g, b;
g = guScale * u + gvScale * v;
b = rvScale * v;
r = buScale * u;
yTL *= yScale;
yTR *= yScale;
yBL *= yScale;
yBR *= yScale;
if (bits == 24)
{
/* Write out top two pixels */
rgb[0] = LIMIT (b + yTL);
rgb[1] = LIMIT (g + yTL);
rgb[2] = LIMIT (r + yTL);
rgb[3] = LIMIT (b + yTR);
rgb[4] = LIMIT (g + yTR);
rgb[5] = LIMIT (r + yTR);
/* Skip down to next line to write out bottom two pixels */
rgb += 3 * rowPixels;
rgb[0] = LIMIT (b + yBL);
rgb[1] = LIMIT (g + yBL);
rgb[2] = LIMIT (r + yBL);
rgb[3] = LIMIT (b + yBR);
rgb[4] = LIMIT (g + yBR);
rgb[5] = LIMIT (r + yBR);
}
else if (bits == 16)
{
/* Write out top two pixels */
rgb[0] =
((LIMIT (b + yTL) >> 3) & 0x1F) | ((LIMIT (g + yTL) << 3) & 0xE0);
rgb[1] = ((LIMIT (g + yTL) >> 5) & 0x07) | (LIMIT (r + yTL) & 0xF8);
rgb[2] =
((LIMIT (b + yTR) >> 3) & 0x1F) | ((LIMIT (g + yTR) << 3) & 0xE0);
rgb[3] = ((LIMIT (g + yTR) >> 5) & 0x07) | (LIMIT (r + yTR) & 0xF8);
/* Skip down to next line to write out bottom two pixels */
rgb += 2 * rowPixels;
rgb[0] =
((LIMIT (b + yBL) >> 3) & 0x1F) | ((LIMIT (g + yBL) << 3) & 0xE0);
rgb[1] = ((LIMIT (g + yBL) >> 5) & 0x07) | (LIMIT (r + yBL) & 0xF8);
rgb[2] =
((LIMIT (b + yBR) >> 3) & 0x1F) | ((LIMIT (g + yBR) << 3) & 0xE0);
rgb[3] = ((LIMIT (g + yBR) >> 5) & 0x07) | (LIMIT (r + yBR) & 0xF8);
}
}
int
v4l_yuv420p2rgb (unsigned char *rgb_out, unsigned char *yuv_in, int width, int
height, int bits)
{
const int numpix = width * height;
const unsigned int bytes = bits >> 3;
int h, w, y00, y01, y10, y11, u, v;
unsigned char *pY = yuv_in;
unsigned char *pU = pY + numpix;
unsigned char *pV = pU + numpix / 4;
unsigned char *pOut = rgb_out;
if (!rgb_out || !yuv_in)
return -1;
for (h = 0; h <= height - 2; h += 2)
{
for (w = 0; w <= width - 2; w += 2)
{
y00 = *(pY);
y01 = *(pY + 1);
y10 = *(pY + width);
y11 = *(pY + width + 1);
u = (*pU++) - 128;
v = (*pV++) - 128;
v4l_copy_420_block (y00, y01, y10, y11, u, v, width, pOut, bits);
pY += 2;
pOut += bytes << 1;
}
pY += width;
pOut += width * bytes;
}
return 0;
}
/////// video (devices) part
signed char raydium_live_video_isvalid(int i)
{
if(i>=0 && i<RAYDIUM_MAX_VIDEO_DEVICES &&
raydium_live_device[i].capture_style!=RAYDIUM_LIVE_FREE)
return 1;
return 0;
}
int raydium_live_video_find_free(void)
{
int i;
for(i=0;i<RAYDIUM_MAX_VIDEO_DEVICES;i++)
if(raydium_live_device[i].capture_style==RAYDIUM_LIVE_FREE)
return i;
return -1;
}
int raydium_live_video_open(char *device, int sizex, int sizey)
{
#ifndef WIN32
char *default_device=RAYDIUM_LIVE_DEVICE_DEFAULT;
int id;
int capture_style = RAYDIUM_LIVE_FREE;
char palette[128];
raydium_live_Device *dev;
char force_read=0;
char cli_device[RAYDIUM_MAX_NAME_LEN];
strcpy(palette,"(none)");
if(!device)
{
raydium_init_cli_option_default("video-device",cli_device,default_device);
device=cli_device;
}
id=raydium_live_video_find_free();
if(id<0)
{
raydium_log("live: ERROR: no more free device slot available (max: %i)",RAYDIUM_MAX_VIDEO_DEVICES);
return -1;
}
dev=&raydium_live_device[id];
dev->fd=open(device, O_RDWR);
if (dev->fd<0)
{
perror("open");
raydium_log("live: ERROR: cannot open device '%s'",device);
return -1;
}
if (ioctl(dev->fd, VIDIOCGCAP, &dev->cap) < 0)
{
perror("VIDIOGCAP");
raydium_log("live: ERROR: not a video4linux device '%s'",device);
close(dev->fd);
return -1;
}
if (ioctl(dev->fd, VIDIOCGWIN, &dev->win) < 0)
{
perror("VIDIOCGWIN");
raydium_log("live: ERROR: early error");
close(dev->fd);
return -1;
}
if (ioctl(dev->fd, VIDIOCGPICT, &dev->vpic) < 0)
{
perror("VIDIOCGPICT");
raydium_log("live: ERROR: early error");
close(dev->fd);
return -1;
}
raydium_log("live: device '%s' (%s)",dev->cap.name,device);
raydium_log("live: min %ix%i, max %ix%i, default %ix%i",
dev->cap.minwidth,dev->cap.minheight,
dev->cap.maxwidth,dev->cap.maxheight,
dev->win.width,dev->win.height);
dev->win.x=0;
dev->win.y=0;
if(sizex<0 || sizey<0)
{
char s[RAYDIUM_MAX_NAME_LEN];
char sx[RAYDIUM_MAX_NAME_LEN];
char sy[RAYDIUM_MAX_NAME_LEN];
dev->win.width=RAYDIUM_LIVE_SIZEX_DEFAULT;
dev->win.height=RAYDIUM_LIVE_SIZEY_DEFAULT;
if(raydium_init_cli_option("video-size",s))
{
if(!raydium_parser_cut(s,sx,sy,'x'))
{
// apply to every video device ... :/
raydium_log("live: ERROR: --video-size format invalid (ex: 352x288)");
}
else
{
dev->win.width=atoi(sx);
dev->win.height=atoi(sy);
}
}
}
else
{
dev->win.width=sizex;
dev->win.height=sizey;
}
dev->win.flags=0;
dev->win.clips=NULL;
dev->win.clipcount=0;
dev->win.chromakey=0;
if (ioctl(dev->fd, VIDIOCSWIN, &dev->win) < 0)
{
perror("VIDIOCSWIN");
raydium_log("live: ERROR: video mode refused: %ix%i",dev->win.width,dev->win.height);
close(dev->fd);
return -1;
}
// read back
if (ioctl(dev->fd, VIDIOCGWIN, &dev->win) < 0)
{
perror("VIDIOCGWIN");
raydium_log("live: ERROR: cannot read back window settings. Should never happen.");
close(dev->fd);
return -1;
}
if (dev->cap.type & VID_TYPE_MONOCHROME)
{
dev->vpic.depth=8;
dev->vpic.palette=VIDEO_PALETTE_GREY; // 8bit grey
strcpy(palette,"grey, 8 bpp");
if(ioctl(dev->fd, VIDIOCSPICT, &dev->vpic) < 0)
{
strcpy(palette,"grey, 6 bpp");
dev->vpic.depth=6;
if(ioctl(dev->fd, VIDIOCSPICT, &dev->vpic) < 0)
{
strcpy(palette,"grey, 4 bpp");
dev->vpic.depth=4;
if(ioctl(dev->fd, VIDIOCSPICT, &dev->vpic) < 0)
{
raydium_log("live: ERROR: cannot found suitable grey palette");
close(dev->fd);
return -1;
}
}
}
}
else
{
strcpy(palette,"RGB, 24 bpp");
dev->vpic.depth=24;
dev->vpic.palette=VIDEO_PALETTE_RGB24;
if(ioctl(dev->fd, VIDIOCSPICT, &dev->vpic) < 0)
{
strcpy(palette,"RGB565, 16 bpp");
dev->vpic.palette=VIDEO_PALETTE_RGB565;
dev->vpic.depth=16;
if(ioctl(dev->fd, VIDIOCSPICT, &dev->vpic)==-1)
{
strcpy(palette,"RGB555, 15 bpp");
dev->vpic.palette=VIDEO_PALETTE_RGB555;
dev->vpic.depth=15;
if(ioctl(dev->fd, VIDIOCSPICT, &dev->vpic)==-1)
{
strcpy(palette,"YUV420P, 24 bpp");
dev->vpic.palette=VIDEO_PALETTE_YUV420P;
dev->vpic.depth=24;
if(ioctl(dev->fd, VIDIOCSPICT, &dev->vpic)==-1)
{
raydium_log("live: ERROR: cannot found suitable color palette");
close(dev->fd);
return -1;
}
}
}
}
}
dev->buffer2 = malloc(dev->win.width * dev->win.height * dev->vpic.depth);
if (!dev->buffer2)
{
raydium_log("live: ERROR: buffer2: out of memory (!?)");
close(dev->fd);
return -1;
}
do // just to allow break in this if :)
{
if(dev->cap.type & VID_TYPE_CAPTURE)
{
capture_style=RAYDIUM_LIVE_CAPTURE_MMAP;
if(ioctl(dev->fd,VIDIOCGMBUF,&dev->gb_buffers)==-1)
{
perror("VIDIOCGMBUF");
raydium_log("live: ERROR: hardware refuse our mmap capture style (but is claiming this feature ...)");
force_read=1;
break;
}
dev->buffer = mmap(0,dev->gb_buffers.size,PROT_READ|PROT_WRITE,MAP_SHARED,dev->fd,0);
if(dev->buffer==(void *) -1)
{
perror("mmap");
raydium_log("live: ERROR: mmap failed");
force_read=1;
break;
}
dev->gb_buf.frame=0;
dev->gb_buf.height = dev->win.height;
dev->gb_buf.width = dev->win.width;
dev->gb_buf.format = dev->vpic.palette;
if(ioctl(dev->fd, VIDIOCMCAPTURE, &dev->gb_buf)==-1)
{
perror("VIDIOCMCAPTURE");
raydium_log("live: ERROR: mmap capture test failed");
munmap(dev->buffer,dev->gb_buffers.size);
force_read=1;
break;
}
}
} while(0); // i'm not proud of this ... :)
if(force_read)
{
raydium_log("live: fallback to read method. MAY BE SLOW !");
}
if( (!(dev->cap.type & VID_TYPE_CAPTURE)) || force_read )
{
capture_style=RAYDIUM_LIVE_CAPTURE_READ;
dev->buffer = malloc(dev->win.width * dev->win.height * dev->vpic.depth);
if (!dev->buffer)
{
raydium_log("live: ERROR: buffer2: out of memory (!?)");
close(dev->fd);
return -1;
}
}
raydium_log("live: current: %ix%i, palette %s, %s",
dev->win.width,dev->win.height,palette,
(capture_style==RAYDIUM_LIVE_CAPTURE_READ?"read method":"mmap method") );
// reserve slot
dev->capture_style=capture_style;
strcpy(dev->name,device);
raydium_log("live: video init for this device is ok");
return id;
#else
raydium_log("live: Live API is not supported under win32 yet");
return -1;
#endif
}
int raydium_live_video_open_auto(void)
{
return raydium_live_video_open(RAYDIUM_LIVE_DEVICE_AUTO,RAYDIUM_LIVE_SIZE_AUTO,RAYDIUM_LIVE_SIZE_AUTO);
}
int raydium_live_video_read(raydium_live_Device *dev)
{
#ifndef WIN32
fd_set fds;
struct timeval tv;
int r;
if(dev->capture_style==RAYDIUM_LIVE_FREE)
{
raydium_log("live: ERROR: read failed: invalid device");
return -1;
}
// polling
FD_ZERO (&fds);
FD_SET (dev->fd, &fds);
tv.tv_sec=0;
tv.tv_usec=0;
r = select(dev->fd + 1, &fds, NULL, NULL, &tv);
// nothing to read, we'll try later (next frame)
if(r<=0)
return 0;
dev->src = dev->buffer;
if(dev->capture_style==RAYDIUM_LIVE_CAPTURE_READ)
{
read(dev->fd, dev->buffer, dev->win.width * dev->win.height * dev->vpic.depth);
}
else
{
dev->frame=dev->gb_buf.frame;
dev->gb_buf.height = dev->win.height;
dev->gb_buf.width = dev->win.width;
dev->gb_buf.format = dev->vpic.palette;
dev->gb_buf.frame=!dev->frame;
ioctl(dev->fd, VIDIOCMCAPTURE, &dev->gb_buf);
if(ioctl(dev->fd, VIDIOCSYNC, &dev->frame)==-1)
{
perror("mmap");
return 0;
}
dev->src+=dev->gb_buffers.offsets[dev->frame];
}
if(dev->vpic.palette==VIDEO_PALETTE_YUV420P)
{
// YUV420P style
v4l_yuv420p2rgb (dev->buffer2,dev->src,dev->win.width,dev->win.height,dev->vpic.depth);
}
else
{
// RGB style
int i,j;
int r,g,b;
for (i = j = 0; i < dev->win.width * dev->win.height; i++)
{
READ_VIDEO_PIXEL(dev->src, dev->vpic.palette, dev->vpic.depth, r, g, b);
dev->buffer2[j++]=b>>8;
dev->buffer2[j++]=g>>8;
dev->buffer2[j++]=r>>8;
}
}
return 1;
#endif
}
void raydium_internal_live_video_callback(void)
{
int i;
for(i=0;i<RAYDIUM_MAX_VIDEO_DEVICES;i++)
if(raydium_live_device[i].capture_style!=RAYDIUM_LIVE_FREE)
if(raydium_live_video_read(&raydium_live_device[i]))
raydium_live_texture_refresh(i);
}
/////////////// live API core
void raydium_internal_live_close(void)
{
int i;
for(i=0;i<RAYDIUM_MAX_VIDEO_DEVICES;i++)
if(raydium_live_device[i].capture_style!=RAYDIUM_LIVE_FREE)
{
#ifndef WIN32
munmap(raydium_live_device[i].buffer, raydium_live_device[i].gb_buffers.size);
close(raydium_live_device[i].fd);
#endif
}
}
void raydium_live_init(void)
{
int i;
for(i=0;i<RAYDIUM_MAX_VIDEO_DEVICES;i++)
{
raydium_live_device[i].capture_style=RAYDIUM_LIVE_FREE;
raydium_live_device[i].buffer=NULL;
raydium_live_device[i].frame=0;
}
for(i=0;i<RAYDIUM_MAX_LIVE_TEXTURES;i++)
{
raydium_live_texture[i].state=0;
raydium_live_texture[i].device=NULL;
raydium_live_texture[i].OnRefresh=NULL;
raydium_live_texture[i].data_source=NULL;
}
raydium_log("video (live): OK");
}
signed char raydium_live_texture_isvalid(int i)
{
if(i>=0 && i<RAYDIUM_MAX_LIVE_TEXTURES && raydium_live_texture[i].state)
return 1;
return 0;
}
int raydium_live_texture_find_free(void)
{
int i;
for(i=0;i<RAYDIUM_MAX_LIVE_TEXTURES;i++)
if(!raydium_live_texture[i].state)
return i;
return -1;
}
int raydium_live_texture_find(int original_texture)
{
int i;
for(i=0;i<RAYDIUM_MAX_LIVE_TEXTURES;i++)
if(raydium_live_texture[i].state &&
raydium_live_texture[i].texture==original_texture)
return i;
return -1;
}
int raydium_live_texture_video(int device_id, char *as)
{
#ifndef WIN32
int id;
raydium_live_Device *dev;
raydium_live_Texture *tex;
if(!raydium_live_video_isvalid(device_id))
{
raydium_log("live: ERROR: invalid device id, cannot create live source");
return -1;
}
dev=&raydium_live_device[device_id];
id=raydium_live_texture_find_free();
if(id<0)
{
raydium_log("live: ERROR: no more free live texture slot available (max: %i)",RAYDIUM_MAX_LIVE_TEXTURES);
return -1;
}
tex=&raydium_live_texture[id];
tex->tx=dev->win.width;
tex->ty=dev->win.height;
tex->hardware_tx=raydium_trigo_pow2_next(dev->win.width);
tex->hardware_ty=raydium_trigo_pow2_next(dev->win.height);
tex->bpp=dev->vpic.depth;
tex->texture=raydium_texture_load_internal("not needed :)",as,1,0,0,0,id);
if(tex->texture<=0)
{
raydium_log("live: ERROR: cannot create 'faked' texture (see above)");
return -1;
}
tex->device=dev;
tex->data_source=dev->buffer2;
tex->state=1;
raydium_log("live: %s linked to %s (live)",dev->name,as);
return id;
#else
raydium_log("live: Live API is not supported under win32 yet");
return -1;
#endif
}
void raydium_live_texture_refresh(int livetex)
{
raydium_live_Texture *tex;
int (*f)(unsigned char *data, int tx, int ty, int bpp);
if(!raydium_live_texture_isvalid(livetex))
{
raydium_log("live: cannot refresh live texture: wrong name or id");
return;
}
tex=&raydium_live_texture[livetex];
f=tex->OnRefresh;
if(f && !f(tex->data_source,tex->tx,tex->ty,tex->bpp))
return;
//printf("%i - %ix%i %i bpp\n",tex->texture,tex->tx,tex->ty,tex->bpp);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,tex->texture);
glTexSubImage2D(GL_TEXTURE_2D,0,0,0,
tex->tx,
tex->ty,
(tex->bpp==24?GL_RGB:GL_RGBA),
GL_UNSIGNED_BYTE,
tex->data_source);
}
void raydium_live_texture_refresh_name(char *texture)
{
raydium_live_texture_refresh(raydium_live_texture_find(raydium_texture_find_by_name(texture)));
}
int raydium_live_texture_create(char *as, unsigned char *data_source, int tx, int ty, int bpp)
{
int id,i;
raydium_live_Texture *tex;
id=raydium_live_texture_find_free();
if(id<0)
{
raydium_log("live: ERROR: no more free live texture slot available (max: %i)",RAYDIUM_MAX_LIVE_TEXTURES);
return -1;
}
if(bpp!=24 && bpp!=32)
{
raydium_log("live: ERROR: live textures are limited to 24 or 32 bpp color depth only, for now");
return -1;
}
// duplicated ?
for(i=0;i<raydium_texture_index;i++)
if(!strcmp(raydium_texture_name[i],as))
{
raydium_log("live: WARNING ! %s is duplicated",as);
// this is the right answer only if duplicated texture
// is already a "live" one ! (to fix ?)
id=raydium_live_texture_find(i);
// ... but reset/update some values
tex=&raydium_live_texture[id];
tex->device=NULL;
tex->data_source=data_source;
raydium_live_texture_refresh(id);
return id;
}
tex=&raydium_live_texture[id];
tex->tx=tx;
tex->ty=ty;
tex->hardware_tx=raydium_trigo_pow2_next(tex->tx);
tex->hardware_ty=raydium_trigo_pow2_next(tex->ty);
tex->bpp=bpp;
tex->texture=raydium_texture_load_internal("not needed :)",as,1,0,0,0,id);
if(tex->texture<=0)
{
raydium_log("live: ERROR: cannot create 'faked' texture (see above)");
return -1;
}
tex->device=NULL;
tex->data_source=data_source;
tex->state=1;
raydium_live_texture_refresh(id);
raydium_log("live: texture '%s' created",as);
return id;
}
void raydium_live_texture_mask(int livetex, GLfloat alpha)
{
raydium_live_Texture *tex;
GLfloat u,v;
if(!raydium_live_texture_isvalid(livetex))
{
raydium_log("live: cannot draw live mask: wrong name or id");
return;
}
tex=&raydium_live_texture[livetex];
u=tex->tx/(float)tex->hardware_tx;
v=tex->ty/(float)tex->hardware_ty;
//raydium_osd_mask_texture_clip(tex->texture,alpha,u*100,v*100,0,0);
raydium_osd_mask_texture_clip(tex->texture,alpha,0,v*100,u*100,0);
}
void raydium_live_texture_mask_name(char *texture, GLfloat alpha)
{
raydium_live_texture_mask(raydium_live_texture_find(raydium_texture_find_by_name(texture)),alpha);
}
// (the current code of this function is quiet a hack ...)
void raydium_live_texture_draw(int livetex, GLfloat alpha,GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)
{
raydium_live_Texture *tex;
GLfloat u,v;
if(!raydium_live_texture_isvalid(livetex))
{
raydium_log("live: cannot draw live mask: wrong name or id");
return;
}
tex=&raydium_live_texture[livetex];
u=tex->tx/(float)tex->hardware_tx;
v=tex->ty/(float)tex->hardware_ty;
raydium_osd_start();
raydium_texture_current_set(tex->texture);
raydium_rendering_internal_prepare_texture_render(tex->texture);
glColor4f(1,1,1,alpha);
glEnable(GL_BLEND);
glDepthMask(GL_FALSE);
glBegin(GL_QUADS);
glTexCoord2f(0,v);
glVertex3f(x1,y1,0);
glTexCoord2f(u,v);
glVertex3f(x2,y1,0);
glTexCoord2f(u,0);
glVertex3f(x2,y2,0);
glTexCoord2f(0,0);
glVertex3f(x1,y2,0);
glEnd();
raydium_rendering_internal_restore_render_state();
raydium_osd_stop();
}
void raydium_live_texture_draw_name(char *texture, GLfloat alpha,GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)
{
raydium_live_texture_draw(raydium_live_texture_find(raydium_texture_find_by_name(texture)),alpha,x1,y1,x2,y2);
}
void raydium_live_texture_refresh_callback_set(int livetex, void *callback)
{
raydium_live_Texture *tex;
if(!raydium_live_texture_isvalid(livetex))
{
raydium_log("live: cannot set OnRefresh callback: wrong name or id");
return;
}
tex=&raydium_live_texture[livetex];
tex->OnRefresh=callback;
}
void raydium_live_texture_refresh_callback_set_name(char *texture, void *callback)
{
raydium_live_texture_refresh_callback_set(raydium_live_texture_find(raydium_texture_find_by_name(texture)),callback);
}

133
raydium/live.h Normal file
View File

@ -0,0 +1,133 @@
/*
Raydium - CQFD Corp.
http://raydium.org/
License: GPL - GNU General Public License, see "gpl.txt" file.
*/
// Live textures functions
// TODO:
// 4 bpp live textures support
#ifndef LIVE_H
#define LIVE_H
#ifndef WIN32
#include <linux/types.h>
#include <linux/videodev.h>
#include <sys/mman.h>
#endif
#define RAYDIUM_LIVE_DEVICE_DEFAULT "/dev/video0"
#define RAYDIUM_LIVE_SIZEX_DEFAULT 352
#define RAYDIUM_LIVE_SIZEY_DEFAULT 288
#define RAYDIUM_LIVE_DEVICE_AUTO NULL
#define RAYDIUM_LIVE_SIZE_AUTO -1
#define RAYDIUM_LIVE_FREE 0
#define RAYDIUM_LIVE_CAPTURE_NONE -1
#define RAYDIUM_LIVE_CAPTURE_READ 1
#define RAYDIUM_LIVE_CAPTURE_MMAP 2
typedef struct raydium_live_Device
{
#ifndef WIN32
int fd;
struct video_capability cap;
struct video_window win;
struct video_picture vpic;
// for mmap captures
struct video_mbuf gb_buffers;
struct video_mmap gb_buf;
#endif
unsigned char *buffer; // capture buffer
unsigned char *src; // intermediate buffer
unsigned char *buffer2; // final buffer
signed char capture_style;
int frame;
char name[RAYDIUM_MAX_NAME_LEN];
} raydium_live_Device;
typedef struct raydium_live_Texture
{
signed char state;
raydium_live_Device *device;
int texture;
void *OnRefresh;
int tx;
int ty;
int hardware_tx;
int hardware_ty;
int bpp;
unsigned char *data_source;
} raydium_live_Texture;
__global raydium_live_Device raydium_live_device[RAYDIUM_MAX_VIDEO_DEVICES];
__global raydium_live_Texture raydium_live_texture[RAYDIUM_MAX_LIVE_TEXTURES];
// mostly from tvset.c (thanks to vgrabber.c)
#define READ_VIDEO_PIXEL(buf, format, depth, r, g, b) \
{ \
switch (format) \
{ \
case VIDEO_PALETTE_GREY: \
switch (depth) \
{ \
case 4: \
case 6: \
case 8: \
(r) = (g) = (b) = (*buf++ << 8);\
break; \
\
case 16: \
(r) = (g) = (b) = \
*((unsigned short *) buf); \
buf += 2; \
break; \
} \
break; \
\
\
case VIDEO_PALETTE_RGB565: \
{ \
unsigned short tmp = *(unsigned short *)buf; \
(r) = tmp&0xF800; \
(g) = (tmp<<5)&0xFC00; \
(b) = (tmp<<11)&0xF800; \
buf += 2; \
} \
break; \
\
case VIDEO_PALETTE_RGB555: \
(r) = (buf[0]&0xF8)<<8; \
(g) = ((buf[0] << 5 | buf[1] >> 3)&0xF8)<<8; \
(b) = ((buf[1] << 2 ) & 0xF8)<<8; \
buf += 2; \
break; \
\
case VIDEO_PALETTE_RGB24: \
(r) = buf[0] << 8; (g) = buf[1] << 8; \
(b) = buf[2] << 8; \
buf += 3; \
break; \
case VIDEO_PALETTE_YUV420P: \
(r) = buf[0]+1.140*buf[2]; \
(g) = buf[0]-0.394*buf[1]-0.581*buf[2]; \
(b) = buf[0]+2.028*buf[1]; \
buf += 3; \
break; \
\
default: \
raydium_log("live: error: palette unknown"); \
} \
}
// endif LIVE_H
#endif

32
raydium/log.c Normal file
View File

@ -0,0 +1,32 @@
/*
Raydium - CQFD Corp.
http://raydium.org/
License: GPL - GNU General Public License, see "gpl.txt" file.
*/
#ifndef DONT_INCLUDE_HEADERS
#include "index.h"
#else
#include "headers/log.h"
#endif
void raydium_console_line_add(char *format, ...);
void raydium_log(char *format, ...)
{
char str[RAYDIUM_MAX_NAME_LEN];
va_list argptr;
int retlen;
va_start(argptr,format);
retlen = vsnprintf(str,RAYDIUM_MAX_NAME_LEN - 1, format,argptr);
va_end(argptr);
if(retlen < 0) retlen = 0;
str[retlen] = '\0';
printf("Raydium: %s\n",str);
if(raydium_log_file) fprintf(raydium_log_file,"%s\n",str);
raydium_console_line_add("%s", str);
}

23
raydium/main.c Normal file
View File

@ -0,0 +1,23 @@
/*
* Raydium - CQFD Corp.
* http://raydium.org/
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#define MAIN_C
#include "common.h"
// EOF

23
raydium/main.h Normal file
View File

@ -0,0 +1,23 @@
/*
* Raydium - CQFD Corp.
* http://raydium.org/
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#define MAIN_H
#include "common.h"
// EOF

70
raydium/mouse.c Normal file
View File

@ -0,0 +1,70 @@
/*
Raydium - CQFD Corp.
http://raydium.org/
License: GPL - GNU General Public License, see "gpl.txt" file.
*/
#ifndef DONT_INCLUDE_HEADERS
#include "index.h"
#else
#include "headers/mouse.h"
#endif
/*
#define raydium_mouse_hide() glutSetCursor(GLUT_CURSOR_NONE);
#define raydium_mouse_show() glutSetCursor(GLUT_CURSOR_LEFT_ARROW);
#define raydium_mouse_move(x,y) glutWarpPointer(x,y)
*/
signed char raydium_mouse_isvisible(void)
{
int ret;
ret=glutGet(GLUT_WINDOW_CURSOR);
return (ret==GLUT_CURSOR_NONE?0:1);
}
void raydium_mouse_init(void)
{
if(raydium_window_mode==RAYDIUM_RENDERING_NONE)
return;
memset(raydium_mouse_button,0,3);
raydium_mouse_click=0;
raydium_mouse_x=raydium_mouse_y=raydium_window_ty=0;
raydium_log("mouse: OK");
raydium_mouse_hide();
}
void raydium_mouse_click_callback(int but,int state,int x,int y)
{
unsigned char n=0,s=0;
signed char special=0;
if(but==GLUT_LEFT_BUTTON) n=0;
else if(but==GLUT_RIGHT_BUTTON) n=1;
else if(but==GLUT_MIDDLE_BUTTON) n=2;
else
{
special=1;
n=but;
}
if(state==GLUT_DOWN) s=1;
if(state==GLUT_UP) s=0;
if(s) raydium_mouse_click=n+1;
if(!special)
raydium_mouse_button[n]=s;
}
void raydium_mouse_move_callback(int x, int y)
{
if(x>=0 && x<raydium_window_tx) raydium_mouse_x=x;
if(y>=0 && y<raydium_window_ty) raydium_mouse_y=y;
}
int raydium_mouse_button_pressed(int button)
{
return raydium_mouse_button[button];
}

451
raydium/myglut-win32.c Normal file
View File

@ -0,0 +1,451 @@
/*
Raydium - CQFD Corp.
http://raydium.org/
License: GPL - GNU General Public License, see "gpl.txt" file.
*/
#include "headers/myglut.h"
#include <windows.h>
#include <gl/glaux.h>
static HINSTANCE currInstance;
static HWND currWnd;
static HDC currDC;
static HGLRC currGLRC;
LRESULT CALLBACK WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
// ---------------------- public API
void glutInit(int *argc, char **argv)
{
currInstance = NULL ;
currWnd = NULL ;
currDC = NULL ;
currGLRC = NULL ;
glutReshapeFuncCB=NULL;
glutKeyboardFuncCB=NULL;
glutSpecialUpFuncCB=NULL;
glutSpecialFuncCB=NULL;
glutMotionFuncCB=NULL;
glutPassiveMotionFuncCB=NULL;
glutMouseFuncCB=NULL;
glutDisplayFuncCB=NULL;
glutIdleFuncCB=NULL;
_glutMouseVisible=1;
}
void mylgutCloseWindow(void)
{
wglMakeCurrent ( NULL, NULL ) ;
wglDeleteContext ( currGLRC ) ;
DestroyWindow ( currWnd ) ;
}
//glutSetCursor
void glutSetCursor(int cursor)
{
switch(cursor)
{
case GLUT_CURSOR_LEFT_ARROW:
if(_glutMouseVisible) break;
ShowCursor(1);
_glutMouseVisible=1;
break;
case GLUT_CURSOR_NONE:
default:
if(!_glutMouseVisible) break;
ShowCursor(0);
_glutMouseVisible=0;
break;
break;
}
//SetCursor( LoadCursor ( NULL, wcursor ) ) ;
}
//glutWarpPointer (move mouse)
void glutWarpPointer(int x, int y)
{
POINT point;
point.x = x;
point.y = y;
ClientToScreen(currWnd /* ? */, &point);
SetCursorPos(point.x, point.y);
}
//glutSwapBuffers
void glutSwapBuffers(void)
{
glFlush () ;
SwapBuffers ( currDC ) ;
}
//glutMainLoop is generic (myglut.c)
// ------------- private part
void myglutGetEvents (void)
{
MSG msg;
while ( PeekMessage( &msg, currWnd, 0, 0, PM_REMOVE ) )
{
TranslateMessage( &msg ) ;
DispatchMessage ( &msg ) ;
}
}
void pwInit ( int x, int y, int w, int h, int multisample,
char *title, int border, int num_samples )
{
WNDCLASS wc;
signed char fullscn;
RECT rect;
DWORD style = 0;
int iPixelFormat;
int origin [2] = { 0, 0 };
int size [2] = { 640, 480 };
PIXELFORMATDESCRIPTOR pfd;
currInstance = GetModuleHandleA( NULL ) ;
/* Register the window class */
wc.style = CS_OWNDC | CS_VREDRAW | CS_HREDRAW ;
wc.lpfnWndProc = WndProc ;
wc.cbClsExtra = 0 ;
wc.cbWndExtra = 0 ;
wc.hInstance = currInstance ;
wc.hIcon = LoadIcon ( NULL, IDI_APPLICATION ) ;
wc.hCursor = LoadCursor ( NULL, IDC_ARROW ) ;
wc.hbrBackground = ( HBRUSH ) ( COLOR_WINDOW + 1 ) ;
wc.lpszMenuName = NULL ;
wc.lpszClassName = "RaydiumAppClass" ;
if ( !RegisterClass( &wc ) )
{
raydium_log("(my)glut: ERROR: Can't register window class" ) ;
exit ( 1 ) ;
}
/* Setup window style */
fullscn = (w == -1 && h == -1 ) ? 1 : 0 ;
if ( w == -1 ) w = GetSystemMetrics( SM_CXSCREEN ) ;
if ( h == -1 ) h = GetSystemMetrics( SM_CYSCREEN ) ;
if ( x == -1 ) x = (GetSystemMetrics( SM_CXSCREEN ) / 2) - (w/2) ;
if ( y == -1 ) y = (GetSystemMetrics( SM_CYSCREEN ) / 2) - (h/2);
origin [ 0 ] = x ;
origin [ 1 ] = y ;
size [ 0 ] = w ;
size [ 1 ] = h ;
rect.left = x ;
rect.top = y ;
rect.right = rect.left + w ;
rect.bottom = rect.top + h ;
if ( !fullscn )
style = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS ;
else
style = WS_POPUP ;
AdjustWindowRect( &rect, style, 0 ) ;
/* Create the window */
currWnd = CreateWindow(
"RaydiumAppClass", title, style,
rect.left, rect.top,
rect.right - rect.left, rect.bottom - rect.top,
NULL, NULL, currInstance, NULL ) ;
if ( !currWnd )
{
raydium_log("(my)glut: ERROR: Can't create window" ) ;
exit ( 1 ) ;
}
/* Get DC for this window */
currDC = GetDC ( currWnd ) ;
if ( !currDC )
{
raydium_log("(my)glut: ERROR: Can't get window DC" ) ;
exit ( 1 ) ;
}
// wglGetExtensionsStringARBtype *wglGetExtensionsStringARB = (wglGetExtensionsStringARBtype *)wglGetProcAddress ( "wglGetExtensionsStringARB" ) ;
// const char *extensionsString = wglGetExtensionsStringARB ( currDC ) ;
// printf ( "%s %x %s\n", glGetString ( GL_EXTENSIONS ), wglGetExtensionsStringARB, extensionsString ) ;
// if (!GLExtensionExists("WGL_ARB_multisample "))
// return suggestedFormat;
pfd.nSize=sizeof(PIXELFORMATDESCRIPTOR);
pfd.nVersion=1;
pfd.dwFlags=PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.iPixelType=PFD_TYPE_RGBA;
pfd.cColorBits=24;
pfd.cRedBits=0;
pfd.cRedShift=0;
pfd.cGreenBits=0;
pfd.cGreenShift=0;
pfd.cBlueBits=0;
pfd.cBlueShift=0;
pfd.cAlphaBits=0;
pfd.cAlphaShift=0;
pfd.cAccumBits=0;
pfd.cAccumRedBits=0;
pfd.cAccumGreenBits=0;
pfd.cAccumBlueBits=0;
pfd.cAccumAlphaBits=0;
pfd.cDepthBits=32;
pfd.cStencilBits=1;
pfd.cAuxBuffers=0;
pfd.iLayerType=PFD_MAIN_PLANE;
pfd.bReserved=0;
pfd.dwLayerMask=0;
pfd.dwVisibleMask=0;
pfd.dwDamageMask=0;
/* Get best available match of pixel format for DC */
iPixelFormat = ChoosePixelFormat ( currDC, &pfd ) ;
if ( iPixelFormat == 0 )
{
raydium_log("(my)glut: ERROR: Can't get OpenGL pixel format" ) ;
exit ( 1 ) ;
}
/* Set the pixel format of the DC */
if ( !SetPixelFormat( currDC, iPixelFormat, &pfd ) )
{
raydium_log("(my)glut: ERROR: Can't set OpenGL pixel format" ) ;
exit ( 1 ) ;
}
/* Show the window and paint its contents */
ShowWindow ( currWnd, SW_SHOW ) ;
UpdateWindow ( currWnd ) ;
/* Create openGL context and make it current */
currGLRC = wglCreateContext ( currDC ) ;
if ( !currGLRC )
{
raydium_log("(my)glut: ERROR: Unable to open a suitable window");
exit ( 1 ) ;
}
if ( !wglMakeCurrent ( currDC, currGLRC ) )
{
raydium_log("(my)glut: ERROR: Unable to open a suitable window");
exit ( 1 ) ;
}
glClear ( GL_COLOR_BUFFER_BIT ) ;
glutSwapBuffers () ;
glClear ( GL_COLOR_BUFFER_BIT ) ;
glutSwapBuffers () ;
// if (glutReshapeFuncCB)
// glutReshapeFuncCB(w, h);
DescribePixelFormat(currDC, iPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
raydium_log("Found %ix%i with %i bpp color and %i bits zbuffer (stencil is %i)",w,h,pfd.cColorBits,pfd.cDepthBits,pfd.cStencilBits);
}
LRESULT CALLBACK WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
static int key = -1 ;
static int updown = GLUT_UP ;
static int old_key = -1 ; // We need this because "key" changes case
int button = -1 ;
static int mb = 0 ;
static int lastx = 0 ;
static int lasty = 0 ;
BYTE state[256];
WORD code[2];
signed char b;
signed char special=0;
signed char repeating=0;
int size[2];
switch (uMsg)
{
case WM_LBUTTONDOWN:
case WM_MBUTTONDOWN:
case WM_RBUTTONDOWN:
updown = GLUT_DOWN ;
if ( uMsg == WM_LBUTTONDOWN ) { button = GLUT_LEFT_BUTTON ; mb |= 1 ; }
else if ( uMsg == WM_MBUTTONDOWN ) { button = GLUT_MIDDLE_BUTTON ; mb |= 2 ; }
else { button = GLUT_RIGHT_BUTTON ; mb |= 4 ; }
SetCapture ( hWnd ) ;
lastx = (LOWORD( lParam ) ) ;
lasty = (HIWORD( lParam ) ) ;
if ( button != -1 && glutMouseFuncCB )
(*glutMouseFuncCB) ( button, updown, lastx, lasty ) ;
break;
case WM_LBUTTONUP:
case WM_MBUTTONUP:
case WM_RBUTTONUP:
updown = GLUT_UP ;
if ( uMsg == WM_LBUTTONUP ) { button = GLUT_LEFT_BUTTON ; mb &= ~1 ; }
else if ( uMsg == WM_MBUTTONUP ) { button = GLUT_MIDDLE_BUTTON ; mb &= ~2 ; }
else { button = GLUT_RIGHT_BUTTON ; mb &= ~4 ; }
if ( mb == 0 ) ReleaseCapture () ;
lastx = (LOWORD( lParam ) ) ;
lasty = (HIWORD( lParam ) ) ;
if ( button != -1 && glutMouseFuncCB )
(*glutMouseFuncCB) ( button, updown, lastx, lasty ) ;
break;
case WM_MOUSEMOVE:
lastx = (LOWORD( lParam ) );
lasty = (HIWORD( lParam ) );
if ( glutPassiveMotionFuncCB )
(*glutPassiveMotionFuncCB) ( lastx, lasty ) ;
break;
case WM_MOUSEWHEEL:
if ( ( short ) HIWORD( wParam ) > 0 )
{
if ( glutPassiveMotionFuncCB )
(*glutMouseFuncCB) ( 3, GLUT_DOWN, lastx, lasty ) ;
if ( glutPassiveMotionFuncCB )
(*glutMouseFuncCB) ( 3, GLUT_UP, lastx, lasty ) ;
}
else
{
if ( glutPassiveMotionFuncCB )
(*glutMouseFuncCB) ( 4, GLUT_DOWN, lastx, lasty ) ;
if ( glutPassiveMotionFuncCB )
(*glutMouseFuncCB) ( 4, GLUT_UP, lastx, lasty ) ;
}
case WM_KEYDOWN:
// If the key is already down, we are on auto-repeat. Break if the autorepeat is disabled.
if ( ( updown == GLUT_DOWN ) && ( (int)wParam == old_key ) )
{
/* if ( autoRepeat )
{*/
// Disable CTRL, SHIFT, CapsLock keys from making a callback
if ( ( key == VK_CONTROL ) || ( key == VK_SHIFT ) || ( key == VK_CAPITAL ) )
break ;
/* if ( key != -1 && kbCB ) // Autorepeat enabled, call the callback with an "up" setting
(*kbCB) ( key, PW_UP, lastx, lasty ) ;
}
else*/
repeating=1;
}
updown = GLUT_DOWN ;
old_key = wParam ;
// FALLTHROUGH
case WM_KEYUP:
if ( uMsg == WM_KEYUP ) updown = GLUT_UP ;
key = wParam ;
// Disable CTRL, SHIFT, CapsLock keys from making a callback
if ( ( key == VK_CONTROL ) || ( key == VK_SHIFT ) || ( key == VK_CAPITAL ) )
break ;
switch ( key )
{
case VK_F1: key = GLUT_KEY_F1; special=1; break;
case VK_F2: key = GLUT_KEY_F2; special=1; break;
case VK_F3: key = GLUT_KEY_F3; special=1; break;
case VK_F4: key = GLUT_KEY_F4; special=1; break;
case VK_F5: key = GLUT_KEY_F5; special=1; break;
case VK_F6: key = GLUT_KEY_F6; special=1; break;
case VK_F7: key = GLUT_KEY_F7; special=1; break;
case VK_F8: key = GLUT_KEY_F8; special=1; break;
case VK_F9: key = GLUT_KEY_F9; special=1; break;
case VK_F10: key = GLUT_KEY_F10; special=1; break;
case VK_F11: key = GLUT_KEY_F11; special=1; break;
case VK_F12: key = GLUT_KEY_F12; special=1; break;
case VK_LEFT: key = GLUT_KEY_LEFT; special=1; break;
case VK_RIGHT: key = GLUT_KEY_RIGHT; special=1; break;
case VK_UP: key = GLUT_KEY_UP; special=1; break;
case VK_DOWN: key = GLUT_KEY_DOWN; special=1; break;
case VK_PRIOR: key = GLUT_KEY_PAGE_UP; special=1; break;
case VK_NEXT: key = GLUT_KEY_PAGE_DOWN; special=1; break;
case VK_HOME: key = GLUT_KEY_HOME; special=1; break;
case VK_END: key = GLUT_KEY_END; special=1; break;
case VK_INSERT: key = GLUT_KEY_INSERT; special=1; break;
default:
// don't do this for WinCE
b = GetKeyboardState( state );
assert(b);
code [ 0 ] = 0; // WK: I need to do this, or on my Win2k box, the upper bits remain unchanged.
if( ToAscii( key, 0, state, code, 0 ) == 1 )
if((0xFF00 & code[0]) == 0) // setting a high bit in key causes crashes later on (out of range array access)
key=code[ 0 ];
}
if ( key != -1)
{
// special down
if(special && updown==GLUT_DOWN && glutSpecialFuncCB && !repeating)
glutSpecialFuncCB(key,lastx,lasty);
// special up
if(special && updown==GLUT_UP && glutSpecialUpFuncCB && !repeating)
glutSpecialUpFuncCB(key,lastx,lasty);
// normal
if(!special && updown==GLUT_DOWN && glutKeyboardFuncCB)
glutKeyboardFuncCB(key,lastx,lasty);
/*if(!special && repeating && glutKeyboardFuncCB)
glutKeyboardFuncCB(key,lastx,lasty);*/
//(*kbCB) ( key, updown, lastx, lasty ) ;
}
break;
case WM_SIZE:
size[0] = LOWORD(lParam) ;
size[1] = HIWORD(lParam) ;
_glutWindowSize[0]=size[0];
_glutWindowSize[1]=size[1];
if (glutReshapeFuncCB)
glutReshapeFuncCB(size[0], size[1]);
break;
case WM_CLOSE:
exit(0);
break;
default:
return ( DefWindowProc ( hWnd, uMsg, wParam, lParam ) ) ;
}
return 0;
}

660
raydium/myglut-x11.c Normal file
View File

@ -0,0 +1,660 @@
/*
Raydium - CQFD Corp.
http://raydium.org/
License: GPL - GNU General Public License, see "gpl.txt" file.
*/
#include "headers/myglut.h"
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/keysym.h>
#include <X11/cursorfont.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
//#include <X11/Xutil.h> // provided by glx
#include <GL/glx.h>
#ifdef HAVE_XINERAMA
#include <X11/extensions/Xinerama.h>
#endif
#ifdef HAVE_MOTIF
#include <X11/Xm/MwmUtil.h>
#else
/* bit definitions for MwmHints.flags */
#define MWM_HINTS_FUNCTIONS (1L << 0)
#define MWM_HINTS_DECORATIONS (1L << 1)
#define MWM_HINTS_INPUT_MODE (1L << 2)
#define MWM_HINTS_STATUS (1L << 3)
/* bit definitions for MwmHints.decorations */
#define MWM_DECOR_ALL (1L << 0)
#define MWM_DECOR_BORDER (1L << 1)
#define MWM_DECOR_RESIZEH (1L << 2)
#define MWM_DECOR_TITLE (1L << 3)
#define MWM_DECOR_MENU (1L << 4)
#define MWM_DECOR_MINIMIZE (1L << 5)
#define MWM_DECOR_MAXIMIZE (1L << 6)
typedef struct
{
unsigned long flags ;
unsigned long functions ;
unsigned long decorations ;
long inputMode ;
unsigned long status ;
} PropMotifWmHints ;
#define PROP_MOTIF_WM_HINTS_ELEMENTS 5
#endif
#ifndef GLX_SAMPLE_BUFFERS_ARB
#define GLX_SAMPLE_BUFFERS_ARB 100000
#define GLX_SAMPLES_ARB 100001
#endif
Display *currDisplay ;
XVisualInfo *visualInfo ;
Window currHandle ;
GLXContext currContext ;
Window rootWindow ;
Atom delWinAtom ;
int currScreen;
int currConnect;
typedef struct PixelFormat
{
int num_samples ;
int bits_per_pixel ;
int z_bits ;
int stencil_bits ;
} PixelFormat;
signed char XineramaAndFullscreenFocusHack=0;
signed char FullscreenFlag=0;
PixelFormat preferred_pixel_formats [] =
{
/* NumSamples, RGB_bits, Z_bits, Stencil */
{ 0, 24, 24, 1 }, /* Progressively nastier image formats */
{ 0, 16, 24, 1 },
{ 0, 16, 16, 1 },
{ 0, 16, 16, 0 },
{ -1, -1, -1, -1 } /* Magic end marker */
} ;
void pwInit ( int x, int y, int w, int h, int multisample,
char *title, int border, int num_samples );
int raydium_init_cli_option(char *option, char *value);
// ---------------------- public API
void glutInit(int *argc, char **argv)
{
currDisplay = NULL ;
visualInfo = NULL ;
currScreen = 0;
currConnect = 0;
glutReshapeFuncCB=NULL;
glutKeyboardFuncCB=NULL;
glutSpecialUpFuncCB=NULL;
glutSpecialFuncCB=NULL;
glutMotionFuncCB=NULL;
glutPassiveMotionFuncCB=NULL;
glutMouseFuncCB=NULL;
glutDisplayFuncCB=NULL;
glutIdleFuncCB=NULL;
_glutMouseVisible=1;
}
void mylgutCloseWindow(void)
{
glXDestroyContext ( currDisplay, currContext ) ;
XDestroyWindow ( currDisplay, currHandle ) ;
XFlush ( currDisplay ) ;
}
//glutSetCursor
void glutSetCursor(int cursor)
{
int currCursor;
Pixmap pix ;
char blank_cursor[16*16];
XColor bcol = { 0 } ;
switch(cursor)
{
case GLUT_CURSOR_LEFT_ARROW:
currCursor = XC_left_ptr;
XDefineCursor( currDisplay, currHandle,
XCreateFontCursor ( currDisplay, currCursor ) ) ;
_glutMouseVisible=1;
break;
case GLUT_CURSOR_NONE:
default:
memset(blank_cursor,0,16*16);
pix = XCreateBitmapFromData ( currDisplay,
rootWindow,
blank_cursor, 16, 16 ) ;
XDefineCursor ( currDisplay, currHandle,
XCreatePixmapCursor ( currDisplay,
pix, pix, &bcol, &bcol, 0, 0 ) ) ;
XFreePixmap ( currDisplay, pix ) ;
_glutMouseVisible=1;
}
}
//glutWarpPointer (move mouse)
void glutWarpPointer(int x, int y)
{
XWarpPointer(currDisplay, None, currHandle, 0, 0, 0, 0, x, y);
XFlush(currDisplay);
}
//glutSwapBuffers
void glutSwapBuffers(void)
{
glFlush () ;
glXSwapBuffers ( currDisplay, currHandle ) ;
// get events ?
}
//glutMainLoop is generic (myglut.c)
// ------------- private part
void chooseVisual (PixelFormat *pf)
{
int attribs [ 100 ] ;
int n = 0 ;
attribs [n++] = GLX_RGBA ;
switch ( pf->bits_per_pixel )
{
case 3 :
attribs [n++] = GLX_RED_SIZE ; attribs [n++] = 1 ;
attribs [n++] = GLX_GREEN_SIZE ; attribs [n++] = 1 ;
attribs [n++] = GLX_BLUE_SIZE ; attribs [n++] = 1 ;
break ;
case 16 :
attribs [n++] = GLX_RED_SIZE ; attribs [n++] = 5 ;
attribs [n++] = GLX_GREEN_SIZE ; attribs [n++] = 6 ;
attribs [n++] = GLX_BLUE_SIZE ; attribs [n++] = 5 ;
break ;
case 24 :
attribs [n++] = GLX_RED_SIZE ; attribs [n++] = 8 ;
attribs [n++] = GLX_GREEN_SIZE ; attribs [n++] = 8 ;
attribs [n++] = GLX_BLUE_SIZE ; attribs [n++] = 8 ;
break ;
}
switch ( pf->z_bits )
{
case 1 : attribs [n++] = GLX_DEPTH_SIZE ; attribs [n++] = 1 ; break ;
case 16 : attribs [n++] = GLX_DEPTH_SIZE ; attribs [n++] = 16 ; break ;
case 24 : attribs [n++] = GLX_DEPTH_SIZE ; attribs [n++] = 24 ; break ;
case 32 : attribs [n++] = GLX_DEPTH_SIZE ; attribs [n++] = 32 ; break ;
}
switch ( pf->stencil_bits )
{
case 1 : attribs [n++] = GLX_STENCIL_SIZE ; attribs [n++] = 1 ; break ;
case 8 : attribs [n++] = GLX_STENCIL_SIZE ; attribs [n++] = 8 ; break ;
}
if ( pf->num_samples > 0 )
{
attribs [n++] = GLX_SAMPLE_BUFFERS_ARB ; attribs [n++] = 1 ;
attribs [n++] = GLX_SAMPLES_ARB ; attribs [n++] = pf->num_samples ;
}
attribs [n++] = GLX_DOUBLEBUFFER ;
attribs [n++] = None ;
visualInfo = glXChooseVisual ( currDisplay, currScreen, attribs ) ;
}
void pwInit ( int x, int y, int w, int h, int multisample,
char *title, int border, int num_samples )
{
char *displayName = NULL;
int i;
int origin[2];
int size[2];
int DispX,DispY; // X screen size
XSetWindowAttributes attribs ;
XTextProperty textProperty ;
XSizeHints sizeHints ;
XWMHints wmHints ;
unsigned int mask ;
PixelFormat pf ;
#ifdef HAVE_XINERAMA
int i_d1, i_d2;
#endif
PropMotifWmHints hints ;
Atom prop_t ;
Atom prop ;
displayName=getenv ( "DISPLAY" ) ;
if ( displayName == NULL ) displayName = ":0.0" ;
currDisplay = XOpenDisplay ( displayName ) ;
if ( currDisplay == NULL )
{
raydium_log("(my)glut: ERROR: Can't open display '%s'",
XDisplayName ( displayName ) ) ;
exit ( 1 ) ;
}
/* OpenGL GLX extension availability? */
if ( ! glXQueryExtension ( currDisplay, NULL, NULL ) )
{
raydium_log("(my)glut: ERROR: GLX extension not available on display '%s'",
XDisplayName ( displayName ) ) ;
exit ( 1 ) ;
}
currScreen = DefaultScreen ( currDisplay ) ;
rootWindow = RootWindow ( currDisplay, currScreen ) ;
currConnect = ConnectionNumber ( currDisplay ) ;
delWinAtom = XInternAtom ( currDisplay, "WM_DELETE_WINDOW", 0 ) ;
DispX = DisplayWidth ( currDisplay, currScreen ) ;
DispY = DisplayHeight ( currDisplay, currScreen ) ;
#ifdef HAVE_XINERAMA
if(XineramaQueryExtension( currDisplay, &i_d1, &i_d2 )
&& XineramaIsActive( currDisplay ) )
{
XineramaScreenInfo *screens;
int num_screens;
int selected;
char str[RAYDIUM_MAX_NAME_LEN];
screens = XineramaQueryScreens(currDisplay,&num_screens);
raydium_log("Xinerama detected with %i screens:",num_screens);
for(i=0;i<num_screens;i++)
{
raydium_log("*** screen %i : %ix%i at (%i,%i)",i,screens[i].width,screens[i].height,screens[i].x_org,screens[i].y_org);
}
if(raydium_init_cli_option("xinerama-fullscreen",NULL))
{
raydium_log("... but using Xinerama fullscreen anyway !");
}
else
{
if(raydium_init_cli_option("xinerama-screen",str))
selected=atoi(str);
else
selected=0;
if(selected<0 || selected >=num_screens)
{
raydium_log("invalid screen id !");
selected=0;
}
raydium_log("using Xinerama screen %i",selected);
x+=screens[selected].x_org;
y+=screens[selected].y_org;
DispX=screens[selected].width;
DispY=screens[selected].height;
if(w==-1 && h==-1) XineramaAndFullscreenFocusHack=1;
}
XFree(screens);
} // end Xinerama
else
{
raydium_log("no Xinerama on this display");
}
#else
raydium_log("no Xinerama support. See config.h for HAVE_XINERAMA symbol");
#endif
if ( w == -1 && h == -1)
{
w = DispX;
h = DispY;
FullscreenFlag = 1;
}
origin [ 0 ] = x ;
origin [ 1 ] = y ;
size [ 0 ] = w ;
size [ 1 ] = h ;
for (i = 0 ; preferred_pixel_formats [ i ] . num_samples >= 0 ; i++ )
{
pf = preferred_pixel_formats [ i ] ;
pf . num_samples = num_samples ;
chooseVisual ( &pf ) ;
if ( visualInfo != NULL )
break ;
}
if ( visualInfo == NULL )
{
num_samples = 0 ;
for (i = 0 ; preferred_pixel_formats [ i ] . num_samples >= 0 ; i++ )
{
pf = preferred_pixel_formats [ i ] ;
pf . num_samples = num_samples ;
chooseVisual ( &pf ) ;
if ( visualInfo != NULL )
break ;
}
if ( visualInfo == NULL )
{
raydium_log("(my)glut: ERROR: Unable to open a suitable window");
exit ( 1 ) ;
}
}
attribs.event_mask = StructureNotifyMask | ExposureMask |
ButtonPressMask | ButtonReleaseMask |
KeyPressMask | KeyReleaseMask |
EnterWindowMask | LeaveWindowMask |
PointerMotionMask | ButtonMotionMask |
VisibilityChangeMask ;
attribs.background_pixmap = None ;
attribs.background_pixel = 0 ;
attribs.border_pixel = 0 ;
attribs.colormap = XCreateColormap ( currDisplay, rootWindow,
visualInfo->visual, AllocNone ) ;
mask = CWBackPixmap | CWBorderPixel | CWColormap | CWEventMask;
if(FullscreenFlag)
{
attribs.override_redirect = True;
mask |= CWOverrideRedirect;
}
currHandle = XCreateWindow ( currDisplay, rootWindow,
x, y, w, h, 0, visualInfo->depth,
InputOutput, visualInfo->visual,
mask, &attribs ) ;
currContext = glXCreateContext ( currDisplay, visualInfo, NULL, 1 ) ;
glXMakeCurrent ( currDisplay, currHandle, currContext ) ;
if ( ! glXIsDirect ( currDisplay, glXGetCurrentContext() ) )
{
raydium_log("(my)glut: WARNING: This is an *INDIRECT* rendering context.") ;
}
sizeHints.flags = 0 ;
if ( x >= 0 && y >= 0 )
sizeHints.flags |= USPosition ;
sizeHints.flags |= USSize ;
sizeHints.x = x ; sizeHints.y = y ;
sizeHints.width = w ; sizeHints.height = h ;
if(FullscreenFlag)
{
// make this window unresizable
sizeHints.flags |= PMinSize;
sizeHints.flags |= PMaxSize;
sizeHints.min_width=w;
sizeHints.max_width=w;
sizeHints.min_height=h;
sizeHints.max_height=h;
}
wmHints.flags = StateHint;
wmHints.initial_state = NormalState ;
hints . flags = MWM_HINTS_DECORATIONS ;
hints . decorations = border ? MWM_DECOR_ALL : 0 ;
prop_t = prop = XInternAtom ( currDisplay, "_MOTIF_WM_HINTS", True ) ;
if ( prop != 0 )
XChangeProperty ( currDisplay, currHandle, prop, prop_t, 32,
PropModeReplace, (unsigned char *) &hints,
PROP_MOTIF_WM_HINTS_ELEMENTS) ;
XStringListToTextProperty ( (char **) &title, 1, &textProperty ) ;
XSetWMProperties ( currDisplay, currHandle,
&textProperty, &textProperty, 0, 0,
&sizeHints, &wmHints, NULL ) ;
XSetWMProtocols ( currDisplay, currHandle, &delWinAtom , 1 );
XMapWindow ( currDisplay, currHandle ) ;
glXMakeCurrent ( currDisplay, currHandle, currContext ) ;
glutSetCursor(GLUT_CURSOR_LEFT_ARROW);
glClear ( GL_COLOR_BUFFER_BIT ) ;
glutSwapBuffers();
glClear ( GL_COLOR_BUFFER_BIT ) ;
glutSwapBuffers();
raydium_log("Found %ix%i with %i bpp color and %i bits zbuffer (stencil is %i)",sizeHints.width,sizeHints.height,pf.bits_per_pixel,pf.z_bits,pf.stencil_bits);
_glutWindowSize[0]=sizeHints.width;
_glutWindowSize[1]=sizeHints.height;
if(FullscreenFlag)
XGrabKeyboard(currDisplay,currHandle,False,GrabModeAsync,GrabModeAsync,CurrentTime);
// XSetInputFocus(currDisplay,currHandle,RevertToNone,CurrentTime);
}
void myglutGetEvents (void)
{
static int size[2]={-1,-1};
XEvent event ;
XComposeStatus composeStatus ;
char asciiCode [ 32 ] ;
KeySym keySym ;
int len,result;
signed char special=0;
// insideCallback = true ;
while ( XPending ( currDisplay ) )
{
int updown = GLUT_DOWN ;
XNextEvent ( currDisplay, &event ) ;
// refreshModifiers ( &event ) ;
switch ( event.type )
{
case ClientMessage : exit(0) ; break ;
case DestroyNotify : exit(0) ; break ;
case ConfigureNotify :
if ( currHandle == event.xconfigure.window &&
( size[0] != event.xconfigure.width ||
size[1] != event.xconfigure.height ) )
{
size[0] = event.xconfigure.width ;
size[1] = event.xconfigure.height ;
glXMakeCurrent ( currDisplay, currHandle, currContext ) ;
glXWaitX () ;
if (glutReshapeFuncCB)
glutReshapeFuncCB(size[0], size[1]);
}
break;
case MappingNotify:
XRefreshKeyboardMapping ( (XMappingEvent *) &event ) ;
break;
case EnterNotify :
if(XineramaAndFullscreenFocusHack)
{
XSetInputFocus(currDisplay,currHandle,RevertToParent,CurrentTime);
XRaiseWindow(currDisplay,currHandle);
}
break;
case LeaveNotify :
case VisibilityNotify:
case Expose : break ;
case MotionNotify :
if (glutPassiveMotionFuncCB)
glutPassiveMotionFuncCB( event.xmotion.x, event.xmotion.y);
break ;
case ButtonRelease :
updown = GLUT_UP ;
// FALLTHROUGH
case ButtonPress :
{
if (glutMouseFuncCB)
glutMouseFuncCB(event.xbutton.button-1, updown, event.xbutton.x, event.xbutton.y ) ;
}
break ;
case KeyRelease :
updown = GLUT_UP ;
// FALLTHROUGH
case KeyPress :
len = XLookupString( &event.xkey, asciiCode, sizeof(asciiCode),
&keySym, &composeStatus ) ;
result = -1 ;
if( len > 0 )
result = asciiCode[ 0 ] ;
else
{
special=1;
switch( keySym )
{
case XK_F1: result = GLUT_KEY_F1; break;
case XK_F2: result = GLUT_KEY_F2; break;
case XK_F3: result = GLUT_KEY_F3; break;
case XK_F4: result = GLUT_KEY_F4; break;
case XK_F5: result = GLUT_KEY_F5; break;
case XK_F6: result = GLUT_KEY_F6; break;
case XK_F7: result = GLUT_KEY_F7; break;
case XK_F8: result = GLUT_KEY_F8; break;
case XK_F9: result = GLUT_KEY_F9; break;
case XK_F10: result = GLUT_KEY_F10; break;
case XK_F11: result = GLUT_KEY_F11; break;
case XK_F12: result = GLUT_KEY_F12; break;
case XK_KP_Left:
case XK_Left: result = GLUT_KEY_LEFT; break;
case XK_KP_Right:
case XK_Right: result = GLUT_KEY_RIGHT; break;
case XK_KP_Up:
case XK_Up: result = GLUT_KEY_UP; break;
case XK_KP_Down:
case XK_Down: result = GLUT_KEY_DOWN; break;
case XK_KP_Prior:
case XK_Prior: result = GLUT_KEY_PAGE_UP; break;
case XK_KP_Next:
case XK_Next: result = GLUT_KEY_PAGE_DOWN; break;
case XK_KP_Home:
case XK_Home: result = GLUT_KEY_HOME; break;
case XK_KP_End:
case XK_End: result = GLUT_KEY_END; break;
case XK_KP_Insert:
case XK_Insert: result = GLUT_KEY_INSERT; break;
}
}
if(result!=-1)
{
// check autorepeat with current KeyRelease and next event
if (special && XEventsQueued(currDisplay, QueuedAfterReading))
{
XEvent ahead;
XPeekEvent(currDisplay, &ahead);
if (ahead.type == KeyPress && event.type == KeyRelease
&& ahead.xkey.window == event.xkey.window
&& ahead.xkey.keycode == event.xkey.keycode
&& ahead.xkey.time == event.xkey.time)
{
// repeating key. Discard event.
break;
}
}
// special down
if(special && updown==GLUT_DOWN && glutSpecialFuncCB && !raydium_key[result])
glutSpecialFuncCB(result,event.xkey.x, event.xkey.y);
// special up
if(special && updown==GLUT_UP && glutSpecialUpFuncCB && raydium_key[result])
glutSpecialUpFuncCB(result,event.xkey.x, event.xkey.y);
// normal
if(!special && updown==GLUT_DOWN && glutKeyboardFuncCB)
glutKeyboardFuncCB(result,event.xkey.x, event.xkey.y);
}
break ;
}
}
// insideCallback = false ;
glXMakeCurrent ( currDisplay, currHandle, currContext ) ;
}

11
raydium/myglut.README Normal file
View File

@ -0,0 +1,11 @@
(my)glut is an alternative to "real" GLUT, providing a small subset
of the original API, up to Raydium needs.
This code is heavily based on PW, the PLIB windowing library
( http://plib.sourceforge.net/ ). Huge thanks to Steve Baker for his great work.
Xf.
---
Raydium - CQFD Corp.
http://raydium.org/
License: GPL - GNU General Public License, see "gpl.txt" file.

181
raydium/myglut.c Normal file
View File

@ -0,0 +1,181 @@
/*
Raydium - CQFD Corp.
http://raydium.org/
License: GPL - GNU General Public License, see "gpl.txt" file.
*/
// avoid "real GLUT"
#ifndef GLUT_API_VERSION
#ifndef DONT_INCLUDE_HEADERS
#include "index.h"
#else
#include "headers/myglut.h"
#endif
#ifndef raydium_log
void raydium_log(char *format, ...);
#endif
int _glutWindowSize[2];
signed char _glutMouseVisible;
#ifdef WIN32
#include "myglut-win32.c"
#else
#include "myglut-x11.c"
#endif
//glutInitDisplayMode
//glutGameModeString
//glutEnterGameMode
//glutInitWindowSize
//glutCreateWindow
// are replaced by .. myglutCreateWindow
void myglutCreateWindow(GLuint tx, GLuint ty, signed char rendering, char *name)
{
switch(rendering)
{
case RAYDIUM_RENDERING_NONE:
return;
case RAYDIUM_RENDERING_WINDOW:
pwInit(-1,-1,tx,ty,0,name,1,0);
break;
case RAYDIUM_RENDERING_FULLSCREEN:
pwInit(0,0,-1,-1,0,name,0,0);
break;
}
}
//glutMainLoop
void glutMainLoop(void)
{
//#ifdef WIN32
// since windows is firing WM_SIZE too quickly ...
if(glutReshapeFuncCB)
glutReshapeFuncCB(_glutWindowSize[0],_glutWindowSize[1]);
//#endif
do{
glutIdleFuncCB();
myglutGetEvents();
}while(1);
}
// glutWireSphere
void glutWireSphere(GLdouble radius, GLint slices, GLint stacks)
{
static GLUquadricObj *quadObj=NULL;
if(!quadObj)
quadObj=gluNewQuadric();
gluQuadricDrawStyle(quadObj, GLU_LINE);
gluQuadricNormals(quadObj, GLU_SMOOTH);
gluSphere(quadObj, radius, slices, stacks);
}
//glutGet
int glutGet(int enu)
{
switch(enu)
{
case GLUT_WINDOW_CURSOR:
return _glutMouseVisible;
case GLUT_WINDOW_WIDTH:
return _glutWindowSize[0];
case GLUT_WINDOW_HEIGHT:
return _glutWindowSize[1];
default:
raydium_log("(my)glutGet: ERROR: unknown 'enu' %i",enu);
}
return 0;
}
//glutIgnoreKeyRepeat (1 = yes)
void glutIgnoreKeyRepeat(int ignore)
{
//glutIgnoreKeyRepeatFlag=(ignore?1:0);
}
//glutReshapeFunc - void (GLUTCALLBACK *func)(int width, int height)
void glutReshapeFunc(void *func)
{
glutReshapeFuncCB=func;
}
//glutKeyboardFunc - void (GLUTCALLBACK *func)(unsigned char key, int x, int y)
void glutKeyboardFunc(void *func)
{
glutKeyboardFuncCB=func;
}
//glutSpecialUpFunc - void (GLUTCALLBACK *func)(int key, int x, int y)
void glutSpecialUpFunc(void *func)
{
glutSpecialUpFuncCB=func;
}
//glutSpecialFunc - void (GLUTCALLBACK *func)(int key, int x, int y)
void glutSpecialFunc(void *func)
{
glutSpecialFuncCB=func;
}
//glutMotionFunc - void (GLUTCALLBACK *func)(int x, int y)
void glutMotionFunc(void *func)
{
glutMotionFuncCB=func;
}
//glutPassiveMotionFunc - void (GLUTCALLBACK *func)(int x, int y)
void glutPassiveMotionFunc(void *func)
{
glutPassiveMotionFuncCB=func;
}
//glutMouseFunc - void (GLUTCALLBACK *func)(int button, int state, int x, int y)
void glutMouseFunc(void *func)
{
glutMouseFuncCB=func;
}
//glutDisplayFunc - void (GLUTCALLBACK *func)(void)
void glutDisplayFunc(void *func)
{
glutDisplayFuncCB=func;
}
//glutIdleFunc - void (GLUTCALLBACK *func)(void)
void glutIdleFunc(void *func)
{
glutIdleFuncCB=func;
}
//glutExtensionSupported - int (GLUTCALLBACK *func)(const char *name);
int glutExtensionSupported(const char *name)
{
char *ext;
int i;
int start=0;
char curr[128];
ext=(char *)glGetString(GL_EXTENSIONS);
if(!ext) return 0;
for(i=0;i<=strlen(ext);i++)
{
if(ext[i]==' ' || ext[i]==0)
{
strncpy(curr,ext+start,i-start);
curr[i-start]=0;
//printf("-%s-\n",curr);
if(!strcasecmp(curr,name))
return 1;
start=i+1;
}
}
return 0;
}
#endif

1517
raydium/network.c Normal file

File diff suppressed because it is too large Load Diff

125
raydium/network.h Normal file
View File

@ -0,0 +1,125 @@
/*
Raydium - CQFD Corp.
http://raydium.org/
License: GPL - GNU General Public License, see "gpl.txt" file.
*/
// WARNING: this file is for "RAYDIUM_NETWORK_ONLY" applications only,
// providing a small subset of needed Raydium API.
#ifndef NETWORK_H
#define NETWORK_H
#ifdef RAYDIUM_NETWORK_ONLY
#include "php_wrappers.c"
#ifndef RAYDLL
void raydium_init_args(int argc, char **argv);
#else
void raydium_init_args_hack(int argc, char **argv);
#endif
int raydium_rayphp_repository_file_get(char *path);
signed char raydium_rayphp_http_test(void);
void raydium_console_init(void);
void raydium_php_init(void);
signed char raydium_network_init(void);
void raydium_network_internal_dump(void);
signed char raydium_network_server_create(void);
void raydium_random_randomize(void);
signed char raydium_parser_db_get(char *key, char *value, char *def);
void raydium_register_function(void *addr,char *name);
void raydium_file_home_path_cpy(char *file, char *dest);
void raydium_timecall_init(void);
void raydium_network_only_quit(int sig)
{
raydium_network_internal_dump();
exit(0);
}
#ifdef PHP_SUPPORT
// do the minimal reg_api job (this should not be done like this ! :/)
// part 1
PHP_i_sss(raydium_parser_db_get);
PHP_v_ss(raydium_file_home_path_cpy);
#endif
void raydium_network_only_init(int argc, char **argv)
{
setbuf(stdout,NULL);
signal(SIGINT,raydium_network_only_quit);
raydium_init_args(argc,argv);
raydium_random_randomize();
raydium_timecall_init();
raydium_console_init();
#ifdef PHP_SUPPORT
raydium_php_init();
// do the minimal reg_api job (this should not be done like this ! :/)
// part 2
raydium_register_function(C2PHP(raydium_parser_db_get),"raydium_parser_db_get");
raydium_register_function(C2PHP(raydium_file_home_path_cpy),"raydium_file_home_path_cpy");
#endif
raydium_network_init();
raydium_network_server_create();
}
void raydium_osd_color_ega(char hexa)
{
//
}
void raydium_osd_start(void)
{
//
}
void raydium_osd_stop(void)
{
//
}
void raydium_osd_printf(GLfloat x, GLfloat y, GLfloat size, GLfloat spacer,char *texture, char *format, ...)
{
//
}
GLuint raydium_texture_find_by_name(char *name)
{
return 0;
}
signed char raydium_texture_current_set(GLuint current)
{
return 0;
}
signed char raydium_texture_current_set_name(char *name)
{
return 0;
}
void raydium_rendering_internal_prepare_texture_render(GLuint tex)
{
//
}
// duplicated ... should move to another file than init.c
char *raydium_version(void)
{
static char version[RAYDIUM_MAX_NAME_LEN];
static signed char first=1;
if(first)
{
first=0;
sprintf(version,"%i.%03i",RAYDIUM_MAJOR,RAYDIUM_MINOR);
}
return version;
}
#endif
#endif

167
raydium/normal.c Normal file
View File

@ -0,0 +1,167 @@
/*
Raydium - CQFD Corp.
http://raydium.org/
License: GPL - GNU General Public License, see "gpl.txt" file.
*/
#ifndef DONT_INCLUDE_HEADERS
#include "index.h"
#else
#include "headers/normal.h"
#endif
void raydium_normal_generate_lastest_triangle(int default_visu)
{
GLfloat vect[2][3];
GLfloat norm[3];
GLfloat len;
int i;
GLuint index=raydium_vertex_index;
// let's find "vectors" of the triangle's plane ...
vect[0][0]=
raydium_vertex_x[index-1] -
raydium_vertex_x[index-2] ;
vect[0][1]=
raydium_vertex_y[index-1] -
raydium_vertex_y[index-2] ;
vect[0][2]=
raydium_vertex_z[index-1] -
raydium_vertex_z[index-2] ;
vect[1][0]=
raydium_vertex_x[index-1] -
raydium_vertex_x[index-3] ;
vect[1][1]=
raydium_vertex_y[index-1] -
raydium_vertex_y[index-3] ;
vect[1][2]=
raydium_vertex_z[index-1] -
raydium_vertex_z[index-3] ;
// ... and now, the normal ...
norm[0]=vect[0][1]*vect[1][2] - vect[0][2]*vect[1][1];
norm[1]=vect[0][2]*vect[1][0] - vect[0][0]*vect[1][2];
norm[2]=vect[0][0]*vect[1][1] - vect[0][1]*vect[1][0];
// ... wich we normalize.
len=sqrt(norm[0]*norm[0] + norm[1]*norm[1] + norm[2]*norm[2]);
for(i=1;i<=3;i++)
{
raydium_vertex_normal_x[index-i]=-norm[0]/len;
if(default_visu) raydium_vertex_normal_visu_x[index-i]=raydium_vertex_normal_x[index-i];
}
for(i=1;i<=3;i++)
{
raydium_vertex_normal_y[index-i]=-norm[1]/len;
if(default_visu) raydium_vertex_normal_visu_y[index-i]=raydium_vertex_normal_y[index-i];
}
for(i=1;i<=3;i++)
{
raydium_vertex_normal_z[index-i]=-norm[2]/len;
if(default_visu) raydium_vertex_normal_visu_z[index-i]=raydium_vertex_normal_z[index-i];
}
//raydium_log("norm [%f,%f,%f]/%f",norm[0],norm[1],norm[2],len);
}
void raydium_normal_restore_all(void)
{
GLuint i;
for(i=0;i<raydium_vertex_index;i++)
{
raydium_vertex_normal_visu_x[i]=raydium_vertex_normal_x[i];
raydium_vertex_normal_visu_y[i]=raydium_vertex_normal_y[i];
raydium_vertex_normal_visu_z[i]=raydium_vertex_normal_z[i];
}
raydium_log("normal: Normals restaured.");
}
void raydium_normal_regenerate_all(void)
{
GLuint save=raydium_vertex_index;
if(save<3) return;
for(raydium_vertex_index=3;raydium_vertex_index<=save;raydium_vertex_index+=3)
raydium_normal_generate_lastest_triangle(1);
raydium_vertex_index=save;
raydium_log("normal: Normals regenerated.");
}
void raydium_normal_smooth_from_to(GLuint from, GLuint to)
{
GLuint i,j;
GLfloat x,y,z;
GLfloat sum_x;
GLfloat sum_y;
GLfloat sum_z;
GLuint n;
GLuint debug_time;
char *tag; // 1 means "already done", 2 means "used for last normals search"
GLuint total;
total=to-from;
tag=malloc(total);
if(!tag) { raydium_log("normal: Not enought memory for normal smoothing, giving up."); return; }
memset(tag,0,total);
debug_time=0;
for(i=from;i<to;i++)
{
if(tag[i-from]) continue;
x=raydium_vertex_x[i];
y=raydium_vertex_y[i];
z=raydium_vertex_z[i];
sum_x=0;
sum_y=0;
sum_z=0;
n=0;
for(j=from;j<to;j++)
{
if(raydium_vertex_x[j]==x && raydium_vertex_y[j]==y && raydium_vertex_z[j]==z)
{
sum_x+=raydium_vertex_normal_x[i];
sum_y+=raydium_vertex_normal_y[i];
sum_z+=raydium_vertex_normal_z[i];
n++;
tag[j-from]=2;
}
}
sum_x/=(GLfloat)n;
sum_y/=(GLfloat)n;
sum_z/=(GLfloat)n;
for(j=from;j<to;j++)
if(tag[j-from]==2)
{
raydium_vertex_normal_visu_x[j]=sum_x;
raydium_vertex_normal_visu_y[j]=sum_y;
raydium_vertex_normal_visu_z[j]=sum_z;
tag[j-from]=1;
}
debug_time++;
//if(debug_time>100) { raydium_log("normal: smoothing: %i/%i",i-from,total); debug_time=0; }
}
free(tag);
raydium_log("normal: smoothing done.");
}
void raydium_normal_smooth_all(void)
{
raydium_normal_smooth_from_to(0,raydium_vertex_index);
}

656
raydium/object.c Normal file
View File

@ -0,0 +1,656 @@
/*
Raydium - CQFD Corp.
http://raydium.org/
License: GPL - GNU General Public License, see "gpl.txt" file.
*/
#ifndef DONT_INCLUDE_HEADERS
#include "index.h"
#else
#include "headers/object.h"
#endif
GLint raydium_object_find(char *name)
{
GLint i;
for(i=0;i<raydium_object_index;i++)
if(!strcmp(raydium_object_name[i],name)) return i;
return -1;
}
signed char raydium_object_isvalid(int obj)
{
if(obj>=0 && obj<raydium_object_index)
return 1;
return 0;
}
void raydium_object_reset(GLuint o)
{
raydium_object_name[o][0]=0;
raydium_object_start[o]=0;
raydium_object_end[o]=0;
raydium_object_anims[o]=0;
}
int raydium_object_load(char *filename)
{
if(raydium_object_find(filename)>=0)
{
raydium_log("ERROR: object: %s already loaded",filename);
return -1;
}
raydium_object_start[raydium_object_index]=raydium_vertex_index;
read_vertex_from(filename);
raydium_object_end[raydium_object_index]=raydium_vertex_index;
strcpy(raydium_object_name[raydium_object_index],filename);
return(raydium_object_index++);
}
GLint raydium_object_find_load(char *name)
{
int ret;
ret=raydium_object_find(name);
if(ret<0) return raydium_object_load(name);
return ret;
}
void raydium_object_draw(GLuint o)
{
#ifndef DEBUG_RENDER_DISABLE_DISPLAYLISTS
static GLuint dl[RAYDIUM_MAX_OBJECTS];
static char dl_state[RAYDIUM_MAX_OBJECTS];
static int first=0;
int i;
#endif
if(!raydium_object_isvalid(o))
{
raydium_log("object: draw: ERROR: id or name is invalid");
return;
}
// if animated : draw "only" first (generated) frame
if(raydium_object_anims[o]>0)
{
raydium_object_anim_generate_internal(o,raydium_object_anim_instance_current[o]);
raydium_rendering_from_to(raydium_object_start[o],raydium_object_start[o]+raydium_object_anim_len[o]);
return;
}
// ...
#ifndef DEBUG_RENDER_DISABLE_DISPLAYLISTS
if(first)
for(i=0;i<RAYDIUM_MAX_OBJECTS;i++)
dl_state[i]=-1;
if(raydium_render_displaylists_tag && !raydium_shadow_rendering)
{
if(!dl_state[o])
{
// build DL
dl_state[o]=1;
dl[o]=glGenLists(1);
raydium_log("Object: creating display list for object %s",raydium_object_name[o]);
glNewList(dl[o],GL_COMPILE);
raydium_rendering_from_to(raydium_object_start[o],raydium_object_end[o]);
glEndList();
}
glCallList(dl[o]);
}
else raydium_rendering_from_to(raydium_object_start[o],raydium_object_end[o]);
#else
// No display lists, draw
raydium_rendering_from_to(raydium_object_start[o],raydium_object_end[o]);
#endif
}
void raydium_object_draw_name(char *name)
{
GLint i;
i=raydium_object_find(name);
if(i>=0) raydium_object_draw(i);
else
raydium_object_draw(raydium_object_load(name));
}
void raydium_object_deform(GLuint obj,GLfloat ampl)
{
GLuint i;
if(!raydium_object_isvalid(obj))
{
raydium_log("object: deform: ERROR: id or name is invalid");
return;
}
for(i=raydium_object_start[obj];i<raydium_object_end[obj];i++)
{
raydium_vertex_x[i]+=raydium_random_neg_pos_1()*ampl;
raydium_vertex_y[i]+=raydium_random_neg_pos_1()*ampl;
raydium_vertex_z[i]+=raydium_random_neg_pos_1()*ampl;
}
/*
GLfloat ox,oy,oz;
GLfloat nx,ny,nz;
GLint j;
for(i=raydium_object_start[obj];i<raydium_object_end[obj];i++)
{
ox=raydium_vertex_x[i];
oy=raydium_vertex_y[i];
oz=raydium_vertex_z[i];
nx=ox+raydium_random_neg_pos_1()*ampl;
ny=oy+raydium_random_neg_pos_1()*ampl;
nz=oz+raydium_random_neg_pos_1()*ampl;
for(j=i;j<raydium_object_end[obj];j++)
if(raydium_vertex_x[j]==ox &&
raydium_vertex_y[j]==oy &&
raydium_vertex_z[j]==oz)
{
raydium_vertex_x[j]=nx;
raydium_vertex_y[j]=ny;
raydium_vertex_z[j]=nz;
}
}*/
}
void raydium_object_deform_name(char *name,GLfloat ampl)
{
raydium_object_deform(raydium_object_find(name),ampl);
}
GLfloat raydium_object_find_dist_max(GLuint obj)
{
GLfloat max=0,val;
int i;
int start,end;
if(!raydium_object_isvalid(obj))
{
raydium_log("object: find_dist_max: ERROR: id or name is invalid");
return -1;
}
if(raydium_object_anims[obj]>0)
{
raydium_object_anim_generate_internal(obj,raydium_object_anim_instance_current[obj]);
start=raydium_object_start[obj];
end=raydium_object_start[obj]+raydium_object_anim_len[obj];
}
else
{
start=raydium_object_start[obj];
end=raydium_object_end[obj];
}
for(i=start;i<end;i++)
{
val=sqrt((raydium_vertex_x[i]*raydium_vertex_x[i])+
(raydium_vertex_y[i]*raydium_vertex_y[i])+
(raydium_vertex_z[i]*raydium_vertex_z[i]) );
if(val>max) max=val;
}
return max;
}
void raydium_object_find_axes_max(GLuint obj, GLfloat *tx, GLfloat *ty, GLfloat *tz)
{
int i;
int start,end;
if(!raydium_object_isvalid(obj))
{
raydium_log("object: find_axes_max: ERROR: id or name is invalid");
return;
}
if(raydium_object_anims[obj]>0)
{
raydium_object_anim_generate_internal(obj,raydium_object_anim_instance_current[obj]);
start=raydium_object_start[obj];
end=raydium_object_start[obj]+raydium_object_anim_len[obj];
}
else
{
start=raydium_object_start[obj];
end=raydium_object_end[obj];
}
*tx=*ty=*tz=0;
for(i=start;i<end;i++)
{
if(raydium_trigo_abs(raydium_vertex_x[i])>*tx) *tx=raydium_trigo_abs(raydium_vertex_x[i]);
if(raydium_trigo_abs(raydium_vertex_y[i])>*ty) *ty=raydium_trigo_abs(raydium_vertex_y[i]);
if(raydium_trigo_abs(raydium_vertex_z[i])>*tz) *tz=raydium_trigo_abs(raydium_vertex_z[i]);
}
*tx*=2;
*ty*=2;
*tz*=2;
}
void raydium_object_find_minmax(GLuint obj, GLfloat *min, GLfloat *max)
{
int i;
int start,end;
//GLfloat min[3];
//GLfloat max[3];
if(!raydium_object_isvalid(obj))
{
raydium_log("object: find_size: ERROR: id or name is invalid");
return;
}
if(raydium_object_anims[obj]>0)
{
raydium_object_anim_generate_internal(obj,raydium_object_anim_instance_current[obj]);
start=raydium_object_start[obj];
end=raydium_object_start[obj]+raydium_object_anim_len[obj];
}
else
{
start=raydium_object_start[obj];
end=raydium_object_end[obj];
}
min[0]=max[0]=raydium_vertex_x[start];
min[1]=max[1]=raydium_vertex_y[start];
min[2]=max[2]=raydium_vertex_z[start];
for(i=start+1;i<end;i++)
{
if(raydium_vertex_x[i]<min[0])
min[0]=raydium_vertex_x[i];
if(raydium_vertex_y[i]<min[1])
min[1]=raydium_vertex_y[i];
if(raydium_vertex_z[i]<min[2])
min[2]=raydium_vertex_z[i];
if(raydium_vertex_x[i]>max[0])
max[0]=raydium_vertex_x[i];
if(raydium_vertex_y[i]>max[1])
max[1]=raydium_vertex_y[i];
if(raydium_vertex_z[i]>max[2])
max[2]=raydium_vertex_z[i];
}
/*tx=(max[0]-min[0]);
*ty=(max[1]-min[1]);
*tz=(max[2]-min[2]);*/
}
void raydium_object_find_center_factors(GLuint obj, GLfloat *tx, GLfloat *ty, GLfloat *tz)
{
GLfloat min[3];
GLfloat max[3];
raydium_object_find_minmax(obj,min,max);
*tx=(max[0]-((max[0]-min[0])/2));
*ty=(max[1]-((max[1]-min[1])/2));
*tz=(max[2]-((max[2]-min[2])/2));
(*tx)/=(max[0]-min[0]);
(*ty)/=(max[1]-min[1]);
(*tz)/=(max[2]-min[2]);
}
//////////////////////////////////////////////////////////
// Animation support starts here
GLint raydium_object_anim_find(int object, char *name)
{
int i;
if(!raydium_object_isvalid(object))
{
raydium_log("object: anim_find: ERROR: id or name is invalid");
return -1;
}
for(i=0;i<raydium_object_anims[object];i++)
if(!strcmp(raydium_object_anim_names[object][i],name))
return i;
return -1;
}
#define _pondavg(a,b,f) ( (a)+(((b)-(a))*(f)) )
// There's always a bug here, causing jitters when switching animation:
// frame_b jumps from "destination frame" to "destination frame"+1, as
// during normal operation
void raydium_object_anim_generate_internal(int object, int instance)
{
int i;
GLfloat factor;
int anim_frames;
int frame_a,frame_b;
int anim_current;
GLfloat anim_frame_current;
char flag;
if(!raydium_object_isvalid(object))
{
raydium_log("object: generate_internal: ERROR: id or name is invalid");
return;
}
// here starts the big job ! :)
anim_current=raydium_object_anim_current[object][instance];
anim_frame_current=raydium_object_anim_frame_current[object][instance];
// How many frames for the current anim ?
anim_frames=
raydium_object_anim_end[object][anim_current] -
raydium_object_anim_start[object][anim_current];
flag=0;
// slow ... :( (any good idea to make a modulo on a float ?)
while(anim_frame_current>(anim_frames+1))
{
anim_frame_current-=(anim_frames+1);
flag=1;
}
// end of ponctually anim ?
if(flag && raydium_object_anim_punctually_flag[object][instance]>=0)
{
raydium_object_anim_punctually_flag[object][instance]=-1;
raydium_object_anim(object,instance,raydium_object_anim_default_anim[object]);
raydium_object_anim_frame(object,instance,0);
// recursive call with regular situation
raydium_object_anim_generate_internal(object,instance);
return;
}
//printf("frame (int): %i\n",(int)raydium_object_anim_frame_current[object][instance]);
//printf("%f %i\n",raydium_object_anim_frame_current[object],anim_frames);
factor=anim_frame_current-(int)anim_frame_current;
frame_a=raydium_object_start[object]+
(raydium_object_anim_start[object][anim_current] *
raydium_object_anim_len[object]) +
(((int)anim_frame_current) *
raydium_object_anim_len[object]) +
raydium_object_anim_len[object];
if( ((int)anim_frame_current) >= anim_frames)
{
frame_b=raydium_object_start[object] +
(raydium_object_anim_start[object][anim_current] *
raydium_object_anim_len[object]) +
raydium_object_anim_len[object];
}
else
frame_b=frame_a+raydium_object_anim_len[object];
// if we come from another anim, let's erase frame_a
if(raydium_object_anim_previous[object][instance]>=0)
{
// is it the first pass right after anim change ?
if(raydium_object_anim_frame_previous_timeout[object][instance]==-1)
{
// save current frame
raydium_object_anim_frame_previous_timeout[object][instance]=raydium_object_anim_frame_current[object][instance];
//printf("*** start\n");
}
// We're now in current anim, cancel previous one
if(raydium_object_anim_frame_current[object][instance]-raydium_object_anim_frame_previous_timeout[object][instance]>=1)
{
raydium_object_anim_previous[object][instance]=-1;
//printf("*** end\n");
}
else
{
// ... erase frame_a
//printf("%f| erasing %i (%f)",anim_frame_current,anim_current,anim_frame_current);
anim_current=raydium_object_anim_previous[object][instance];
anim_frame_current=raydium_object_anim_frame_previous[object][instance];
anim_frames=
raydium_object_anim_end[object][anim_current] -
raydium_object_anim_start[object][anim_current];
// slow ... :( (any good idea to make a modulo on a float ?)
while(anim_frame_current>(anim_frames+1))
anim_frame_current-=(anim_frames+1);
//printf(" with %i (%f)\n",anim_current,anim_frame_current);
factor=(raydium_object_anim_frame_current[object][instance]-raydium_object_anim_frame_previous_timeout[object][instance]);
frame_a=raydium_object_start[object]+
(raydium_object_anim_start[object][anim_current] *
raydium_object_anim_len[object]) +
(((int)anim_frame_current) *
raydium_object_anim_len[object]) +
raydium_object_anim_len[object];
}
//printf("refresh from %i/%i (a) and %i/%i (b), factor = %.2f (%i af)\n",frame_a,frame_a/raydium_object_anim_len[object],frame_b,frame_b/raydium_object_anim_len[object],factor,anim_frames);
}
//printf("refresh from %i/%i (a) and %i/%i (b), factor = %.2f (%i af)\n",frame_a,frame_a/raydium_object_anim_len[object],frame_b,frame_b/raydium_object_anim_len[object],factor,anim_frames);
for(i=0;i<raydium_object_anim_len[object];i++)
{
raydium_vertex_x[raydium_object_start[object]+i]=_pondavg(raydium_vertex_x[frame_a+i],raydium_vertex_x[frame_b+i],factor);
raydium_vertex_y[raydium_object_start[object]+i]=_pondavg(raydium_vertex_y[frame_a+i],raydium_vertex_y[frame_b+i],factor);
raydium_vertex_z[raydium_object_start[object]+i]=_pondavg(raydium_vertex_z[frame_a+i],raydium_vertex_z[frame_b+i],factor);
raydium_vertex_normal_visu_x[raydium_object_start[object]+i]=_pondavg(raydium_vertex_normal_visu_x[frame_a+i],raydium_vertex_normal_visu_x[frame_b+i],factor);
raydium_vertex_normal_visu_y[raydium_object_start[object]+i]=_pondavg(raydium_vertex_normal_visu_y[frame_a+i],raydium_vertex_normal_visu_y[frame_b+i],factor);
raydium_vertex_normal_visu_z[raydium_object_start[object]+i]=_pondavg(raydium_vertex_normal_visu_z[frame_a+i],raydium_vertex_normal_visu_z[frame_b+i],factor);
raydium_vertex_texture_u[raydium_object_start[object]+i]=_pondavg(raydium_vertex_texture_u[frame_a+i],raydium_vertex_texture_u[frame_b+i],factor);
raydium_vertex_texture_v[raydium_object_start[object]+i]=_pondavg(raydium_vertex_texture_v[frame_a+i],raydium_vertex_texture_v[frame_b+i],factor);
raydium_vertex_texture[raydium_object_start[object]+i]=raydium_vertex_texture[frame_a+i];
}
}
void raydium_object_anim_frame(int object, int instance, GLfloat frame)
{
if(!raydium_object_isvalid(object))
{
raydium_log("object: anim_frame: ERROR: id or name is invalid");
return;
}
raydium_object_anim_frame_current[object][instance]=frame;
}
void raydium_object_anim_frame_name(char *object, int instance, GLfloat frame)
{
raydium_object_anim_frame(raydium_object_find_load(object),instance,frame);
}
void raydium_object_anim(int object, int instance, int anim)
{
if(!raydium_object_isvalid(object))
{
raydium_log("object: anim: ERROR: id or name is invalid");
return;
}
if(anim<0 || anim>=raydium_object_anims[object])
{
raydium_log("object: anim: ERROR: id or name is invalid for animation");
return;
}
if(raydium_object_anim_current[object][instance]==anim)
return;
//printf("%i asked %i\n",raydium_object_anim_current[object][instance],anim);
// warning, change anim BEFORE anim's frame
raydium_object_anim_previous[object][instance]=raydium_object_anim_current[object][instance];
raydium_object_anim_frame_previous[object][instance]=raydium_object_anim_frame_current[object][instance];
raydium_object_anim_frame_previous_timeout[object][instance]=-1;
raydium_object_anim_current[object][instance]=anim;
}
void raydium_object_anim_name(char *object, int instance, char *anim)
{
int o;
o=raydium_object_find_load(object);
raydium_object_anim(o,instance,raydium_object_anim_find(o,anim));
}
void raydium_object_anim_instance(int object, int instance)
{
if(!raydium_object_isvalid(object))
{
raydium_log("object: anim_instance: ERROR: id or name is invalid");
return;
}
raydium_object_anim_instance_current[object]=instance;
}
void raydium_object_anim_instance_name(char *object, int instance)
{
raydium_object_anim_instance(raydium_object_find_load(object),instance);
}
void raydium_object_anim_automatic(int object, int anim, GLfloat factor)
{
if(!raydium_object_isvalid(object))
{
raydium_log("object: anim_automatic: ERROR: id or name is invalid");
return;
}
if(anim<0 || anim>=raydium_object_anims[object])
{
raydium_log("object: anim_automatic: ERROR: id or name is invalid for animation");
return;
}
//printf("%i %i %f\n",object,anim,factor);
raydium_object_anim_automatic_factor[object][anim]=factor;
}
void raydium_object_anim_automatic_name(char *object, char *anim, GLfloat factor)
{
int o;
o=raydium_object_find_load(object);
raydium_object_anim_automatic(o,raydium_object_anim_find(o,anim),factor);
}
void raydium_object_callback(void)
{
GLfloat f;
int o,i;
for(o=0;o<raydium_object_index;o++)
if(raydium_object_anims[o]>0)
for(i=0;i<RAYDIUM_MAX_OBJECT_ANIM_INSTANCES;i++)
{
f=raydium_frame_time * raydium_object_anim_time_factor *
raydium_object_anim_automatic_factor[o][raydium_object_anim_current[o][i]];
raydium_object_anim_frame_current[o][i]+=f;
}
}
void raydium_object_anim_default(int object, int anim)
{
if(!raydium_object_isvalid(object))
{
raydium_log("object: anim_default: ERROR: id or name is invalid");
return;
}
if(anim<0 || anim>=raydium_object_anims[object])
{
raydium_log("object: anim_default: ERROR: id or name is invalid for animation");
return;
}
raydium_object_anim_default_anim[object]=anim;
}
signed char raydium_object_anim_ispunctually(int object, int instance)
{
if(!raydium_object_isvalid(object))
{
raydium_log("object: anim_isdefault: ERROR: id or name is invalid");
return 0;
}
return (raydium_object_anim_punctually_flag[object][instance]>=0?1:0);
}
signed char raydium_object_anim_ispunctually_name(char *object, int instance)
{
return raydium_object_anim_ispunctually(raydium_object_find_load(object),instance);
}
// punctually (change current and set flag. set frame to 0 [in,out])
void raydium_object_anim_punctually(int object, int anim, int instance)
{
if(!raydium_object_isvalid(object))
{
raydium_log("object: anim_punctually: ERROR: id or name is invalid");
return;
}
if(anim<0 || anim>=raydium_object_anims[object])
{
raydium_log("object: anim_punctually: ERROR: id or name is invalid for animation");
return;
}
raydium_object_anim(object,instance,anim);
raydium_object_anim_frame(object,instance,0);
raydium_object_anim_punctually_flag[object][instance]=anim;
}
void raydium_object_anim_punctually_name(char *object, char *anim, int instance)
{
int o;
o=raydium_object_find_load(object);
raydium_object_anim_punctually(o,raydium_object_anim_find(o,anim),instance);
}
// no loops for some animation (death)

4102
raydium/ode.c Normal file

File diff suppressed because it is too large Load Diff

275
raydium/ode.h Normal file
View File

@ -0,0 +1,275 @@
/*
Raydium - CQFD Corp.
http://raydium.org/
License: GPL - GNU General Public License, see "gpl.txt" file.
*/
#ifndef RAY_ODE_H
#define RAY_ODE_H
#ifdef __cplusplus
// ugly workaround to avoid odemath.h ...
#define _ODE_ODEMATH_H_
#endif
#include "../ode/include/ode/ode.h"
#define RAYDIUM_ODE_MAX_OBJECTS 64
#define RAYDIUM_ODE_MAX_ELEMENTS 256
#define RAYDIUM_ODE_MAX_JOINTS 256
#define RAYDIUM_ODE_MAX_MOTORS 64
#define RAYDIUM_ODE_MAX_EXPLOSIONS 32
#define RAYDIUM_ODE_MOTOR_MAX_JOINTS 10
#define RAYDIUM_ODE_MOTOR_MAX_GEARS 10
#define RAYDIUM_ODE_ELEMENT_MAX_FIXING 10
#define RAYDIUM_ODE_PHYSICS_FREQ 400
#define RAYDIUM_ODE_TIMESTEP (0.006f)
#define RAYDIUM_ODE_AUTODETECT -1
#define RAYDIUM_ODE_STANDARD 1
#define RAYDIUM_ODE_STATIC 2
#define RAYDIUM_ODE_FIXING 3
#define RAYDIUM_ODE_MOTOR_ENGINE 1
#define RAYDIUM_ODE_MOTOR_ANGULAR 2
#define RAYDIUM_ODE_MOTOR_ROCKET 3
#define RAYDIUM_ODE_JOINT_AXE_X 1,0,0
#define RAYDIUM_ODE_JOINT_AXE_Y 0,1,0
#define RAYDIUM_ODE_JOINT_AXE_Z 0,0,1
#define RAYDIUM_ODE_JOINT_SUSP_DEFAULT_AXES RAYDIUM_ODE_JOINT_AXE_Z,RAYDIUM_ODE_JOINT_AXE_Y
#define RAYDIUM_ODE_JOINT_FIXED -10
#define RAYDIUM_ODE_MATERIAL_HARD 0.9,0.1
#define RAYDIUM_ODE_MATERIAL_MEDIUM 0.5,0.5
#define RAYDIUM_ODE_MATERIAL_SOFT 0.1,0.9
#define RAYDIUM_ODE_MATERIAL_SOFT2 0.0,0.9
#define RAYDIUM_ODE_MATERIAL_DEFAULT RAYDIUM_ODE_MATERIAL_HARD
#define RAYDIUM_ODE_SLIP_ICE 5.f
#define RAYDIUM_ODE_SLIP_PLAYER 10.f
#define RAYDIUM_ODE_SLIP_NORMAL 0.4f
#define RAYDIUM_ODE_SLIP_DEFAULT RAYDIUM_ODE_SLIP_NORMAL
#define RAYDIUM_ODE_TAG_EXPLOSION -1
#define RAYDIUM_ODE_TAG_GROUND -2
#define RAYDIUM_ODE_NETWORK_OPTIMAL -1
#define RAYDIUM_ODE_NETWORK_MAXFREQ 20
#define RAYDIUM_ODE_NETWORK_EXPLOSION_EXPL 1
#define RAYDIUM_ODE_NETWORK_EXPLOSION_BLOW 2
// do not change values, some other file are using numeric values ! (shadows)
#define RAYDIUM_ODE_DRAW_NORMAL 0
#define RAYDIUM_ODE_DRAW_DEBUG 1
#define RAYDIUM_ODE_DRAW_AABB 2
#define RAYDIUM_ODE_DRAW_RAY 3
#define RAYDIUM_ODE_DRAW_SHADOWERS 4
#define RAYDIUM_ODE_DRAW_NORMAL_NO_POST 5
__global dWorldID raydium_ode_world;
__global dSpaceID raydium_ode_space;
__global dJointGroupID raydium_ode_contactgroup;
__global int raydium_ode_ground_mesh;
__global GLint raydium_ode_timecall; // read only (timecall index for ode callback)
__global void * raydium_ode_CollideCallback; // signed char f(int,int,dContact*)
__global void * raydium_ode_StepCallback; // void f(void)
__global void * raydium_ode_ObjectNearCollide; // signed char f(int,int)
__global void * raydium_ode_RayCallback; // signed char f(int,int,dContact*)
__global signed char raydium_ode_network_distant_create;
__global signed char raydium_ode_network_next_local_only;
__global signed char raydium_ode_network_explosion_create;
__global int raydium_ode_network_maxfreq;
__global void * raydium_ode_ExplosionCallback; // void f(signed char,dReal,dReal,dReal *)
__global void * raydium_ode_BeforeElementDrawCallback;
__global void * raydium_ode_AfterElementDrawCallback;
__global signed char raydium_ode_element_delete_LOCK;
typedef struct raydium_ode_Explosion // used for "blowing" explosions
{
int id;
char name[RAYDIUM_MAX_NAME_LEN];
signed char state;
dReal config_radius; // desired radius
dReal config_propag; // propagation speed (increment to config_radius)
dReal radius; // current radius
int element;
dReal position[3];
} raydium_ode_Explosion;
typedef struct raydium_ode_Joint
{
int id;
char name[RAYDIUM_MAX_NAME_LEN];
signed char state;
int mesh; // not used for joints, yet
signed char hinge2correct; // this hinge2 needs to be re-aligned each timestep
signed char motored; // powered by a motor ?
dReal motorforce;
dReal breakableforce; // is breakable ? (max force without braking)
signed char breaking; // is currently breaking (used as a tag for OnDelete)
dJointID joint;
void * OnDelete; // pointer to OnDelete user callback
} raydium_ode_Joint;
typedef struct raydium_ode_Motor
{
int id;
char name[RAYDIUM_MAX_NAME_LEN];
signed char state;
int object; // owner
int joints[RAYDIUM_ODE_MOTOR_MAX_JOINTS]; // attached to ... (joints)
int joints_axe[RAYDIUM_ODE_MOTOR_MAX_JOINTS]; // wich axe ? (joint relative)
int rocket_element; // rocket only: attached to this element
dReal rocket_direction[3]; // rocket only (relative to element)
dReal rocket_orientation[3]; // rocket only (relative to element)
dReal rocket_position[3]; // rocket only (relative to element)
signed char rocket_playermovement; // this rocket is used for a FPS player
dReal speed; // "engine style" motor: desired speed
dReal angle; // "angular style" motor: desired angle
dReal force; // all styles (engine, angular and rocket)
dReal gears[RAYDIUM_ODE_MOTOR_MAX_GEARS]; // gear box factors
int gear; // current gear
int gear_max; // max gear
} raydium_ode_Motor;
typedef struct raydium_ode_ElementInternalSave
{
char name[RAYDIUM_MAX_NAME_LEN];
int type; // ODE geom type
dReal sphere_radius;
dReal box_sizes[3];
dReal mass;
int object;
int mesh;
dReal slip;
dReal cfm;
dReal erp;
dReal rel_pos[3];
dReal rel_rot[4];
void *user_data;
int user_tag;
void *OnBlow;
void *OnDelete;
} raydium_ode_ElementInternalSave;
// Warning: there's a sample of this in doc. Sync when you change something here.
typedef struct raydium_ode_Ray
{
signed char state; // is this ray active ?
dGeomID geom;
//signed char visible; // use "drawing debug" to display the ray
dReal rel_dir[3];
// farest contact
dReal max_dist;
int max_elem;
dReal max_pos[3];
// nearest contact
dReal min_dist;
int min_elem;
dReal min_pos[3];
} raydium_ode_Ray;
typedef struct raydium_ode_Element
{
int id;
char name[RAYDIUM_MAX_NAME_LEN];
signed char state;
int object;
int mesh;
signed char _touched; // touched during very last timestep
signed char _movesfrom; // is leaving this object to "object" member
signed char _avoidedcol; // is any collision was avoided because of this move ?
signed char isplayer; // is this element an FPS player ? ("standing elem")
dReal playerangle; // FPS player angle
dReal slip; // slipping factor
dReal rotfriction; // rotation friction factor (avoid infinite rolling spheres)
dGeomID geom;
dBodyID body;
dReal erp;
dReal cfm;
void * user_data; // point to user data
int user_tag; // tag reseverd to user (this tag is networked)
raydium_ode_ElementInternalSave *fixed_elements[RAYDIUM_ODE_ELEMENT_MAX_FIXING];
int nid; // network ID
signed char distant; // owned by a distant machine
int distant_owner;
time_t lastnetupdate;
void * OnBlow; // when touched by a blowing explosion void (*f)(int,dReal,dReal)
void * OnDelete; // int (*f)(int)
int ttl; // time to live, -1 for infinite (default)
int particle;
dReal particle_offset[3];
unsigned long net_last_time;
dReal net_last_pos1[3];
dReal net_last_pos2[3];
dReal netvel[3]; // test
unsigned long net_last_interval;
int ground_texture;
signed char marked_as_deleted;
raydium_ode_Ray ray;
} raydium_ode_Element;
typedef struct raydium_ode_Object
{
int id;
char name[RAYDIUM_MAX_NAME_LEN];
signed char state;
signed char colliding; // elements of this objet can collide each other
dSpaceID group;
// dGeomID group;
} raydium_ode_Object;
typedef struct raydium_ode_network_Event
{
int nid;
dReal pos[3];
dReal rot[4];
dReal vel[3]; // test
} raydium_ode_network_Event;
typedef struct raydium_ode_network_Explosion
{
signed char type; // RAYDIUM_ODE_NETWORK_EXPLOSION_* (EXPL or BLOW)
dReal pos[3];
dReal radius;
dReal force; // BLOW only
dReal propag; // EXPL only
} raydium_ode_network_Explosion;
__global raydium_ode_Object raydium_ode_object[RAYDIUM_ODE_MAX_OBJECTS];
__global raydium_ode_Element raydium_ode_element[RAYDIUM_ODE_MAX_ELEMENTS+1]; // the last element is used for "static joint"
__global raydium_ode_Joint raydium_ode_joint[RAYDIUM_ODE_MAX_JOINTS];
__global raydium_ode_Motor raydium_ode_motor[RAYDIUM_ODE_MAX_MOTORS];
__global raydium_ode_Explosion raydium_ode_explosion[RAYDIUM_ODE_MAX_EXPLOSIONS];
/*
void raydium_ode_callback(void);
int raydium_ode_object_create(char *);
void raydium_ode_motor_rocket_orientation(int m, dReal rx, dReal ry, dReal rz);
int raydium_ode_object_find(char *name);
char raydium_ode_element_material(int e, dReal erp, dReal cfm);
char raydium_ode_element_slip(int e, dReal slip);
char raydium_ode_object_colliding(int o, char colliding);
char raydium_ode_element_delete(int e, char deletejoints);
void raydium_ode_element_move(int elem, dReal *pos);
dReal *raydium_ode_element_pos_get(int j);
*/
void raydium_ode_network_init(void);
void raydium_ode_network_element_delete(int e);
void raydium_ode_network_element_new(int e);
void raydium_ode_network_read(void);
int raydium_network_nid_element_find(int nid);
int raydium_ode_network_MaxElementsPerPacket(void);
void raydium_ode_network_explosion_send(raydium_ode_network_Explosion *exp);
void raydium_ode_network_element_trajectory_correct(int elem);
// (#ifdef RAY_ODE_H)
#endif

602
raydium/ode_net.c Normal file
View File

@ -0,0 +1,602 @@
/*
Raydium - CQFD Corp.
http://raydium.org/
License: GPL - GNU General Public License, see "gpl.txt" file.
*/
// This .c file is included from ode.c, so there's no includes here.
void raydium_ode_network_element_new(int e);
int raydium_ode_network_MaxElementsPerPacket(void)
{
return ((RAYDIUM_NETWORK_PACKET_SIZE-RAYDIUM_NETWORK_PACKET_OFFSET)/sizeof(raydium_ode_network_Event)-1);
}
int raydium_network_nid_element_find(int nid)
{
int i;
for(i=0;i<RAYDIUM_ODE_MAX_ELEMENTS;i++)
if(raydium_ode_element[i].state && raydium_ode_element[i].nid==nid)
return i;
return -1;
}
void raydium_ode_network_newdel_event(int type,char *buff)
{
int id;
int nid,dec,elem;
int tag;
dReal get[4];
dReal default_pos[3]={0,0,9999};
id=buff[1];
if(id==raydium_network_uid) return; // do not update our elements
//raydium_log("ode_net: new or del event received... (%i)",type);
dec=RAYDIUM_NETWORK_PACKET_OFFSET;
memcpy(&nid,buff+dec,sizeof(int));
elem=raydium_network_nid_element_find(nid);
dec+=sizeof(int);
if(type==RAYDIUM_NETWORK_PACKET_ODE_NEWELEM)
{
int type;
char mesh[RAYDIUM_MAX_NAME_LEN];
char name[RAYDIUM_MAX_NAME_LEN];
int group;
// raydium_log("ode_net: NEWELEM event, from %i",buff[1]);
// if we already have this element, refresh it
if(elem>=0)
raydium_ode_element_delete(elem,1);
memcpy(&type,buff+dec,sizeof(int));
dec+=sizeof(int);
memcpy(get,buff+dec,sizeof(dReal)*3);
dec+=(sizeof(dReal)*3);
memcpy(&tag,buff+dec,sizeof(int));
dec+=sizeof(int);
strcpy(mesh,buff+dec);
sprintf(name,"net_%i",nid); // may use the other side element name ?
group=raydium_ode_object_find("DISTANT");
switch(type)
{
case dSphereClass:
raydium_ode_network_distant_create=1;
elem=raydium_ode_object_sphere_add(name,group,1,get[0],RAYDIUM_ODE_STATIC,tag,mesh);
break;
case dBoxClass:
raydium_ode_network_distant_create=1;
elem=raydium_ode_object_box_add(name,group,1,get[0],get[1],get[2],RAYDIUM_ODE_STATIC,tag,mesh);
break;
}
raydium_ode_element[elem].distant_owner=buff[1];
raydium_ode_element[elem].nid=nid;
raydium_ode_element[elem].lastnetupdate=time(NULL);
raydium_ode_element_move(elem,default_pos);
// raydium_log("ode_net: ... new: %s",raydium_ode_element[elem].name);
}
if(type==RAYDIUM_NETWORK_PACKET_ODE_REMELEM)
{
if(elem<0) return;
if(!raydium_ode_element[elem].distant) return;
raydium_ode_element_delete(elem,1);
// raydium_log("ode_net: ... delete: %s",raydium_ode_element[elem].name);
}
}
void raydium_ode_network_nidwho_event(int type,char *buff)
{
int nid,elem;
memcpy(&nid,buff+RAYDIUM_NETWORK_PACKET_OFFSET,sizeof(int));
elem=raydium_network_nid_element_find(nid);
if(elem<0) return;
// test if we are owner of elem
if(!raydium_ode_element[elem].distant)
{
//raydium_log("ode_net: sending answer to nidwho request for %s",raydium_ode_element[elem].name);
raydium_ode_network_element_new(elem);
}
}
void raydium_ode_network_explosion_event(int type,char *buff)
{
raydium_ode_network_Explosion *exp;
exp=(raydium_ode_network_Explosion *)(buff+RAYDIUM_NETWORK_PACKET_OFFSET);
raydium_ode_network_explosion_create=1; // really create explosion
if(exp->type==RAYDIUM_ODE_NETWORK_EXPLOSION_EXPL)
{
// needs to (automaticaly) generates a "name" for explosions
char name[RAYDIUM_MAX_NAME_LEN];
raydium_ode_name_auto("net_expl",name);
raydium_ode_explosion_create(name,exp->radius,exp->propag,exp->pos);
}
if(exp->type==RAYDIUM_ODE_NETWORK_EXPLOSION_BLOW)
raydium_ode_explosion_blow(exp->radius,exp->force,exp->pos);
// Useless, but...
raydium_ode_network_explosion_create=0;
}
void raydium_ode_network_init(void)
{
char opt[128];
raydium_ode_network_maxfreq=RAYDIUM_ODE_NETWORK_MAXFREQ;
raydium_network_netcall_add(raydium_ode_network_newdel_event,RAYDIUM_NETWORK_PACKET_ODE_NEWELEM,1);
raydium_network_netcall_add(raydium_ode_network_newdel_event,RAYDIUM_NETWORK_PACKET_ODE_REMELEM,1);
raydium_network_netcall_add(raydium_ode_network_nidwho_event,RAYDIUM_NETWORK_PACKET_ODE_NIDWHO,1);
raydium_network_netcall_add(raydium_ode_network_explosion_event,RAYDIUM_NETWORK_PACKET_ODE_EXPLOSION,1);
if(raydium_init_cli_option("ode-rate",opt))
raydium_ode_network_maxfreq=atoi(opt);
raydium_ode_object_create("DISTANT");
raydium_ode_object_colliding_name("DISTANT",0);
}
signed char raydium_ode_network_TimeToSend(void)
{
static float time;
time+=raydium_frame_time;
if(time > (1.0/raydium_ode_network_maxfreq))
{
time=0;
return 1;
}
return 0;
}
// Refresh elements pos/rot to network
void raydium_ode_network_element_send(short nelems, int *e)
{
char data[RAYDIUM_NETWORK_PACKET_SIZE];
raydium_ode_network_Event set;
int dec;
int i;
short real=0;
dReal q[4];
dReal *p;
if(raydium_network_mode!=RAYDIUM_NETWORK_MODE_CLIENT)
return;
dec=RAYDIUM_NETWORK_PACKET_OFFSET;
dec+=sizeof(nelems);
for(i=0;i<nelems;i++)
{
if(!raydium_ode_element_isvalid(e[i])) continue;
if(raydium_ode_element[e[i]].nid<0) continue;
if(raydium_ode_element[e[i]].distant) continue;
set.nid=raydium_ode_element[e[i]].nid;
p=raydium_ode_element_pos_get(e[i]);
memcpy(set.pos,p,sizeof(dReal)*3);
raydium_ode_element_rotq_get(e[i],q);
memcpy(set.rot,q,sizeof(dReal)*4);
p=raydium_ode_element_linearvelocity_get(e[i]);
memcpy(set.vel,p,sizeof(dReal)*3);
memcpy(data+dec,&set,sizeof(set));
dec+=sizeof(set);
real++;
if(dec>=RAYDIUM_NETWORK_PACKET_SIZE)
{
raydium_log("ode_net: PACKET SIZE TOO SMALL !");
return;
}
}
memcpy(data+RAYDIUM_NETWORK_PACKET_OFFSET,&real,sizeof(real));
raydium_network_write(NULL,raydium_network_uid,RAYDIUM_NETWORK_PACKET_ODE_DATA,data);
}
void raydium_ode_network_element_send_all(void)
{
int i,n;
int e[RAYDIUM_ODE_MAX_ELEMENTS];
if(!raydium_ode_network_TimeToSend()) return;
n=0;
for(i=0;i<RAYDIUM_ODE_MAX_ELEMENTS;i++)
if(raydium_ode_element_isvalid(i) &&
raydium_ode_element[i].nid>=0 )
{
e[n]=i;
n++;
}
raydium_ode_network_element_send(n,e);
}
void raydium_ode_network_element_send_random(int nelems)
{
int i=0;
int n;
int done[RAYDIUM_ODE_MAX_ELEMENTS];
int e[RAYDIUM_ODE_MAX_ELEMENTS];
int total=0;
if(!raydium_ode_network_TimeToSend()) return;
if(nelems==RAYDIUM_ODE_NETWORK_OPTIMAL)
nelems=raydium_ode_network_MaxElementsPerPacket();
memset(done,0,RAYDIUM_ODE_MAX_ELEMENTS*sizeof(int));
while(i<nelems)
{
n=raydium_random_i(0,RAYDIUM_ODE_MAX_ELEMENTS);
if(raydium_ode_element[n].state && raydium_ode_element[n].nid>=0 && !done[n])
{
done[n]=1;
e[i]=n;
i++;
}
total++;
if(total>RAYDIUM_ODE_MAX_ELEMENTS) break;
}
raydium_ode_network_element_send(i,e);
}
void raydium_ode_network_element_send_iterative(int nelems)
{
static int curr=-1;
int i=0;
int e[RAYDIUM_ODE_MAX_ELEMENTS];
int total=0;
if(!raydium_ode_network_TimeToSend()) return;
if(nelems==RAYDIUM_ODE_NETWORK_OPTIMAL)
nelems=raydium_ode_network_MaxElementsPerPacket();
while(i<nelems)
{
curr++;
if(curr>=RAYDIUM_ODE_MAX_ELEMENTS) curr=0;
if(raydium_ode_element[curr].state && raydium_ode_element[curr].nid>=0)
{
e[i]=curr;
i++;
}
total++;
if(total>RAYDIUM_ODE_MAX_ELEMENTS) break;
}
raydium_ode_network_element_send(i,e);
}
void raydium_ode_network_nidwho(int nid)
{
char data[RAYDIUM_NETWORK_PACKET_SIZE];
// limit nidwho req freq
if(!raydium_ode_network_TimeToSend()) return;
memcpy(data+RAYDIUM_NETWORK_PACKET_OFFSET,&nid,sizeof(int));
raydium_network_write(NULL,raydium_network_uid,RAYDIUM_NETWORK_PACKET_ODE_NIDWHO,data);
}
void raydium_ode_network_apply(raydium_ode_network_Event *ev)
{
int elem,i;
unsigned long now;
unsigned long before;
dReal factor;
dReal *pos;
dReal Pcross[3];
elem=raydium_network_nid_element_find(ev->nid);
if(elem<0)
{
// ask for this nid:
raydium_ode_network_nidwho(ev->nid);
return; // nid not found.. unknown element !
}
raydium_ode_element[elem].lastnetupdate=time(NULL);
// must test time modulo here !
now=raydium_timecall_clock();
before=raydium_ode_element[elem].net_last_time;
raydium_ode_element[elem].net_last_interval=now-raydium_ode_element[elem].net_last_time;
raydium_ode_element[elem].net_last_time=now;
raydium_ode_element_rotateq(elem,ev->rot);
if(!before || raydium_timecall_interval[raydium_ode_timecall]==0)
{
raydium_ode_element_move(elem,ev->pos);
memcpy(raydium_ode_element[elem].netvel,ev->vel,sizeof(dReal)*3);
#ifdef DEBUG_ODENET
raydium_log("%i elem's first update (or 0 hz ODE callback)",elem);
#endif
}
else
{
// we must modify "netvel" to force reconciliation
pos=raydium_ode_element_pos_get(elem);
factor=((raydium_ode_element[elem].net_last_interval/(float)raydium_timecall_clocks_per_sec)*(float)RAYDIUM_ODE_PHYSICS_FREQ)*RAYDIUM_ODE_TIMESTEP;
#ifdef DEBUG_ODENET
raydium_log("ODE 1 sec factor : %f",factor);
#endif
if(factor<0.01) // probably another packet from the same read loop
{
for(i=0;i<3;i++)
raydium_ode_element[elem].netvel[i]=0;
return;
}
// 1 - determine probable next point (real and predi vectors cross point)
for(i=0;i<3;i++)
Pcross[i]=ev->pos[i]+
(ev->vel[i] * factor);
#ifdef DEBUG_ODENET
raydium_log("pcross = %f %f %f | pos = %f %f %f",Pcross[0],Pcross[1],Pcross[2],pos[0],pos[1],pos[2]);
#endif
// 2 - determine vector to this point from estimated last prediction (pos)
for(i=0;i<3;i++)
raydium_ode_element[elem].netvel[i]=(Pcross[i]-pos[i])/factor;
#ifdef DEBUG_ODENET
raydium_log("netvel = %f %f %f | org = %f %f %f",
raydium_ode_element[elem].netvel[0],
raydium_ode_element[elem].netvel[1],
raydium_ode_element[elem].netvel[2],
ev->vel[0],
ev->vel[1],
ev->vel[2]);
raydium_log("---");
#endif
// start previ (client side)... (may be unused)
//memcpy(raydium_ode_element[elem].net_last_pos2,raydium_ode_element[elem].net_last_pos1,sizeof(dReal)*3);
//memcpy(raydium_ode_element[elem].net_last_pos1,ev->pos,sizeof(dReal)*3);
// ... end previ
}
#ifndef ODE_PREDICTION
raydium_ode_element_move(elem,ev->pos);
raydium_ode_element_rotateq(elem,ev->rot);
#endif
#ifdef ODE_NETWORK_GHOSTS
{
// horrible... but usefull for debugging.
dMatrix3 R;
dQtoR(ev->rot,R);
ev->pos[0]+=0.01;
raydium_camera_replace_go(ev->pos,R);
raydium_object_draw(raydium_ode_element[elem].mesh);
//printf("ode_net: %s updated (packet usage: %i byte(s))\n", raydium_ode_element[elem].name,sizeof(*ev)+RAYDIUM_NETWORK_PACKET_OFFSET);
}
#endif
}
// Read new packets (flushed read must be an option !)
void raydium_ode_network_read(void)
{
signed char type;
int id,i;
short n;
char data[RAYDIUM_NETWORK_PACKET_SIZE];
raydium_ode_network_Event *get;
if(raydium_network_mode!=RAYDIUM_NETWORK_MODE_CLIENT)
return;
for(i=0;i<RAYDIUM_ODE_MAX_ELEMENTS;i++)
if(raydium_ode_element[i].nid>=0 &&
raydium_ode_element[i].distant &&
(time(NULL)>raydium_ode_element[i].lastnetupdate+RAYDIUM_NETWORK_TIMEOUT))
{
raydium_ode_element_delete(i,1);
//raydium_log("element %i deleted: timeout",i);
}
// read (flushed ?), and if RAYDIUM_NETWORK_PACKET_DATA, search nid and update pos/rot
if(raydium_network_read(&id,&type,data)!=RAYDIUM_NETWORK_DATA_OK)
//if(raydium_network_read_flushed(&id,&type,data)!=RAYDIUM_NETWORK_DATA_OK)
return;
#ifndef ODE_NETWORK_GHOSTS
if(id==raydium_network_uid)
return; // do not update our elements !
#endif
memcpy(&n,data+RAYDIUM_NETWORK_PACKET_OFFSET,sizeof(n));
if(type==RAYDIUM_NETWORK_PACKET_ODE_DATA)
for(i=0;i<n;i++)
{
get=(raydium_ode_network_Event *)(data+RAYDIUM_NETWORK_PACKET_OFFSET+sizeof(n)+(i*sizeof(*get)));
raydium_ode_network_apply(get);
}
}
// Add new element to network
void raydium_ode_network_element_new(int e)
{
char data[RAYDIUM_NETWORK_PACKET_SIZE];
int dec,i;
dReal set[3];
if(raydium_network_mode!=RAYDIUM_NETWORK_MODE_CLIENT)
return;
if(!raydium_ode_element_isvalid(e)) return;
if(raydium_ode_element[e].distant) return;
raydium_ode_element[e].nid=(raydium_network_uid+1)*1000+e;
dec=RAYDIUM_NETWORK_PACKET_OFFSET;
memcpy(data+dec,&raydium_ode_element[e].nid,sizeof(int));
dec+=sizeof(int);
i=dGeomGetClass(raydium_ode_element[e].geom);
memcpy(data+dec,&i,sizeof(int));
dec+=sizeof(int);
switch(i)
{
case dSphereClass:
set[0]=dGeomSphereGetRadius(raydium_ode_element[e].geom);
set[1]=set[2]=0;
break;
case dBoxClass:
dGeomBoxGetLengths(raydium_ode_element[e].geom,set);
break;
}
memcpy(data+dec,set,sizeof(dReal)*3);
dec+=(sizeof(dReal)*3);
memcpy(data+dec,&raydium_ode_element[e].user_tag,sizeof(int));
dec+=sizeof(int);
strncpy(data+dec,raydium_object_name[raydium_ode_element[e].mesh],RAYDIUM_NETWORK_PACKET_SIZE-dec-1);
data[RAYDIUM_NETWORK_PACKET_SIZE-1]='\0';
raydium_network_write(NULL,raydium_network_uid,RAYDIUM_NETWORK_PACKET_ODE_NEWELEM,data);
}
void raydium_ode_network_element_delete(int e)
{
char data[RAYDIUM_NETWORK_PACKET_SIZE];
int dec;
if(raydium_network_mode!=RAYDIUM_NETWORK_MODE_CLIENT)
return;
if(!raydium_ode_element_isvalid(e)) return;
if(raydium_ode_element[e].nid<0) return;
if(raydium_ode_element[e].distant) return;
dec=RAYDIUM_NETWORK_PACKET_OFFSET;
memcpy(data+dec,&raydium_ode_element[e].nid,sizeof(int));
dec+=sizeof(int);
raydium_network_write(NULL,raydium_network_uid,RAYDIUM_NETWORK_PACKET_ODE_REMELEM,data);
}
void raydium_ode_network_explosion_send(raydium_ode_network_Explosion *exp)
{
char data[RAYDIUM_NETWORK_PACKET_SIZE];
memcpy(data+RAYDIUM_NETWORK_PACKET_OFFSET,exp,sizeof(raydium_ode_network_Explosion));
raydium_network_write(NULL,raydium_network_uid,RAYDIUM_NETWORK_PACKET_ODE_EXPLOSION,data);
}
signed char raydium_ode_network_element_isdistant(int elem)
{
if(!raydium_ode_element_isvalid(elem))
{
raydium_log("ODE: Error: cannot get element 'is distant' flag: invalid name/index");
return 0;
}
return raydium_ode_element[elem].distant;
}
signed char raydium_ode_network_element_isdistant_name(char *elem)
{
return raydium_ode_network_element_isdistant(raydium_ode_element_find(elem));
}
signed char raydium_ode_network_element_distantowner(int elem)
{
if(!raydium_ode_element_isvalid(elem))
{
raydium_log("ODE: Error: cannot get element 'distant owner': invalid name/index");
return 0;
}
return raydium_ode_element[elem].distant_owner;
}
signed char raydium_ode_network_element_distantowner_name(char *elem)
{
return raydium_ode_network_element_distantowner(raydium_ode_element_find(elem));
}
void raydium_ode_network_element_trajectory_correct(int elem)
{
//dReal vector[3];
dReal pos[3];
dReal *cur;
//unsigned long now;
int i;
raydium_ode_Element *e;
if(!raydium_ode_element_isvalid(elem))
{
raydium_log("ODE: Error: cannot correct trajectory: invalid name/index");
return;
}
e=&raydium_ode_element[elem];
//now=raydium_timecall_clock();
// determine vector (last1 - last2)
//for(i=0;i<3;i++)
// vector[i]=e->net_last_pos1[i]-e->net_last_pos2[i];
// pos = last1 + ( vector * ( (now - last1) / interval ))
//for(i=0;i<3;i++)
// pos[i]=e->net_last_pos1[i] + ( vector[i] * ( (now - e->net_last_time) / (dReal)(e->net_last_interval) ));
// Use "dead reckoning" method :
cur=raydium_ode_element_pos_get(elem);
memcpy(pos,cur,sizeof(dReal)*3);
for(i=0;i<3;i++)
pos[i]+=(e->netvel[i]*RAYDIUM_ODE_TIMESTEP);
// pos[i]+=(e->netvel[i]/RAYDIUM_ODE_PHYSICS_FREQ);
//printf("cur = %f %f %f | next = %f %f %f (%f %f %f)\n",cur[0],cur[1],cur[2],pos[0],pos[1],pos[2],e->netvel[0],e->netvel[1],e->netvel[2]);
#ifdef ODE_PREDICTION
// pray.
raydium_ode_element_move(elem,pos);
#endif
}
void raydium_ode_network_elment_next_local(void)
{
raydium_ode_network_next_local_only=1;
}

566
raydium/osd.c Normal file
View File

@ -0,0 +1,566 @@
/*
Raydium - CQFD Corp.
http://raydium.org/
License: GPL - GNU General Public License, see "gpl.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);
//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);
}
// 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;
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]=='\n' || 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;
}
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);
glVertex3f(-size+dx,size,0);
glTexCoord2f(u+(1/16.f),v);
glVertex3f(size+dx,size,0);
glTexCoord2f(u+(1/16.f),v-(1/16.f));
glVertex3f(size+dx,-size,0);
glTexCoord2f(u,v-(1/16.f));
glVertex3f(-size+dx,-size,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;
GLdouble sx,sy,sz;
GLdouble modelMatrix[16];
GLdouble projectionMatrix[16];
GLint viewport[4];
va_start(argptr,format);
vsprintf(str,format,argptr);
va_end(argptr);
raydium_camera_replace();
glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix);
glGetDoublev(GL_PROJECTION_MATRIX, projectionMatrix);
glGetIntegerv(GL_VIEWPORT, viewport);
gluProject(x,y,z,modelMatrix,projectionMatrix,viewport,&sx,&sy,&sz);
sx=sx/raydium_window_tx*100;
sy=sy/raydium_window_ty*100;
if(sz<=1.0) raydium_osd_printf(sx,sy,size,spacer,texture,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_draw(void)
{
if(!raydium_osd_cursor_texture || !raydium_window_tx) return;
raydium_osd_start();
glTranslatef(((GLfloat)raydium_mouse_x/raydium_window_tx)*100.f,
((GLfloat)(raydium_window_ty-raydium_mouse_y)/raydium_window_ty)*100.f,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,0,0);
glTexCoord2f(1,0);
glVertex3f(raydium_osd_cursor_xsize,0,0);
glTexCoord2f(1,1);
glVertex3f(raydium_osd_cursor_xsize,-raydium_osd_cursor_ysize,0);
glTexCoord2f(0,1);
glVertex3f(0,-raydium_osd_cursor_ysize,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
}

252
raydium/parser.c Normal file
View File

@ -0,0 +1,252 @@
/*
Raydium - CQFD Corp.
http://raydium.org/
License: GPL - GNU General Public License, see "gpl.txt" file.
*/
#ifndef DONT_INCLUDE_HEADERS
#include "index.h"
#else
#include "headers/parser.h"
#endif
// proto
char * raydium_file_home_path(char *file);
// Trims string (left and right), removing ' ' and '\n' and ';'
void raydium_parser_trim(char *org)
{
int i;
char temp[RAYDIUM_MAX_NAME_LEN];
strcpy(temp,org);
for(i=0;i<strlen(temp);i++)
if(temp[i]!=' ')
break;
strcpy(org,temp+i); // heading spaces: ok
for(i=strlen(org);i>=0;i--)
if(org[i]!=' ' && org[i]!='\n' && org[i]!='\r' && org[i]!=0 && org[i]!=';')
break;
org[i+1]=0; // tailing chars: ok
}
signed char raydium_parser_isdata(char *str)
{
if(strlen(str)==0) return 0;
if(str[0]=='/' && str[1]=='/') return 0;
return 1;
}
signed char raydium_parser_cut(char *str,char *part1, char *part2, char separator)
{
// strstr, strok and strsep aren't that good ;)
int i;
int len;
len=strlen(str);
for(i=0;i<len+1;i++)
if(str[i]==separator)
break;
if(i==len+1) return 0; // not found
strcpy(part2,str+i+1);
strcpy(part1,str);
part1[i]=0;
raydium_parser_trim(part1);
raydium_parser_trim(part2);
return i+1;
}
void raydium_parser_replace(char *str,char what, char with)
{
int len,i;
len=strlen(str);
for(i=0;i<len;i++)
if(str[i]==what)
str[i]=with;
}
int raydium_parser_read(char *var, char *val_s, GLfloat *val_f, int *size, FILE *fp)
{
char str[RAYDIUM_MAX_NAME_LEN];
char *ret;
do {
str[0]=0;
ret=fgets(str,RAYDIUM_MAX_NAME_LEN-1,fp);
raydium_parser_trim(str);
} while(ret!=NULL && !raydium_parser_isdata(str));
if(ret==NULL)
{
*size=0;
return RAYDIUM_PARSER_TYPE_EOF;
}
raydium_parser_cut(str,var,val_s,'=');
if(val_s[0]=='[') // is raw data (RAYDIUM_MAX_NAME_LEN limit !)
{
int offset=0;
int len;
do {
str[0]=0;
ret=fgets(str,RAYDIUM_MAX_NAME_LEN-1,fp);
if(ret==NULL)
break;
if(strlen(str)>=1 && str[0]==']') // bad idea, but ... no time for now
break;
len=strlen(str);
memcpy(val_s+offset,str,len);
offset+=len;
} while(1);
val_s[offset]=0;
*size=offset;
return RAYDIUM_PARSER_TYPE_RAWDATA;
}
if(val_s[0]=='"') // is a string
{
raydium_parser_replace(val_s,'"',' ');
raydium_parser_trim(val_s);
*size=strlen(val_s);
return RAYDIUM_PARSER_TYPE_STRING;
}
if(val_s[0]=='{') // is a float array
{
char extracted[RAYDIUM_MAX_NAME_LEN];
char next[RAYDIUM_MAX_NAME_LEN];
*size=0;
raydium_parser_replace(val_s,'{',' ');
raydium_parser_trim(val_s);
while(raydium_parser_cut(val_s,extracted,next,','))
{
val_f[*size]=atof(extracted);
(*size)++;
strcpy(val_s,next);
}
val_f[*size]=atof(next);
(*size)++;
val_s[0]=0;
return RAYDIUM_PARSER_TYPE_FLOAT;
}
// is a float
*val_f=atof(val_s);
*size=1;
return RAYDIUM_PARSER_TYPE_FLOAT;
}
signed char raydium_parser_db_get(char *key, char *value, char *def)
{
FILE *fp;
char line[(RAYDIUM_MAX_NAME_LEN*2)+1];
char part1[RAYDIUM_MAX_NAME_LEN];
char part2[RAYDIUM_MAX_NAME_LEN];
signed char found=0;
fp=fopen(RAYDIUM_DB_FILENAME,"rt");
while( fp && (fgets(line,RAYDIUM_MAX_NAME_LEN,fp)) )
{
raydium_parser_trim(line);
if(!raydium_parser_cut(line,part1,part2,RAYDIUM_DB_SEPARATOR))
{
//raydium_log("db: ERROR: invalid: '%s'",line);
continue;
}
if(strcmp(part1,key))
continue;
found=1;
strcpy(value,part2);
}
if(fp)
fclose(fp);
if(!found && def)
{
strcpy(value,def);
found=1;
}
return found;
}
signed char raydium_parser_db_set(char *key, char *value)
{
FILE *fp,*out;
char line[(RAYDIUM_MAX_NAME_LEN*2)+1];
char part1[RAYDIUM_MAX_NAME_LEN];
char part2[RAYDIUM_MAX_NAME_LEN];
signed char found=0;
out=fopen(RAYDIUM_DB_TEMP,"wt");
if(!out)
{
raydium_log("db: cannot create new database !");
return 0;
}
fp=fopen(RAYDIUM_DB_FILENAME,"rt");
while( fp && (fgets(line,RAYDIUM_MAX_NAME_LEN,fp)) )
{
raydium_parser_trim(line);
if(!raydium_parser_cut(line,part1,part2,RAYDIUM_DB_SEPARATOR))
{
//raydium_log("db: ERROR: invalid: '%s'",line);
continue;
}
if(!strcmp(part1,key))
{
fprintf(out,"%s;%s\n",key,value);
found=1;
continue;
}
fprintf(out,"%s\n",line);
}
if(!found)
fprintf(out,"%s;%s\n",key,value);
if(fp)
fclose(fp);
fclose(out);
// We must use a temporary string (line), since raydium_file_home_path returns
// a static string so we cant call it twice the same time in rename().
unlink(RAYDIUM_DB_FILENAME); // since windows's rename is not POSIX
strcpy(line,RAYDIUM_DB_FILENAME);
if(rename(RAYDIUM_DB_TEMP,line)==-1)
{
raydium_log("db: cannot rename new database !");
perror("rename");
return 0;
}
return 1;
}

205
raydium/particle.c Normal file
View File

@ -0,0 +1,205 @@
///////////////////////////////////////////////////////
//
// !!! THIS FILE IS OLD !!!
// (used as a reference for new particle engine)
//
// See particle2.* files
//
///////////////////////////////////////////////////////
/*
Raydium - CQFD Corp.
http://raydium.org/
License: GPL - GNU General Public License, see "gpl.txt" file.
*/
// proto
void raydium_camera_replace(void);
void raydium_particle_init(GLuint expl, GLuint part)
{
raydium_particle_ttl[expl][part]=0;
}
void raydium_explosion_reset(GLuint exp)
{
GLuint i;
raydium_explosion_ttl[exp]=0;
for(i=0;i< RAYDIUM_MAX_PARTICLES;i++)
raydium_particle_init(exp,i);
}
void raydium_explosion_add(GLfloat x, GLfloat y, GLfloat z,
GLfloat vx, GLfloat vy, GLfloat vz,
GLfloat dispersion, GLuint ttl, GLfloat dens_perc,
GLfloat grav)
{
GLuint n=0; // gngngngngng ... debug !
raydium_explosion_reset(n);
raydium_explosion_ttl[n]=ttl;
raydium_explosion_x[n]=x;
raydium_explosion_y[n]=y;
raydium_explosion_z[n]=z;
raydium_explosion_vector_x[n]=vx;
raydium_explosion_vector_y[n]=vy;
raydium_explosion_vector_z[n]=vz;
raydium_explosion_dispersion[n]=dispersion;
raydium_explosion_gravity[n]=grav;
// we need to know how many particles to generate per frame,
// user gives us dens_perc, 0 < x < 100
raydium_explosion_density_pf[n]=((float)RAYDIUM_MAX_PARTICLES*dens_perc)/(float)100;
}
char raydium_particle_life(GLuint expl, GLuint part, GLuint *created)
{
char ret=0;
if(raydium_particle_ttl[expl][part]<=0 &&
raydium_explosion_ttl[expl]>0 &&
(*created)<raydium_explosion_density_pf[expl]) /* explosion alive, we can regenerate particle */
{
(*created)++;
//ret=1;
raydium_particle_ttl[expl][part]=RAYDIUM_MAX_PARTICLES/raydium_explosion_density_pf[expl];
// set particle
raydium_particle_x[expl][part]=raydium_explosion_x[expl];
raydium_particle_y[expl][part]=raydium_explosion_y[expl];
raydium_particle_z[expl][part]=raydium_explosion_z[expl];
// need to take direction vector
raydium_particle_ix[expl][part]=raydium_random_neg_pos_1()*raydium_explosion_dispersion[expl];
raydium_particle_iy[expl][part]=raydium_random_neg_pos_1()*raydium_explosion_dispersion[expl];
raydium_particle_iz[expl][part]=raydium_random_neg_pos_1()*raydium_explosion_dispersion[expl];
}
if(raydium_particle_ttl[expl][part]>0) // alive
{
ret=1;
// move particle
raydium_particle_x[expl][part]+=raydium_particle_ix[expl][part];
raydium_particle_y[expl][part]+=raydium_particle_iy[expl][part];
raydium_particle_z[expl][part]+=raydium_particle_iz[expl][part];
raydium_particle_iz[expl][part]-=raydium_explosion_gravity[expl];
raydium_particle_ttl[expl][part]--;
}
return ret;
}
void raydium_explosion_life(GLuint expl)
{
GLuint i;
char any_alive=0;
GLuint created=0;
for(i=0;i< RAYDIUM_MAX_PARTICLES;i++)
if(raydium_particle_life(expl,i,&created)) any_alive=1;
if(raydium_explosion_ttl[expl]>0) raydium_explosion_ttl[expl]--;
if(raydium_explosion_ttl[expl]==0 && any_alive) raydium_explosion_ttl[expl]=-1;
if(raydium_explosion_ttl[expl]<0 && !any_alive) raydium_explosion_ttl[expl]=0;
}
void raydium_explosion_callback(void)
{
GLuint i;
for(i=0;i< RAYDIUM_MAX_EXPLOSIONS;i++)
if(raydium_explosion_ttl[i]!=0)
raydium_explosion_life(i);
}
void raydium_explosion_draw_particles(GLuint expl)
{
GLuint i;
#define TSIZE ((float)0.5)
GLfloat modmat[16];
GLfloat ux;
GLfloat uy;
GLfloat uz;
GLfloat rx;
GLfloat ry;
GLfloat rz;
glGetFloatv(GL_MODELVIEW_MATRIX,modmat);
ux=modmat[0];
uy=modmat[4];
uz=modmat[8];
ux*=TSIZE/2;
uy*=TSIZE/2;
uz*=TSIZE/2;
rx=modmat[1];
ry=modmat[5];
rz=modmat[9];
rx*=TSIZE/2;
ry*=TSIZE/2;
rz*=TSIZE/2;
for(i=0;i< RAYDIUM_MAX_PARTICLES;i++)
if(raydium_particle_ttl[expl][i])
{
glBegin(GL_QUADS); // berk... but i'll switch to TRIANGLES one day ;)
glTexCoord2f(0.0f, 0.0f);
glVertex3f(raydium_particle_x[expl][i] + (-rx - ux),
raydium_particle_y[expl][i] + (-ry - uy),
raydium_particle_z[expl][i] + (-rz - uz));
glTexCoord2f(1.0f, 0.0f);
glVertex3f(raydium_particle_x[expl][i] + (rx - ux),
raydium_particle_y[expl][i] + (ry - uy),
raydium_particle_z[expl][i] + (rz - uz));
glTexCoord2f(1.0f, 1.0f);
glVertex3f(raydium_particle_x[expl][i] + (rx + ux),
raydium_particle_y[expl][i] + (ry + uy),
raydium_particle_z[expl][i] + (rz + uz));
glTexCoord2f(0.0f, 1.0f);
glVertex3f(raydium_particle_x[expl][i] + (ux - rx),
raydium_particle_y[expl][i] + (uy - ry),
raydium_particle_z[expl][i] + (uz - rz));
glEnd();
}
}
void raydium_explosion_draw_all(void)
{
GLuint i;
GLuint texsave;
char light;
texsave=raydium_texture_current;
light=raydium_light_enabled_tag;
raydium_light_disable();
if (raydium_camera_pushed) raydium_camera_replace(); // is it really our job to do it here ?
//raydium_rendering_internal_restore_render_state();
raydium_rendering_internal_prepare_texture_render(raydium_texture_current_set_name("flare.tga"));
glDepthMask(GL_FALSE);
for(i=0;i< RAYDIUM_MAX_EXPLOSIONS;i++)
if(raydium_explosion_ttl[i]!=0)
raydium_explosion_draw_particles(i);
glDepthMask(GL_TRUE);
if(light) raydium_light_enable();
raydium_texture_current_set(texsave);
//raydium_rendering_internal_prepare_texture_render(texsave);
}

Some files were not shown because too many files have changed in this diff Show More