26#include <libFreeWRL.h>
28#include "../ui/common.h"
29#include <scenegraph/Vector.h>
32#if defined (_MSC_VER) || defined (AQUA) || defined(QNX) || defined(_ANDROID) || defined(ANDROIDNDK)
33#include "../../buildversion.h"
42#if defined (_MSC_VER) || defined (AQUA) || defined(QNX) || defined(_ANDROID) || defined(ANDROIDNDK)
43const char *libFreeWRL_get_version(
void) {
return FW_BUILD_VERSION_STR;}
61 int target_frames_per_second;
62 char myMenuStatus[MAXSTAT];
63 char messagebar[MAXSTAT];
64 char SensorStatus[MAXSTAT];
67 char window_title[MAXTITLE];
75 int colorSchemeChanged;
86 int draw_bounding_boxes;
93void *common_constructor(){
94 void *v = MALLOCV(
sizeof(
struct pcommon));
95 memset(v,0,
sizeof(
struct pcommon));
98void common_init(
struct tcommon *t){
101 t->prv = common_constructor();
103 ppcommon p = (ppcommon)t->prv;
105 p->myFps = (float) 0.0;
106 p->cursorStyle = ACURSE;
107 p->sb_hasString = FALSE;
108 p->colorScheme = NULL;
109 p->colorSchemeChanged = 0;
110 p->pin_statusbar = 1;
113 p->want_statusbar = 1;
115 p->showConsoleText = 0;
116 p->target_frames_per_second = 120;
117 p->density_factor = 1.0f;
120 p->jsengine = JSENGINE_STUB;
121 p->draw_bounding_boxes = FALSE;
122 p->show_viewpoints = FALSE;
125 p->jsengine = JSENGINE_DUK;
128 p->jsengine = JSENGINE_SM;
129 p->jsengine_variant = 2;
130#ifdef JAVASCRIPT_ENGINE_VARIANT
131 p->jsengine_variant = JAVASCRIPT_ENGINE_VARIANT;
134 p->record_inputs = FALSE;
135 p->playback_inputs = FALSE;
138void common_clear(
struct tcommon *t){
142 ppcommon p = (ppcommon)t->prv;
145 for(i=0;i<vectorSize(p->keyvals);i++){
150 deleteVector(
keyval,p->keyvals);
154void splitpath3(
const char* url,
char** folder,
char** local_name,
char** suff);
156static FILE* frecord = NULL;
157FILE* getRecordFile() {
160 char* folder, * local_name, * suff;
161 splitpath3(gglobal()->Mainloop.url, &folder, &local_name, &suff);
162 strcpy(name, folder);
164 strcat(name, local_name);
165 strcat(name,
".fwplay");
166 frecord = fopen(name,
"w+");
170static double last_time, run_time;
171void record_touch(
int mev,
unsigned int ID,
int mouseX,
int mouseY,
int windex) {
172 ttglobal tg = gglobal();
173 FILE* f = getRecordFile();
174 double this_time = Time1970sec();
175 double delta_time = this_time -last_time;
176 last_time = this_time;
179 float fmouseX, fmouseY, scale;
180 scale = 2.0f / (float)tg->display.screenHeight;
181 fmouseY = (float)mouseY * scale - 1.0f;
182 fmouseX = (float)mouseX * scale - 1.0f;
183 fprintf(f,
"T,%d,%u,%f,%f,%d,%lf\n",mev,ID,fmouseX,fmouseY,windex,delta_time);
185void record_mouse(
int mev,
int butnum,
int mouseX,
int mouseY,
int windex) {
186 ttglobal tg = gglobal();
187 FILE* f = getRecordFile();
188 double this_time = Time1970sec();
189 double delta_time = this_time - last_time;
190 last_time = this_time;
193 float fmouseX, fmouseY, scale;
194 scale = 2.0f / (float)tg->display.screenHeight;
195 fmouseY = (float)mouseY * scale - 1.0f;
196 fmouseX = (float)mouseX * scale - 1.0f;
198 fprintf(f,
"M,%d,%d,%f,%f,%d,%lf\n",mev,butnum,fmouseX,fmouseY,windex,delta_time);
200void record_rawkeypress(
int key,
int type) {
201 FILE* f = getRecordFile();
202 double this_time = Time1970sec();
203 double delta_time = this_time - last_time;
204 last_time = this_time;
205 fprintf(f,
"K,%d,%d,%lf\n",
key, type, delta_time);
208void fwl_set_modeRecord() {
209 ppcommon p = (ppcommon)gglobal()->common.prv;
210 p->record_inputs = TRUE;
211 last_time = Time1970sec();
214void fwl_do_keyPress0(
int key,
int type);
215int fwl_handle_mouse0(
const int mev,
const unsigned int button,
int x,
int y,
int windex);
216int fwl_handle_touch0(
int mev,
unsigned int ID,
int mouseX,
int mouseY,
int windex);
218void updateCursorStyle0(
int cstyle);
221static pthread_t playback_thread;
222void _playbackthread(ttglobal tglobal) {
223 ttglobal tg = tglobal;
224 char name[300], line[300], cc;
225 int mev, butnum, mouseX, mouseY, windex, cstyle, ID,
key, type, iret;
226 float fmouseX, fmouseY, scale;
227 double delta_time, this_time, dtime;
228 char* folder, * local_name, * suff;
229 fwl_setCurrentHandle(tg, __FILE__, __LINE__);
230 while (tg->Mainloop.url == NULL) sleep(50);
231 splitpath3(tg->Mainloop.url, &folder, &local_name, &suff);
232 strcpy(name, folder);
234 strcat(name, local_name);
235 strcat(name,
".fwplay");
236 FILE *fplay = fopen(name,
"r+");
237 run_time = Time1970sec();
238 while (fscanf(fplay,
"%s", &line)>0) {
242 sscanf(line,
"%c,%d,%d,%f,%f,%d,%lf\n", &cc, &mev, &butnum, &fmouseX, &fmouseY, &windex, &dtime);
245 this_time = Time1970sec();
246 delta_time = run_time - this_time;
247 if (delta_time > 0.0) sleep((
int)(1000.0 * (delta_time)));
249 scale = 2.0f / (float)tg->display.screenHeight;
250 mouseY = (int)((fmouseY + 1.0)/scale + .5f);
251 mouseX = (int)((fmouseX + 1.0)/scale + .5f);
252 cstyle = fwl_handle_mouse0(mev, butnum, mouseX, mouseY, windex);
254 updateCursorStyle0(cstyle);
258 sscanf(line,
"%c,%d,%u,%f,%f,%d,%lf\n", &cc, &mev, &ID, &fmouseX, &fmouseY, &windex, &dtime);
260 this_time = Time1970sec();
261 delta_time = run_time - this_time;
262 if (delta_time > 0.0) sleep((
int)(1000.0 * (delta_time)));
264 scale = 2.0f / (float)tg->display.screenHeight;
265 mouseY = (int)(fmouseY + 1.0) / scale;
266 mouseX = (int)(fmouseX + 1.0) / scale;
267 cstyle = fwl_handle_touch0(mev, ID, mouseX, mouseY, windex);
269 updateCursorStyle0(cstyle);
273 sscanf(line,
"%c,%d,%d,%lf\n", &cc, &
key, &type, &dtime);
275 this_time = Time1970sec();
276 delta_time = run_time - this_time;
277 if (delta_time > 0.0) sleep((
int)(1000.0 * (delta_time)));
278 fwl_do_keyPress0(
key, type);
283void fwl_set_modePlayback() {
284 ppcommon p = (ppcommon)gglobal()->common.prv;
285 p->playback_inputs = TRUE;
286 last_time = Time1970sec();
287 int ret = pthread_create(&playback_thread, NULL, (
void*)_playbackthread, gglobal());
289int fwl_get_modePlayback() {
290 ppcommon p = (ppcommon)gglobal()->common.prv;
291 return p->playback_inputs;
293int fwl_get_modeRecord() {
294 ppcommon p = (ppcommon)gglobal()->common.prv;
295 return p->record_inputs;
297void fwl_setTrap(
int k){
298 ppcommon p = (ppcommon)gglobal()->common.prv;
302 ppcommon p = (ppcommon)gglobal()->common.prv;
306void fwl_setJsEngine(
char *optarg){
308 int engine, engine_variant, ivalid;
309 ppcommon p = (ppcommon)gglobal()->common.prv;
314 if(strlen(optarg) >= 2 && (!strncmp(optarg,
"SM",2) || !strncmp(optarg,
"sm",2))){
317 engine = JSENGINE_SM;
318 if(strlen(optarg) >= 3){
319 if(optarg[2] ==
'2') engine_variant = 2;
320 if(optarg[2] ==
'1') engine_variant = 1;
323 ConsoleMessage(
"not built with spidermonkey js engine\n");
326 if(!strcmp(optarg,
"DUK") || !strcmp(optarg,
"duk")){
328 #ifdef JAVASCRIPT_DUK
329 engine = JSENGINE_DUK;
331 ConsoleMessage(
"not built with duktape js engine\n");
334 if(!strcmp(optarg,
"NONE") || !strcmp(optarg,
"none")){
336 engine = JSENGINE_STUB;
339 static char *engine_names [] = {
"NONE",
"DUK",
"SM"};
340 ConsoleMessage(
"could not do js preference %s, trying %s\n",optarg,engine_names[p->jsengine]);
343 ConsoleMessage(
"invalid --javascript / -J otpion, should be SM, DUK or NONE\n");
345 if(ivalid && engine > -1){
346 p->jsengine = engine;
347 if(engine_variant > -1) p->jsengine_variant = engine_variant;
351 ppcommon p = (ppcommon)gglobal()->common.prv;
354int getJsEngineVariant(){
355 ppcommon p = (ppcommon)gglobal()->common.prv;
356 return p->jsengine_variant;
360void setMenuFps(
float fps)
362 ppcommon p = (ppcommon)gglobal()->common.prv;
368void kill_status(
void) {
370 ppcommon p = (ppcommon)gglobal()->common.prv;
372 p->sb_hasString = FALSE;
376void showConsoleText(
int on){
377 ppcommon p = (ppcommon)gglobal()->common.prv;
378 p->showConsoleText = on;
380int getShowConsoleText(){
381 ppcommon p = (ppcommon)gglobal()->common.prv;
382 return p->showConsoleText;
385void update_status(
char* msg) {
386 ppcommon p = (ppcommon)gglobal()->common.prv;
389 p->sb_hasString = FALSE;
393 p->sb_hasString = TRUE;
394 strcpy(p->buffer, msg);
398 ppcommon p = (ppcommon)gglobal()->common.prv;
401void setSensorStatus(
char* status) {
403 ppcommon p = (ppcommon)gglobal()->common.prv;
407 snprintf(p->SensorStatus, MAXSTAT - 1,
"%s", pp);
410char* getSensorStatus() {
411 return ((ppcommon)gglobal()->common.prv)->SensorStatus;
413void setMenuStatus3(
char* status3)
416 ppcommon p = (ppcommon)gglobal()->common.prv;
420 snprintf(p->myMenuStatus, MAXSTAT-1,
"%s", pp);
422void setMenuStatusVP(
char *stattext)
424 setMenuStatus3(stattext);
428 return ((ppcommon)gglobal()->common.prv)->myMenuStatus;
433void setWindowTitle0()
435 ppcommon p = (ppcommon)gglobal()->common.prv;
437 snprintf(p->window_title,
sizeof(p->window_title),
"FreeWRL");
440char *getWindowTitle()
442 ppcommon p = (ppcommon)gglobal()->common.prv;
443 return p->window_title;
449 ppcommon p = (ppcommon)gglobal()->common.prv;
451 snprintf(p->messagebar, MAXSTAT-1,
"%s", p->myMenuStatus);
455 ppcommon p = (ppcommon)gglobal()->common.prv;
456 return p->messagebar;
458double get_viewer_dist();
460 ppcommon p = (ppcommon)gglobal()->common.prv;
461 snprintf(p->distbar, 10,
"D%8f", (
float)get_viewer_dist());
467 ppcommon p = (ppcommon)gglobal()->common.prv;
471 ppcommon p = (ppcommon)gglobal()->common.prv;
473 snprintf(p->fpsbar, 10,
"%4d", (
int)(p->myFps + .49999f));
475static int frontend_using_cursor = 0;
476void fwl_set_frontend_using_cursor(
int on)
480 frontend_using_cursor = on;
485 ppcommon p = (ppcommon)gglobal()->common.prv;
486 p->cursorStyle = ACURSE;
488void setLookatCursor()
490 ppcommon p = (ppcommon)gglobal()->common.prv;
491 p->cursorStyle = SCURSE;
494void setSensorCursor()
496 ppcommon p = (ppcommon)gglobal()->common.prv;
497 p->cursorStyle = SCURSE;
502 ppcommon p = (ppcommon)gglobal()->common.prv;
503 if (!frontend_using_cursor)
504 return p->cursorStyle;
509int fwl_set_sbh_pin_option(
char *optarg){
510 if(optarg && strlen(optarg) > 1){
511 ppcommon p = (ppcommon)gglobal()->common.prv;
512 p->pin_statusbar = (optarg[0] ==
'T' || optarg[0] ==
't') ? 1 : 0;
513 p->pin_menubar = (optarg[1] ==
'T' || optarg[1] ==
't') ? 1 : 0;
517int fwl_set_sbh_want_option(
char *optarg){
518 if(optarg && strlen(optarg) > 1){
519 ppcommon p = (ppcommon)gglobal()->common.prv;
520 p->want_statusbar = (optarg[0] ==
'T' || optarg[0] ==
't') ? 1 : 0;
521 p->want_menubar = (optarg[1] ==
'T' || optarg[1] ==
't') ? 1 : 0;
526void fwl_set_sbh_pin(
int sb,
int mb){
527 ppcommon p = (ppcommon)gglobal()->common.prv;
528 p->pin_statusbar = sb;
531void fwl_get_sbh_pin(
int *sb,
int *mb){
532 ppcommon p = (ppcommon)gglobal()->common.prv;
533 *sb = p->pin_statusbar;
534 *mb = p->pin_menubar;
536void fwl_set_sbh_wantMenubar(
int want){
537 ppcommon p = (ppcommon)gglobal()->common.prv;
538 p->want_menubar = want ? 1 : 0;
540int fwl_get_sbh_wantMenubar(){
541 ppcommon p = (ppcommon)gglobal()->common.prv;
542 return p->want_menubar;
544void fwl_set_sbh_wantStatusbar(
int want){
545 ppcommon p = (ppcommon)gglobal()->common.prv;
546 p->want_statusbar = want ? 1 : 0;
548int fwl_get_sbh_wantStatusbar(){
549 ppcommon p = (ppcommon)gglobal()->common.prv;
550 return p->want_statusbar;
553void fwl_set_target_fps(
int target_fps){
554 ppcommon p = (ppcommon)gglobal()->common.prv;
555 p->target_frames_per_second = max(1,target_fps);
557int fwl_get_target_fps(){
558 ppcommon p = (ppcommon)gglobal()->common.prv;
559 return p->target_frames_per_second;
643{NULL,NULL,NULL,NULL},
646void color_html2rgb(
char *html,
float *rgb){
653 if(shex[0] ==
'#') shex = &shex[1];
654 ic = strtol(shex,NULL,16);
656 ig = (ic & 0xFF00) >> 8;
657 ir = (ic & 0xFF0000) >> 16;
658 rgb[0] = (float)ir/255.0f;
659 rgb[1] = (float)ig/255.0f;
660 rgb[2] = (float)ib/255.0f;
662char *hexpermitted =
" #0123456789ABCDEFabcdef";
673int colorsoption2colorscheme(
const char *optionstring,
colorScheme *cs){
679 char *str, *html, *stok;
680 len = strlen(optionstring);
682 strcpy(str,optionstring);
685 if(!strchr(hexpermitted,str[i])){
693 html = strtok(stok,
" ");
695 if(cs->menuIcon) html = cs->menuIcon;
696 else html =
"#FFFFFF";
699 case 0: cs->panel = strdup(html);
break;
700 case 1: cs->menuIcon = strdup(html);
break;
701 case 2: cs->statusText = strdup(html);
break;
702 case 3: cs->messageText = strdup(html);
break;
712colorScheme *search_ui_colorscheme(
char *colorschemename){
717 if(!strcmp(colorSchemes[i].name,colorschemename)){
718 cs = &colorSchemes[i];
722 }
while(colorSchemes[i].name);
725int fwl_set_ui_colorscheme(
char *colorschemename){
727 ppcommon p = (ppcommon)gglobal()->common.prv;
728 cs = search_ui_colorscheme(colorschemename);
731 p->colorSchemeChanged++;
739void fwl_set_ui_colors(
char *fourhtmlcolors){
741 ppcommon p = (ppcommon)gglobal()->common.prv;
742 cs = search_ui_colorscheme(
"custom");
743 colorsoption2colorscheme(fourhtmlcolors, cs);
744 p->colorScheme = (
void *)cs;
745 p->colorSchemeChanged++;
747char *fwl_get_ui_colorschemename(){
749 ppcommon p = (ppcommon)gglobal()->common.prv;
753void fwl_next_ui_colorscheme(){
756 char *colorschemename;
759 colorschemename = fwl_get_ui_colorschemename();
762 if(!strcmp(colorSchemes[i].name,colorschemename)){
763 cs = &colorSchemes[i+1];
765 cs = &colorSchemes[0];
767 if(!strcmp(cs->name,
"custom")){
768 cs = &colorSchemes[0];
770 fwl_set_ui_colorscheme(cs->name);
774 }
while(colorSchemes[i].name);
779#ifndef UI_COLORSCHEME_DEFAULT
780#define UI_COLORSCHEME_DEFAULT "neon:lime"
782void fwl_get_ui_color(
char *use,
float *rgb){
784 ppcommon p = (ppcommon)gglobal()->common.prv;
786 p->colorScheme = search_ui_colorscheme(UI_COLORSCHEME_DEFAULT);
787 p->colorSchemeChanged++;
790 if(!strcmp(use,
"panel")){
791 color_html2rgb(cs->panel, rgb);
792 }
else if(!strcmp(use,
"menuIcon")){
793 color_html2rgb(cs->menuIcon, rgb);
794 }
else if(!strcmp(use,
"statusText")){
795 color_html2rgb(cs->statusText, rgb);
796 }
else if(!strcmp(use,
"messageText")){
797 color_html2rgb(cs->messageText, rgb);
800int fwl_get_ui_color_changed(){
801 ppcommon p = (ppcommon)gglobal()->common.prv;
802 return p->colorSchemeChanged;
826#include <scenegraph/Viewer.h>
828int fwl_setDragChord(
char *chordname);
829int fwl_setKeyChord(
char *chordname);
831int fwl_keyval(
char *
key,
char *val);
833int searchkeyvals(
char *
key){
835 ppcommon p = (ppcommon)gglobal()->common.prv;
837 p->keyvals = newVector(
keyval,4);
839 for(i=0;i<vectorSize(p->keyvals);i++){
841 if(!strcmp(k_v.key,
key)){
848int set_key_val(
char *
key,
char *val){
851 ppcommon p = (ppcommon)gglobal()->common.prv;
853 index = searchkeyvals(
key);
856 p->keyvals = newVector(
keyval,4);
857 k_v.key = STRDUP(
key);
858 k_v.val = STRDUP(val);
859 vector_pushBack(
keyval,p->keyvals,k_v);
861 k_v = vector_get(
keyval,p->keyvals,index);
863 k_v.val = STRDUP(val);
864 vector_set(
keyval,p->keyvals,index,k_v);
868int set_keyval(
char *
keyval){
873 ppcommon p = (ppcommon)gglobal()->common.prv;
875 p->keyvals = newVector(
keyval,4);
884 sep = strchr(kv,
' ');
885 if(!sep) sep = strchr(kv,
',');
891 set_key_val(
key,val);
897char *get_key_val(
char *
key){
900 ppcommon p = (ppcommon)gglobal()->common.prv;
902 index = searchkeyvals(
key);
903 if(index < 0)
return NULL;
904 k_v = vector_get(
keyval,p->keyvals,index);
907int print_keyval(
char *
key){
909 ppcommon p = (ppcommon)gglobal()->common.prv;
910 index = searchkeyvals(
key);
912 ConsoleMessage(
"\n key %s not found\n",
key);
915 k_v = vector_get(
keyval,p->keyvals,index);
916 ConsoleMessage(
"\n key=%s val=%s\n",
key,k_v.val);
921int ssr_test(
char *
keyval);
925 int (*valfunc)(
char *val);
928 {
"dragchord",NULL,fwl_setDragChord,
"[yawz,yawpitch,roll,xy]"},
929 {
"keychord", NULL,fwl_setKeyChord,
"[yawz,yawpitch,roll,xy]"},
930 {
"navmode",NULL,fwl_setNavMode,
"[walk,fly,examine,explore,spherical,turntable,lookat]"},
931 {
"help",print_help,NULL,NULL},
932 {
"pin",NULL,fwl_set_sbh_pin_option,
"[tf,tt,ft,ff]"},
933 {
"colorscheme",NULL,fwl_set_ui_colorscheme,
"[original,midnight,angry,favicon,aqua,neon:lime,neon:yellow,neon:cyan,neon:pink]"},
934 {
"set_keyval",NULL,set_keyval,
"key,val"},
935 {
"print_keyval",NULL,print_keyval,
"key"},
938 {
"ssrtest",NULL,ssr_test,
"nav,val"},
940 {
"",print_help,NULL,NULL},
945 ConsoleMessage(
"\n%s\n",
"spacebar commands: spacebar:key[,val]Enter");
947 while(commands[i].
key){
948 if(commands[i].helpstring)
949 ConsoleMessage(
" %s,%s\n",commands[i].
key,commands[i].helpstring);
951 ConsoleMessage(
" %s\n",commands[i].
key);
961 while(commands[i].
key){
962 if(!strcmp(
key,commands[i].
key)){
970int fwl_keyval(
char *
key,
char *val){
973 cmd = getCommand(
key);
976 ok = cmd->valfunc(val);
980int fwl_command(
char *
key){
983 cmd = getCommand(
key);
990int fwl_commandline(
char *cmdline){
991 char *sep = strchr(cmdline,
' ');
992 if(!sep) sep = strchr(cmdline,
',');
996 val = strdup(&sep[1]);
997 keylen = (int)(sep - cmdline);
999 key = strndup(cmdline,keylen +1);
1002 fwl_keyval(
key,val);
1007 fwl_command(cmdline);
1014void fwl_setDensityFactor(
float density_factor){
1020 ppcommon p = (ppcommon)gglobal()->common.prv;
1021 p->density_factor = density_factor;
1023float fwl_getDensityFactor(){
1024 ppcommon p = (ppcommon)gglobal()->common.prv;
1025 return p->density_factor;
1028 ppcommon p = (ppcommon)gglobal()->common.prv;
1031void fwl_setPedal(
int pedal){
1032 ppcommon p = (ppcommon)gglobal()->common.prv;
1036 ppcommon p = (ppcommon)gglobal()->common.prv;
1039void fwl_setHover(
int hover){
1040 ppcommon p = (ppcommon)gglobal()->common.prv;
1043void fwl_setDrawBoundingBoxes(
int drawbb){
1044 ppcommon p = (ppcommon)gglobal()->common.prv;
1045 p->draw_bounding_boxes = drawbb;
1047int fwl_getDrawBoundingBoxes(){
1048 ppcommon p = (ppcommon)gglobal()->common.prv;
1049 return p->draw_bounding_boxes;
1051void fwl_setShowViewpoints(
int show){
1052 ppcommon p = (ppcommon)gglobal()->common.prv;
1053 p->show_viewpoints = show;
1055int fwl_getShowViewpoints(){
1056 ppcommon p = (ppcommon)gglobal()->common.prv;
1057 return p->show_viewpoints;
1059void fwl_setDrawRig(
int draw) {
1060 ppcommon p = (ppcommon)gglobal()->common.prv;
1063int fwl_getDrawRig() {
1064 ppcommon p = (ppcommon)gglobal()->common.prv;