home *** CD-ROM | disk | FTP | other *** search
- /**** example.c ****/
- /* Program to show the euclid library in action */
- /* By Paul Field
- * See !ReadMe file for distribution/modification restrictions
- */
-
- #include <assert.h>
- #include <stdio.h>
- #include <string.h>
- #include <math.h>
-
- #include "cache.h"
- #include "function.h"
- #include "ewindow.h"
- #include "euclid.h"
-
- #include "alarm.h"
- #include "baricon.h"
- #include "dbox.h"
- #include "event.h"
- #include "flex.h"
- #include "heap.h"
- #include "kernel.h"
- #include "menu.h"
- #include "res.h"
- #include "resspr.h"
- #include "saveas.h"
- #include "template.h"
- #include "visdelay.h"
- #include "werr.h"
- #include "wimp.h"
- #include "wimpt.h"
- #include "win.h"
-
-
- /**** Some test functions followed by 'graphdata' for them ****/
- /**** Functions are actually 2D Versions of Kenneth De Jong's ****/
- /**** Genetic Algorithm test functions ****/
-
- static double fn1(double x, double y)
- { return((x*x+y*y)*0.25-6);
- /* Scaled by 0.25 - otherwise it looks very tall and thin */
- /* -6 to centre it */
- }
-
- static double fn3(double x, double y)
- { int total;
-
- total = (int)x + (int)y;
- return((double)total);
- }
-
- static double fn5(double x, double y)
- { static int a[2][25] =
- { {-2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0,0,0,0, 1, 1, 1, 1,1, 2, 2,2,2,2},
- {-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1,0,1,2,-2,-1, 0, 1,2,-2,-1,0,1,2} };
- int j;
- double total = 0.002;
-
- for (j = 0; j <= 24; j++)
- { double subtotal;
-
- subtotal = pow(x-(double)(a[0][j])*10.0,6) + pow(y-(double)(a[1][j])*10.0,6);
- total += 1.0/((double)j+1.0+subtotal);
- }
- return(total*150-50); /* Scaled by 150 - otherwise you can't see anything */
- /* -50 to centre it */
- }
-
- #define GRAPHS 3 /* If you change this then change the menu definitions */
-
- static graphdata graph[GRAPHS] =
- { { -5.12,5.12,
- -5.12,5.12,
- 20, 700,
- fn1, "Graph1", 0
- },
- { -5.12,5.12,
- -5.12,5.12,
- 30, 700,
- fn3, "Graph2", 0
- },
- { -65.536,65.536,
- -65.536,65.536,
- 20, 700,
- fn5, "Graph3", 0
- }
- };
-
-
- /***** Now for the main wimp program *****/
-
- #define VERSION "0.02"
-
- #define info_version 4 /* 'Version' icon number in info box */
-
- /********* Messages ********/
-
- #define MESS_CRMENU "Unable to create menu."
- #define MESS_ATMENU "Unable to attatch menu."
- #define MESS_NOINFO "Cannot create the info box."
- #define MESS_NOMEM "Not enough memory."
-
- /********* Useful filetypes *********/
-
- #define ftype_sprite 0xff9
- #define ftype_euclid 0xde1
-
-
- /********* menu definition text ***********/
-
- /**** Main menu ****/
-
- #define MM_ITEMS ">Info,Graph1,Graph2,Graph3,Quit"
- typedef enum
- { mm_info=1, mm_graph1, mm_graph2, mm_graph3, mm_quit
- }mm_item;
-
- /**** Graph menu ****/
-
- #define GM_ITEMS "Save,Style,Sprite,Rotate"
- typedef enum
- { gm_save=1, gm_style, gm_sprite, gm_rotate
- }gm_item;
-
- /**** Save menu ****/
-
- #define SM_ITEMS ">Euclid,>Sprite"
- typedef enum
- { sm_euclid=1, sm_sprite
- }sm_item;
-
- /**** Style menu ****/
-
- #define STM_ITEMS "Faces Only,Faces & Edges,Ray Trace|Lit"
- typedef enum
- { stm_faces=1, stm_facesedges, stm_raytrace, stm_lit
- }stm_item;
-
- /**** Sprite options menu ****/
-
- #define SOM_ITEMS "Multitask,Mode"
- typedef enum
- { som_multitask = 1, som_mode
- }som_item;
-
- /**** Multitask menu ****/
-
- #define MTM_ITEMS "None,Slow,Fast,VFast"
- typedef enum
- { mtm_none=1, mtm_slow, mtm_fast, mtm_vfast
- }mtm_item;
-
- /**** Mode menu ****/
-
- #define MDM_ITEMS "Current,Dynamic,num"
- typedef enum
- { mdm_current=1, mdm_dynamic, mdm_num
- }mdm_item;
-
- /**** Global menu variables ****/
-
- static menu mainmenu, graphmenu, savemenu, spritemenu, multimenu, modemenu, stylemenu;
- static char modestring[4];
-
-
- /********* Various global variables *********/
-
- #define SIZE 30*1024 /* Amount of memory set aside for each graph */
- #define ROTATEEVERY 10 /* Graph tries to rotate at 100/ROTATEEVERY frames per second */
-
-
- typedef struct graphwinfo
- { int graphno;
- euclid_header *structure;
- ewindow ew;
- BOOL closed; /* TRUE if window to graph is closed */
- BOOL rotate; /* TRUE if graph is rotating in the window */
- BOOL sprite; /* TRUE if window is using 'sprite' mode */
- mtm_item multitask; /* Type of multitasking */
- ewindow_spritemode mode;
- euclid_mainstyle style; /* Drawing style of the picture */
- BOOL lit;
- }graphwinfo;
-
- static graphwinfo gwi[GRAPHS];
- static void *cache[GRAPHS]; /* Block of memory used by Euclid for drawing */
-
-
- /********* Error handling macros ********/
-
- #define ERR_NonFatal 0
- #define ERR_Fatal 1
-
- #define main_error(error) werr(ERR_NonFatal, error)
- #define main_terminate(error) werr(ERR_Fatal, error)
-
-
- /********** The program **********/
-
- static void main_initcaches(void);
- static void main_createmenus(void);
- static void main_decodemainmenu(void *dummy, char *hit);
- static menu main_makegraphmenu(void *handle);
- static void main_decodegraphmenu(void *dummy, char *hit);
- static void main_setgraphstyle(graphwinfo *gwientry);
- static BOOL main_creategraph(int graphno);
- static euclid_header *main_createstructure(graphdata *g, void *cache);
- static void main_close(ewindow, void *closed);
- static void main_programinfo(void);
- static void main_barclick(wimp_i dummy);
- static void main_rotategraph(int, void *handle);
- static BOOL main_saveeuclid(char *name, void *handle);
- static BOOL main_savesprite(char *name, void *handle);
-
-
- int main(void)
- { int graphno;
-
- wimpt_init("Euclid Library Example");
- res_init("Example");
- resspr_init();
- template_init();
- dbox_init();
- alarm_init();
- flex_init();
- visdelay_init();
- heap_init(TRUE);
-
- main_initcaches();
- for (graphno = 0; graphno < GRAPHS; graphno++)
- { gwi[graphno].structure = NULL;
- gwi[graphno].graphno = graphno;
- gwi[graphno].closed = TRUE;
- gwi[graphno].rotate = FALSE;
- }
- main_createmenus();
- baricon("!Example",(int) resspr_area(), main_barclick);
- if (!event_attachmenu(win_ICONBAR, mainmenu, main_decodemainmenu, NULL))
- { main_terminate(MESS_ATMENU);
- }
- while(TRUE)
- { event_process();
- }
- return(0);
- }
-
- static void main_initcaches(void)
- { int cachesize;
- BOOL seperate;
- int cacheno;
- char var[5];
-
- /** Get and check the size of the drawing cache(s) **/
- os_read_var_val("Example$Cachesize",var,5);
- if (!*var)
- { main_terminate("Example$Cachesize not defined");
- }
- if ((cachesize = atoi(var)*1024) < 10*1024)
- { main_terminate("Example$Cachesize must be greater than or equal to 10");
- }
-
- /** Decide on a single or multiple caches **/
- os_read_var_val("Example$Seperatecaches",var,5);
- if (!*var)
- { main_terminate("Example$Seperatecaches not defined");
- }
- if (!strcmp(var, "yes"))
- { seperate = TRUE;
- }
- else
- { if ((seperate = strcmp(var, "no")) != 0)
- { main_terminate("Example$Seperatecaches must have a value of 'yes' or 'no' "
- "(Note: lower case)");
- }
- }
-
- /** Single cache - assign memory to cache[0] copy reference to cache[1] etc.. **/
- /** Multiple caches - assign memory to each **/
- cacheno = 0;
- do
- { if ((cache[cacheno] = heap_alloc(cachesize)) == NULL)
- { main_terminate(MESS_NOMEM);
- }
- *(unsigned int *)cache[cacheno] = cachesize;
- }
- while(++cacheno < GRAPHS && seperate);
- for (;cacheno < GRAPHS; cacheno++)
- { cache[cacheno] = cache[0];
- }
- }
-
-
- /***** Creating and decoding menus *****/
-
- static void main_createmenus(void)
- { if ((mainmenu = menu_new("Example", MM_ITEMS)) == NULL ||
- (graphmenu = menu_new("Graph", GM_ITEMS)) == NULL ||
- (savemenu = menu_new("Save", SM_ITEMS)) == NULL ||
- (stylemenu = menu_new("Style", STM_ITEMS)) == NULL ||
- (spritemenu= menu_new("Sprite", SOM_ITEMS)) == NULL ||
- (multimenu = menu_new("Multitask",MTM_ITEMS)) == NULL ||
- (modemenu = menu_new("Mode", MDM_ITEMS)) == NULL)
- { main_terminate(MESS_CRMENU);
- }
- menu_make_writeable(modemenu, mdm_num, modestring, 4, "A0-9");
- menu_submenu(spritemenu, som_multitask, multimenu);
- menu_submenu(spritemenu, som_mode, modemenu);
- menu_submenu(graphmenu, gm_save, savemenu);
- menu_submenu(graphmenu, gm_style, stylemenu);
- menu_submenu(graphmenu, gm_sprite, spritemenu);
- }
-
-
- static void main_decodemainmenu(void *dummy, char *hit)
- { dummy=dummy;
-
- switch(hit[0])
- { case mm_info : main_programinfo(); return;
- case mm_quit : exit(0);
- }
- if (hit[0] != 0)
- { int graphno;
- graphwinfo *gwientry;
-
- graphno = hit[0]-mm_graph1;
- gwientry = &gwi[graphno];
- if (gwientry->structure == NULL)
- { main_creategraph(graphno);
- }
- if (gwientry->structure != NULL)
- { ewindow_open(gwientry->ew);
- gwientry->closed = FALSE;
- if (gwientry->rotate)
- { main_rotategraph(0, gwientry);
- }
- menu_setflags(mainmenu, hit[0], TRUE, FALSE);
- }
- }
- }
-
- static menu main_makegraphmenu(void *handle)
- { graphwinfo *gwientry = handle;
- int option;
- BOOL rayok; /* TRUE if raytracing can occur */
- BOOL rayactive; /* TRUE if raytracing is occuring */
-
- rayok = ewindow_hassprite(gwientry->ew) && gwientry->mode != ewindow_smdynamic &&
- gwientry->multitask != mtm_none && !gwientry->rotate;
- rayactive = gwientry->style == emainstyle_raytrace;
-
- menu_setflags(graphmenu, gm_sprite, gwientry->sprite, FALSE);
- menu_setflags(graphmenu, gm_rotate, gwientry->rotate, rayactive);
- menu_setflags(multimenu, mtm_none, gwientry->multitask == mtm_none, rayactive);
- for (option = mtm_none+1; option <= mtm_vfast; option++)
- { menu_setflags(multimenu, option, gwientry->multitask == option, FALSE);
- }
- if (gwientry->mode >= 0)
- { sprintf(modestring, "%d", gwientry->mode);
- }
- else
- { *modestring = NULL;
- }
- menu_setflags(modemenu, mdm_current, gwientry->mode == ewindow_smcurrent, FALSE);
- menu_setflags(modemenu, mdm_dynamic, gwientry->mode == ewindow_smdynamic, rayactive);
- menu_setflags(savemenu, sm_sprite, FALSE, !ewindow_updatecomplete(gwientry->ew) ||
- !ewindow_hassprite(gwientry->ew));
- for (option = stm_faces; option < stm_raytrace; option++)
- { menu_setflags(stylemenu, option, gwientry->style == option-1, FALSE);
- }
- menu_setflags(stylemenu, stm_raytrace, gwientry->style == stm_raytrace-1, !rayok);
- menu_setflags(stylemenu, stm_lit, gwientry->lit, FALSE);
- return(graphmenu);
- }
-
- static void main_decodegraphmenu(void *handle, char *hit)
- { graphwinfo *gwientry = handle;
-
- switch(hit[0])
- { case gm_save:
- switch(hit[1])
- { case sm_euclid:
- saveas(ftype_euclid, "Euclid", SIZE, main_saveeuclid, 0,0, gwientry);
- break;
- case sm_sprite:
- saveas(ftype_sprite, "Sprite", 0, main_savesprite, 0,0, gwientry);
- break;
- }
- break;
- case gm_style:
- switch(hit[1])
- { case stm_raytrace :
- case stm_faces :
- case stm_facesedges :
- gwientry->style = hit[1]-1;
- break;
- case stm_lit :
- gwientry->lit = !gwientry->lit;
- }
- main_setgraphstyle(gwientry);
- break;
- case gm_sprite:
- switch(hit[1])
- { case 0:
- gwientry->sprite = !gwientry->sprite;
- if (gwientry->style == emainstyle_raytrace)
- { main_error("Changing to faces only style.");
- gwientry->style = emainstyle_facesonly;
- main_setgraphstyle(gwientry);
- }
- break;
- case som_multitask:
- if (hit[2] != 0)
- { gwientry->multitask = hit[2];
- }
- switch(hit[2])
- { case mtm_none : ewindow_timing(gwientry->ew, 0, 0); break;
- case mtm_slow : ewindow_timing(gwientry->ew, 1, 2); break;
- case mtm_fast : ewindow_timing(gwientry->ew, 10, 2); break;
- case mtm_vfast : ewindow_timing(gwientry->ew, 0xfe, 2); break;
- }
- break;
- case som_mode:
- switch(hit[2])
- { case mdm_current : gwientry->mode = ewindow_smcurrent; break;
- case mdm_dynamic : gwientry->mode = ewindow_smdynamic; break;
- case mdm_num : gwientry->mode = atoi(modestring); break;
- }
- break;
- }
- ewindow_usesprite(gwientry->ew, gwientry->sprite, gwientry->mode);
- break;
- case gm_rotate:
- gwientry->rotate = !gwientry->rotate;
- if (gwientry->rotate)
- { main_rotategraph(0, gwientry);
- }
- else
- { alarm_removeall(gwientry);
- }
- break;
- }
- }
-
-
- /***** Creating and handling graphwindows *****/
-
- static void main_setgraphstyle(graphwinfo *gwientry)
- { ewindow_setstyle(gwientry->ew, edrawstyle_mainstyle * gwientry->style +
- gwientry->lit * (edrawstyle_lightson|edrawstyle_frontlighton));
- }
-
-
- #define GRAPHSTYLE ((edrawstyle_mainstyle * emainstyle_facesonly) |\
- edrawstyle_lightson | edrawstyle_frontlighton)
-
- static BOOL main_creategraph(int graphno)
- { char *error = NULL;
- graphwinfo *gwientry;
- euclid_header *structure;
- wimp_wind *window;
-
- gwientry = &gwi[graphno];
- if ((window = template_syshandle("ewindow")) == NULL)
- { main_error("Template 'ewindow' not found");
- return(FALSE);
- }
- window->box.y0 -= 40; /* Move each graph window down slightly */
- window->box.y1 -= 40;
-
- if ((structure = main_createstructure(&graph[graphno], cache[graphno])) != NULL &&
- (gwientry->ew = ewindow_create(graph[graphno].name, GRAPHSTYLE, structure,
- NULL, main_close, gwientry)) != NULL)
- { if (!event_attachmenumaker(ewindow_handle(gwientry->ew), main_makegraphmenu,
- main_decodegraphmenu, gwientry))
- { error = MESS_ATMENU;
- ewindow_destroy(gwientry->ew);
- }
- }
- else
- { error = MESS_NOMEM;
- }
-
- if (error)
- { main_error(error);
- if (structure != NULL)
- { heap_free(structure);
- }
- structure = NULL;
- }
- else
- { gwientry->structure = structure;
- gwientry->multitask = mtm_none;
- gwientry->mode = ewindow_smdynamic;
- gwientry->style = emainstyle_facesonly;
- gwientry->lit = TRUE;
- main_setgraphstyle(gwientry);
- }
- return(error == NULL);
- }
-
-
- static euclid_header *main_createstructure(graphdata *g, void *cache)
- { euclid_header *data;
-
- if ((data = heap_alloc(SIZE)) != NULL)
- { visdelay_begin();
-
- wimpt_noerr(euclid_initialise(einitflags_blackonwhite, data, SIZE, NULL));
- if (!wimpt_complain(function_makegraph(data, g, (euclid_mesh **)&data->root)))
- { data->observerrot.x = 0<<6;
- data->observerrot.y = 80<<6;
- data->observerrot.z = 90<<6;
- data->cache = cache;
- data->backgroundcol.c.abscolour = euclid_makecolour(0x80u,0,0xa0,0xff);
- }
- else
- { heap_free(data);
- data = NULL;
- }
- visdelay_end();
- }
- return(data);
- }
-
-
- static void main_close(ewindow ew, void *vgwi)
- { graphwinfo *gwi = vgwi;
-
- if (gwi->rotate)
- { alarm_removeall(gwi);
- }
- gwi->closed = TRUE;
- menu_setflags(mainmenu, gwi->graphno + mm_graph1, FALSE, FALSE);
- ewindow_closeoptions(ew, gwi->style != emainstyle_raytrace);
- ewindow_close(ew);
- }
-
-
- /***** Miscellaneous functions *****/
-
- static void main_programinfo(void)
- { dbox d;
- char versionstring[80];
-
- if ((d = dbox_new("progInfo")) == NULL)
- { main_error(MESS_NOINFO);
- return;
- }
- sprintf(versionstring, "%s (%s)", VERSION, __DATE__);
- dbox_setfield(d, info_version, versionstring);
-
- dbox_show(d);
- dbox_fillin(d);
- dbox_dispose(&d);
- }
-
-
- static void main_barclick(wimp_i dummy)
- { dummy = dummy;
- /* Need to register a function with 'baricon' otherwise clicking */
- /* on the icon bar icon causes the program to crash. */
- }
-
-
- static void main_rotategraph(int time, void *handle)
- { graphwinfo *gwientry = handle;
- int angle;
-
- time=time;
- if (ewindow_updatecomplete(gwientry->ew))
- { angle = gwientry->structure->observerrot.x>>6;
- angle = (angle+10)%360;
- gwientry->structure->observerrot.x = angle<<6;
- ewindow_update(gwientry->ew);
- }
- alarm_set(alarm_timenow()+ROTATEEVERY, main_rotategraph, handle);
- }
-
-
- /***** Saving functions *****/
-
- static BOOL main_saveeuclid(char *name, void *handle)
- { graphwinfo *gwientry = handle;
-
- return(wimpt_complain(euclid_save(gwientry->structure, name)) == NULL);
- }
-
-
- static BOOL main_savesprite(char *name, void *handle)
- { graphwinfo *gwientry = handle;
- sprite_area **area;
- int offset;
- BOOL ok;
-
- if (ewindow_sprite(gwientry->ew, &area, &offset))
- { ok = (wimpt_complain(sprite_area_save(*area, name)) == NULL);
- }
- else
- { /* I don't think this can happen - but better safe than sorry */
- main_error("The sprite memory has been freed - cannot save.");
- ok = FALSE;
- }
- return(ok);
- }
-