home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / mac / developm / source / macraysh.sit / Code / Source / macdialog.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-05-11  |  27.7 KB  |  1,004 lines

  1. /* macdialog.c
  2.  *
  3.  * A collection of routines for the handling of the various settings and dialog boxes which
  4.  * are used to "Mac"ify rayshade.
  5.  *
  6.  */
  7.  
  8. #include <MacHeaders>
  9. #include <Dialogs.h>
  10. #include <Picker.h>
  11.  
  12. #include "geom.h"
  13. #include "rayshade.h"
  14. #include "options.h"
  15. #include "viewing.h"
  16.  
  17. #include "macdialog.h"
  18.  
  19. short magx = 1, magy = 1 ;
  20.  
  21. extern DialogPtr editorDialog ;
  22. extern RSOptions Options ;
  23. extern Geom *CreateProtoObject(short type, char *name) ;
  24. extern Geom *GetCurrentParent() ;
  25. extern Vector crosshair;
  26.  
  27. void aboutDialog()
  28. {
  29.     DialogPtr aboutDialog;
  30.     short i ;
  31.      char done = FALSE;
  32.  
  33.     aboutDialog = GetNewDialog(aboutboxR, NULL, (WindowPtr)-1);
  34.     ShowWindow(aboutDialog);
  35.     DrawDialog(aboutDialog) ;
  36.     SetPort(aboutDialog);
  37.     GetClick();
  38.     DisposDialog(aboutDialog);
  39. }
  40.  
  41. char GetGridSize(int *x, int *y, int *z)
  42. {
  43.     DialogPtr sizeDialog ;
  44.     short hitItem ;
  45.  
  46.     sizeDialog = GetNewDialog(gridsizeR, 0L, (WindowPtr)-1);
  47.  
  48.     SetIntEditText(sizeDialog,gridxBU,0) ;
  49.     SetIntEditText(sizeDialog,gridyBU,0) ;
  50.     SetIntEditText(sizeDialog,gridzBU,0) ;
  51.     DrawDialog(sizeDialog) ;
  52.     DrawHilite(sizeDialog, griduseBU) ;
  53.     do {
  54.         ModalDialog(NULL, &hitItem);
  55.         switch(hitItem) {
  56.             case griduseBU:
  57.                 if(GetIntEditText(sizeDialog, gridxBU, x) &&
  58.                         GetIntEditText(sizeDialog, gridyBU, y) &&
  59.                         GetIntEditText(sizeDialog, gridzBU, z) &&
  60.                         (*x >0) && (*y >0) && (*z >0)) {
  61.                     DisposDialog(sizeDialog);
  62.                     return 1 ;
  63.                 }
  64.                 else
  65.                     SysBeep(1) ;
  66.                 break ;
  67.         }
  68.     } while (1);
  69. }
  70.  
  71. char GetFrameRange(int *start, int *end)
  72. {
  73.     DialogPtr frameDialog ;
  74.     short hitItem ;
  75.     int ns,ne ;
  76.     
  77.     ns = Options.startframe ;
  78.     ne = Options.endframe ;
  79.  
  80.     frameDialog = GetNewDialog(framessetR, 0L, (WindowPtr)-1);
  81.  
  82.     SetIntEditText(frameDialog,framestartET,ns) ;
  83.     SetIntEditText(frameDialog,frameendET,ne) ;
  84.     DrawDialog(frameDialog) ;
  85.     DrawHilite(frameDialog, frameuseBU) ;
  86.     do {
  87.         ModalDialog(NULL, &hitItem);
  88.         switch(hitItem) {
  89.             case frameuseBU:
  90.                 if(GetIntEditText(frameDialog, framestartET, &ns) &&
  91.                         GetIntEditText(frameDialog, frameendET, &ne) &&
  92.                         (ne >= ns) &&
  93.                         (ns >= Options.startframe) &&
  94.                         (ne <= Options.endframe)) {
  95.                     *start = ns ;
  96.                     *end = ne ;
  97.                     DisposDialog(frameDialog);
  98.                     return 1 ;
  99.                 }
  100.                 else
  101.                     SysBeep(1) ;
  102.                 break ;
  103.             case framecancelBU:
  104.                 *start = Options.startframe ;
  105.                 *end = Options.endframe ;
  106.                 DisposDialog(frameDialog);
  107.                 return 0 ;
  108.                 break ;
  109.         }
  110.     } while (1);
  111. }
  112.  
  113. /* Use the Macintosh ColorPicker to modify a Rayshade colour */
  114. void PickColour(Color *col)
  115. {
  116.     RGBColor in, out ;
  117.     static Point pickerPos = { 50,50 } ;
  118.     
  119.     in.red = (unsigned short) (col->r * 65535.) ;
  120.     in.green = (unsigned short) (col->g * 65535.) ;
  121.     in.blue = (unsigned short) (col->b * 65535.) ;
  122.     out = in ;
  123.     if(GetColor(pickerPos,"\pPick a new value", &in, &out)) {
  124.         col->r = ((Float) out.red) /65535.0 ;
  125.         col->g = ((Float) out.green) /65535.0 ;
  126.         col->b = ((Float) out.blue) /65535.0 ;
  127.     }
  128. }
  129.  
  130. void CreateNewObject()
  131. {
  132.     static Str255 name ;
  133.     ControlHandle handle ;
  134.     Handle tempHandle ;
  135.     DialogPtr myDialog = 0L;
  136.     Rect tempRect ;
  137.     static short namenumber = 0 ;
  138.     short hitItem = 0, tempItem, tempType;
  139.     Geom *obj, *parent ;
  140.     char exit = 0 ;
  141.     GrafPtr currPort;
  142.  
  143.     myDialog = GetNewDialog(newobjectR, 0L, (WindowPtr)-1);
  144.  
  145.     sprintf(&name[1],"object%d",namenumber) ;
  146.     name[0] = strlen(&name[1]) ;
  147.     GetDItem(myDialog,objectnameET,&tempType,&tempHandle,&tempRect) ;
  148.     SetIText(tempHandle,&name) ;
  149.  
  150.     SelIText(myDialog, objectnameET, 0, 700) ;
  151.     GetPort(&currPort);
  152.     SetPort(myDialog);
  153.     DrawDialog(myDialog);
  154.     DrawHilite(myDialog,objectcancelBU) ;
  155.     do {
  156.         ModalDialog(NULL, &hitItem);
  157.         switch(hitItem) {
  158.             case objectcreateBU:
  159.                 handle = SnatchHandle(myDialog,objecttypeCI) ;
  160.                 GetIText(SnatchHandle(myDialog,objectnameET), name) ;
  161.                 parent = GetCurrentParent() ;
  162.                 name[name[0]+1] = '\0' ; 
  163.                 obj = CreateProtoObject(GetCtlValue(handle),&name[1]) ;
  164.                 if(obj && parent) {
  165.                     LinkObject(obj,parent) ;
  166.                     ReComputeBounds(obj);
  167.                 }
  168.                 namenumber++;
  169.                 exit = 1 ;
  170.                 break ;
  171.             case objectcancelBU:
  172.                 exit = 1 ;
  173.                 break ;
  174.         }
  175.     } while (!exit);
  176.     DisposDialog(myDialog);
  177.     if(editorDialog) {
  178.         SetPort(editorDialog);
  179.         InvalRect(&editorDialog->portRect) ;
  180.     }
  181.     SetPort(currPort);
  182. }
  183.  
  184. /* 
  185.  * Set the camera angle, tree depth, rays per pixel, and jittering from a dialog box
  186.  * This function is equivalent to the command line parameters on the unix 
  187.  */
  188. void SetRenderOptions()
  189. {
  190.     ControlHandle handle ;
  191.     Handle tempHandle ;
  192.     Rect r, tempRect ;
  193.     short itype ;
  194.     Point pos ;
  195.     int jitter, samples, partcode, shadows, maxdepth, barcode ;
  196.     Str255 message ;
  197.     Str31 myStr ;
  198.     DialogPtr myDialog = 0L;
  199.     ControlHandle temp ;
  200.     short hitItem = 0, tempItem;
  201.     char exit = 0 ;
  202.  
  203.     if(Options.samples < 1) Options.samples = 1 ;
  204.     if(Options.samples > 8) Options.samples = 8 ;
  205.     if(Options.maxdepth > 9) Options.maxdepth = 9 ;
  206.     if(Options.maxdepth < 0) Options.maxdepth = 0 ;
  207.  
  208.     shadows = !Options.no_shadows ;
  209.     maxdepth = Options.maxdepth ;
  210.     jitter = Options.jitter ;
  211.     samples = Options.samples ;
  212.  
  213.     myDialog = GetNewDialog(renderoptionsR, 0L, (WindowPtr)-1);
  214.     /* Set switches to correct values */
  215.     SetCtlMin(SnatchHandle(myDialog,rayspixelSB),1) ;
  216.     SetCtlMax(SnatchHandle(myDialog,rayspixelSB),8) ;
  217.  
  218.     SetCtlValue(SnatchHandle(myDialog,jitterCB),(short)jitter) ;
  219.     SetCtlValue(SnatchHandle(myDialog,shadowsCB),(short)shadows) ;
  220.     SetCtlValue(SnatchHandle(myDialog,treedepthSB),(short)maxdepth) ;    
  221.     SetCtlValue(SnatchHandle(myDialog,rayspixelSB),(short)samples) ;    
  222.  
  223.     GetDItem(myDialog,treedepthET,&itype,&tempHandle,&r) ;
  224.     message[0] = 1 ; message[1] = (char) maxdepth + '0' ;
  225.     SetIText(tempHandle,&message) ;
  226.     GetDItem(myDialog,rayspixelET,&itype,&tempHandle,&r) ;
  227.     message[0] = 1 ; message[1] = (char) samples + '0' ;
  228.     SetIText(tempHandle,&message) ;
  229.     
  230.     DrawDialog(myDialog);
  231.     DrawHilite(myDialog,useBU) ;
  232.     do {
  233.         ModalDialog((ModalFilterProcPtr)renderoptionsfilter, &hitItem);
  234.         switch(hitItem) {
  235.             case rayspixelET:
  236.                 GetDItem(myDialog, rayspixelET, &tempItem, &tempHandle, &tempRect) ;
  237.                 GetIText(tempHandle, myStr) ;
  238.                 samples = myStr[0] ? myStr[1] - '0' : 1 ;
  239.                 SetCtlValue(SnatchHandle(myDialog,rayspixelSB), samples) ;
  240.                 break ;
  241.             case treedepthET:
  242.                 GetDItem(myDialog, treedepthET, &tempItem, &tempHandle, &tempRect) ;
  243.                 GetIText(tempHandle, myStr) ;
  244.                 maxdepth = myStr[0] ? myStr[1] - '0' : 0 ;
  245.                 SetCtlValue(SnatchHandle(myDialog,treedepthSB), maxdepth) ;
  246.                 break ;
  247.             case jitterCB:
  248.                 jitter = (jitter) ? 0 : 1 ;
  249.                 SetCtlValue(SnatchHandle(myDialog,jitterCB), jitter) ;
  250.                 break ;
  251.             case shadowsCB:
  252.                 shadows = (shadows) ? 0 : 1 ;
  253.                 SetCtlValue(SnatchHandle(myDialog,shadowsCB), shadows) ;
  254.                 break ;
  255.             case screenBU:
  256.                 SetScreenOptions() ;
  257.                 DrawHilite(myDialog,useBU) ;
  258.                 break ;
  259.             case cameraBU:
  260.                 SetCameraOptions() ;
  261.                 DrawHilite(myDialog,useBU) ;
  262.                 break ;
  263.             case cancelBU:
  264.                 /* Easy this one... */
  265.                 exit = 1 ;
  266.                 break ;
  267.             case rayspixelSB:
  268.                 GetMouse(&pos) ;
  269.                 handle = SnatchHandle(myDialog,rayspixelSB) ;
  270.                 partcode = TestControl(handle,pos) ;
  271.                 switch(partcode) {
  272.                     case inUpButton:        SetCtlValue(handle,GetCtlValue(handle)-1) ;    break ;
  273.                     case inDownButton:        SetCtlValue(handle,GetCtlValue(handle)+1) ;    break ;
  274.                     case inPageUp:            SetCtlValue(handle,GetCtlValue(handle)-1) ;    break ;
  275.                     case inPageDown:        SetCtlValue(handle,GetCtlValue(handle)+1) ;    break ;
  276.                 }
  277.                 samples = GetCtlValue(handle) ;
  278.                 SetIntEditText(myDialog,rayspixelET,samples) ;
  279.                 break ;
  280.             case treedepthSB:
  281.                 GetMouse(&pos) ;
  282.                 handle = SnatchHandle(myDialog,treedepthSB) ;
  283.                 partcode = TestControl(handle,pos) ;
  284.                 switch(partcode) {
  285.                     case inUpButton:        SetCtlValue(handle,GetCtlValue(handle)-1) ;    break ;
  286.                     case inDownButton:        SetCtlValue(handle,GetCtlValue(handle)+1) ;    break ;
  287.                     case inPageUp:            SetCtlValue(handle,GetCtlValue(handle)-1) ;    break ;
  288.                     case inPageDown:        SetCtlValue(handle,GetCtlValue(handle)+1) ;    break ;
  289.                 }
  290.                 maxdepth = GetCtlValue(handle) ;
  291.                 SetIntEditText(myDialog,treedepthET,maxdepth) ;
  292.                 break ;
  293.             case defaultBU:
  294.                 /* Stick some default options into RSOptions */
  295.                 Options.no_shadows = TRUE;
  296.                 Options.maxdepth = 0;
  297.                 Options.maxdepth_set = TRUE;
  298.                 Options.jitter = TRUE;
  299.                 Options.jitter_set = TRUE;
  300.                 Options.samples = 1;
  301.                 Options.samples_set = TRUE;
  302.             case useBU:
  303.                 Options.no_shadows = !shadows;
  304.                 Options.maxdepth = maxdepth;
  305.                 Options.maxdepth_set = TRUE;
  306.                 Options.jitter = jitter;
  307.                 Options.jitter_set = TRUE;
  308.                 Options.samples = samples;
  309.                 Options.samples_set = TRUE;
  310.                 exit = 1 ;
  311.                 break ;
  312.         } ;
  313.     } while (!exit);
  314.     DisposDialog(myDialog);
  315. }
  316.  
  317. pascal Boolean 
  318. renderoptionsfilter(DialogPtr dialer, EventRecord *myDialogEvent, short *theDialogItem)
  319. {
  320.     WindowPtr temp;
  321.     char theKey;
  322.     Rect tempRect;
  323.     short tempItem, myItem;
  324.     Handle tempHandle;
  325.     long tilticks;
  326.     Boolean returnVal = false;
  327.     Str31 myStr;
  328.     short myitem ;
  329.  
  330.     GetPort(&temp);
  331.     SetPort(dialer);
  332.     myItem = ((DialogPeek)dialer)->editField + 1 ;
  333.     /* Some key filtering schemes follow.  The first is the standard filter to
  334.      * recognize 'return' as Use and 'ESC' as Cancel.
  335.      */
  336.  
  337.     if ((myDialogEvent->what == keyDown) || (myDialogEvent->what == autoKey)) {
  338.         theKey = myDialogEvent->message & charCodeMask;
  339.         switch (theKey) {
  340.             case kReturnKey:
  341.             case kEnterKey:
  342.                 *theDialogItem = useBU ;
  343.                 HiliteControl(SnatchHandle(dialer, useBU), inButton);
  344.                 Delay(8, &tilticks); 
  345.                 HiliteControl(SnatchHandle(dialer, useBU), false);
  346.                 SetPort(temp);
  347.                 returnVal = true;
  348.                 break;
  349.             case kEscKey:
  350.                 *theDialogItem = cancelBU;
  351.                 HiliteControl(SnatchHandle(dialer, cancelBU), inButton);
  352.                 Delay(8, &tilticks);
  353.                 HiliteControl(SnatchHandle(dialer, cancelBU), false);
  354.                 SetPort(temp);
  355.                 returnVal = true;
  356.                 break;
  357.             case kTabKey:
  358.                 returnVal = false ;
  359.                 break ;
  360.             default:
  361.                 /* All non numeric key presses are removed here and a beep is sounded */
  362.                 if((myItem == rayspixelET) || (myItem == treedepthET)) {
  363.                     if((myItem == rayspixelET) && (!isdigit(theKey) || (theKey == '9') || 
  364.                             (theKey=='0')) && !IsEditKey(theKey)) {
  365.                         SysBeep(1);
  366.                         returnVal = true ;
  367.                     }
  368.                     else if((myItem == treedepthET) && !isdigit(theKey) && !IsEditKey(theKey)) {
  369.                         SysBeep(1);
  370.                         returnVal = true ;
  371.                     }
  372.                     else {                        
  373.                         GetDItem(dialer, myItem, &tempItem, &tempHandle, &tempRect);
  374.                         GetIText(tempHandle, myStr);
  375.                         
  376.                         if (myStr[0] > 0) {
  377.                             if (IsEditKey(theKey))
  378.                                 returnVal = false;
  379.                             else {
  380.                                 SysBeep(1);
  381.                                 returnVal = true;
  382.                             }
  383.                         }
  384.                         
  385.                     }
  386.                 }
  387.                 break ;
  388.         }
  389.     }
  390.     return(returnVal);
  391. }
  392.  
  393. void SetMagnificationButtons(DialogPtr myDialog, short mx, short my)
  394. {
  395.     SetCtlValue(SnatchHandle(myDialog,onebyonemagRB), 0) ;
  396.     SetCtlValue(SnatchHandle(myDialog,twobytwomagRB), 0) ;
  397.     SetCtlValue(SnatchHandle(myDialog,fourbyfourmagRB), 0) ;
  398.     SetCtlValue(SnatchHandle(myDialog,eightbyeightmagRB), 0) ;
  399.     SetCtlValue(SnatchHandle(myDialog,sixteenbysixteenmagRB), 0) ;
  400.     SetCtlValue(SnatchHandle(myDialog,thirtytwobythirtytwomagRB), 0) ;
  401.  
  402.     if((mx==1)&&(my==1))
  403.         SetCtlValue(SnatchHandle(myDialog,onebyonemagRB), 1) ;
  404.     else if((mx==2)&&(my==2))
  405.         SetCtlValue(SnatchHandle(myDialog,twobytwomagRB), 1) ;
  406.     else if((mx==4)&&(my==4))
  407.         SetCtlValue(SnatchHandle(myDialog,fourbyfourmagRB), 1) ;
  408.     else if((mx==8)&&(my==8))
  409.         SetCtlValue(SnatchHandle(myDialog,eightbyeightmagRB), 1) ;
  410.     else if((mx==16)&&(my==16))
  411.         SetCtlValue(SnatchHandle(myDialog,sixteenbysixteenmagRB), 1) ;
  412.     else 
  413.         SetCtlValue(SnatchHandle(myDialog,thirtytwobythirtytwomagRB), 1) ;
  414. }
  415.  
  416. /* 
  417.  * Set the screen rendering dimensions
  418.  */
  419. void SetScreenOptions()
  420. {
  421.     ControlHandle handle ;
  422.     Handle tempHandle ;
  423.     Rect r, tempRect ;
  424.     short itype ;
  425.     Str255 output ;
  426.     DialogPtr myDialog = 0L;
  427.     ControlHandle temp ;
  428.     short hitItem = 0, tempItem, mx, my;
  429.     int screenx, screeny, tmpx, tmpy ;
  430.     char myStr[30] ;
  431.     char exit = 0 ;
  432.  
  433.     mx = magx ; my = magy ;
  434.     if(!Options.resolution_set) {
  435.         screenx = 50 ;
  436.         screeny = 50 ;
  437.     }
  438.     else {
  439.         screenx = Screen.xres ;
  440.         screeny = Screen.yres;
  441.     }    
  442.     myDialog = GetNewDialog(screenoptionsR, 0L, (WindowPtr)-1);
  443.     
  444.     /* Set all radios buttons to zero... */
  445.     SetCtlValue(SnatchHandle(myDialog,fiftybyfiftyRB), 0) ;
  446.     SetCtlValue(SnatchHandle(myDialog,hundredbyhundredRB), 0) ;
  447.     SetCtlValue(SnatchHandle(myDialog,twohundredbytwohundredRB), 0) ;
  448.     SetCtlValue(SnatchHandle(myDialog,customRB), 0) ;
  449.     
  450.     SetIntEditText(myDialog, customxET, screenx) ;
  451.     SetIntEditText(myDialog, customyET, screeny) ;
  452.  
  453.     /* Now set correct radio button for screen dimensions */
  454.     if((screenx == 50) && (screeny == 50))
  455.         SetCtlValue(SnatchHandle(myDialog,fiftybyfiftyRB), 1) ;
  456.     else if((screenx == 100) && (screeny == 100))
  457.         SetCtlValue(SnatchHandle(myDialog,hundredbyhundredRB), 1) ;
  458.     else if((screenx == 200) && (screeny == 200))
  459.         SetCtlValue(SnatchHandle(myDialog,twohundredbytwohundredRB), 1) ;
  460.     else {
  461.         /* Set radio button here and also set editable text fields correctly */
  462.         SetCtlValue(SnatchHandle(myDialog,customRB), 1) ;    
  463.     }
  464.     
  465.     SetMagnificationButtons(myDialog, mx, my) ;
  466.  
  467.     DrawDialog(myDialog);
  468.     DrawHilite(myDialog,screenuseBU) ;
  469.     do {
  470.         ModalDialog((ModalFilterProcPtr)screenoptionsfilter, &hitItem);
  471.         
  472.         switch(hitItem) {
  473.             case onebyonemagRB:
  474.                 mx = 1 ; my = 1 ;
  475.                 SetMagnificationButtons(myDialog, mx, my) ;
  476.                 break ;
  477.             case twobytwomagRB:
  478.                 mx = 2 ; my = 2 ;
  479.                 SetMagnificationButtons(myDialog, mx, my) ;
  480.                 break ;
  481.             case fourbyfourmagRB:
  482.                 mx = 4 ; my = 4 ;
  483.                 SetMagnificationButtons(myDialog, mx, my) ;
  484.                 break ;
  485.             case eightbyeightmagRB:
  486.                 mx = 8 ; my = 8 ;
  487.                 SetMagnificationButtons(myDialog, mx, my) ;
  488.                 break ;
  489.             case sixteenbysixteenmagRB:
  490.                 mx = 16 ; my = 16 ;
  491.                 SetMagnificationButtons(myDialog, mx, my) ;
  492.                 break ;
  493.             case thirtytwobythirtytwomagRB:
  494.                 mx = 32 ; my = 32 ;
  495.                 SetMagnificationButtons(myDialog, mx, my) ;
  496.                 break ;
  497.             case fiftybyfiftyRB:
  498.                 SetCtlValue(SnatchHandle(myDialog,fiftybyfiftyRB), 1) ;
  499.                 SetCtlValue(SnatchHandle(myDialog,hundredbyhundredRB), 0) ;
  500.                 SetCtlValue(SnatchHandle(myDialog,twohundredbytwohundredRB), 0) ;
  501.                 SetCtlValue(SnatchHandle(myDialog,customRB), 0) ;
  502.                 screenx = 50 ; screeny = 50 ;
  503.                 SetIntEditText(myDialog, customxET, screenx) ;
  504.                 SetIntEditText(myDialog, customyET, screeny) ;
  505.                 break ;
  506.             case hundredbyhundredRB:
  507.                 SetCtlValue(SnatchHandle(myDialog,fiftybyfiftyRB), 0) ;
  508.                 SetCtlValue(SnatchHandle(myDialog,hundredbyhundredRB), 1) ;
  509.                 SetCtlValue(SnatchHandle(myDialog,twohundredbytwohundredRB), 0) ;
  510.                 SetCtlValue(SnatchHandle(myDialog,customRB), 0) ;
  511.                 screenx = 100 ; screeny = 100 ;
  512.                 SetIntEditText(myDialog, customxET, screenx) ;
  513.                 SetIntEditText(myDialog, customyET, screeny) ;
  514.                 break ;
  515.             case twohundredbytwohundredRB:
  516.                 SetCtlValue(SnatchHandle(myDialog,fiftybyfiftyRB), 0) ;
  517.                 SetCtlValue(SnatchHandle(myDialog,hundredbyhundredRB), 0) ;
  518.                 SetCtlValue(SnatchHandle(myDialog,twohundredbytwohundredRB), 1) ;
  519.                 SetCtlValue(SnatchHandle(myDialog,customRB), 0) ;
  520.                 screenx = 200 ; screeny = 200 ;
  521.                 SetIntEditText(myDialog, customxET, screenx) ;
  522.                 SetIntEditText(myDialog, customyET, screeny) ;
  523.                 break ;
  524.             case customRB:
  525.                 SetCtlValue(SnatchHandle(myDialog,fiftybyfiftyRB), 0) ;
  526.                 SetCtlValue(SnatchHandle(myDialog,hundredbyhundredRB), 0) ;
  527.                 SetCtlValue(SnatchHandle(myDialog,twohundredbytwohundredRB), 0) ;
  528.                 SetCtlValue(SnatchHandle(myDialog,customRB), 1) ;
  529.                 GetDItem(myDialog,customxET,&itype,&tempHandle,&r) ;
  530.                 GetIText(tempHandle, output) ;
  531.                 output[output[0]+1] = '\0' ; screenx = atoi(&output[1]);
  532.                 GetDItem(myDialog,customyET,&itype,&tempHandle,&r) ;
  533.                 GetIText(tempHandle, output) ;
  534.                 output[output[0]+1] = '\0' ; screeny = atoi(&output[1]);
  535.                 break ;
  536.             case customxET:
  537.             case customyET:
  538.                 GetDItem(myDialog,customxET,&itype,&tempHandle,&r) ;
  539.                 GetIText(tempHandle, output) ;
  540.                 output[output[0]+1] = '\0' ; tmpx = atoi(&output[1]);
  541.                 GetDItem(myDialog,customyET,&itype,&tempHandle,&r) ;
  542.                 GetIText(tempHandle, output) ;
  543.                 output[output[0]+1] = '\0' ; tmpy = atoi(&output[1]);
  544.                 if((tmpy != screeny) || (tmpx != screenx)) {
  545.                     screenx = tmpx ;
  546.                     screeny = tmpy ;
  547.                     SetCtlValue(SnatchHandle(myDialog,fiftybyfiftyRB), 0) ;
  548.                     SetCtlValue(SnatchHandle(myDialog,hundredbyhundredRB), 0) ;
  549.                     SetCtlValue(SnatchHandle(myDialog,twohundredbytwohundredRB), 0) ;
  550.                     SetCtlValue(SnatchHandle(myDialog,customRB), 0) ;    
  551.                     if((screenx == 50) && (screeny == 50))
  552.                         SetCtlValue(SnatchHandle(myDialog,fiftybyfiftyRB), 1) ;
  553.                     else if((screenx == 100) && (screeny == 100))
  554.                         SetCtlValue(SnatchHandle(myDialog,hundredbyhundredRB), 1) ;
  555.                     else if((screenx == 200) && (screeny == 200))
  556.                         SetCtlValue(SnatchHandle(myDialog,twohundredbytwohundredRB), 1) ;
  557.                     else
  558.                         SetCtlValue(SnatchHandle(myDialog,customRB), 1) ;    
  559.                 }
  560.                 break ;
  561.             case screencancelBU:
  562.                 /* Easy this one... */
  563.                 exit = 1 ;
  564.                 break ;
  565.             case screenuseBU:
  566.                 GetDItem(myDialog,customxET,&itype,&tempHandle,&r) ;
  567.                 GetIText(tempHandle, output) ;
  568.                 output[output[0]+1] = '\0' ; screenx = atoi(&output[1]);
  569.                 GetDItem(myDialog,customyET,&itype,&tempHandle,&r) ;
  570.                 GetIText(tempHandle, output) ;
  571.                 output[output[0]+1] = '\0' ; screeny = atoi(&output[1]);
  572.                 Screen.xres = screenx ;
  573.                 Screen.yres = screeny ;
  574.                 Options.resolution_set = TRUE;
  575.                 magx = mx ;
  576.                 magy = my ;
  577.                 exit = 1 ;
  578.                 break ;
  579.         } ;
  580.     } while (!exit);
  581.     DisposDialog(myDialog);
  582. }
  583.  
  584. pascal Boolean 
  585. screenoptionsfilter(DialogPtr dialer, EventRecord *myDialogEvent, short *theDialogItem)
  586. {
  587.     WindowPtr temp;
  588.     char theKey;
  589.     Rect tempRect;
  590.     short tempItem, myItem;
  591.     Handle tempHandle;
  592.     long tilticks;
  593.     Boolean returnVal = false;
  594.     Str31 myStr;
  595.     short myitem ;
  596.  
  597.     GetPort(&temp);
  598.     SetPort(dialer);
  599.     myItem = ((DialogPeek)dialer)->editField + 1 ;
  600.     /* Some key filtering schemes follow.  The first is the standard filter to
  601.      * recognize 'return' as Use and 'ESC' as Cancel.
  602.      */
  603.  
  604.     if ((myDialogEvent->what == keyDown) || (myDialogEvent->what == autoKey)) {
  605.         theKey = myDialogEvent->message & charCodeMask;
  606.         switch (theKey) {
  607.             case kReturnKey:
  608.             case kEnterKey:
  609.                 *theDialogItem = screenuseBU ;
  610.                 HiliteControl(SnatchHandle(dialer, screenuseBU), inButton);
  611.                 Delay(8, &tilticks); 
  612.                 HiliteControl(SnatchHandle(dialer, screenuseBU), false);
  613.                 SetPort(temp);
  614.                 returnVal = true;
  615.                 break;
  616.             case kEscKey:
  617.                 *theDialogItem = screencancelBU;
  618.                 HiliteControl(SnatchHandle(dialer, screencancelBU), inButton);
  619.                 Delay(8, &tilticks);
  620.                 HiliteControl(SnatchHandle(dialer, screencancelBU), false);
  621.                 SetPort(temp);
  622.                 returnVal = true;
  623.                 break;
  624.             case kTabKey:
  625.                 returnVal = false ;
  626.                 break ;
  627.             default:
  628.                 /* All non numeric key presses are removed here and a beep is sounded */
  629.                 if((myItem == customxET) || (myItem == customyET)) {
  630.                     if(!isdigit(theKey) && !IsEditKey(theKey)) {
  631.                         SysBeep(1);
  632.                         returnVal = true ;
  633.                     }
  634.                     else {                        
  635.                         GetDItem(dialer, myItem, &tempItem, &tempHandle, &tempRect);
  636.                         GetIText(tempHandle, myStr);
  637.                         
  638.                         if (myStr[0] > 4) {
  639.                             if (IsEditKey(theKey))
  640.                                 returnVal = false;
  641.                             else {
  642.                                 SysBeep(1);
  643.                                 returnVal = true;
  644.                             }
  645.                         }
  646.                         
  647.                     }
  648.                 }
  649.                 break ;
  650.         }
  651.     }
  652.     return(returnVal);
  653. }
  654.  
  655. /* 
  656.  * Set the camera position and direction
  657.  */
  658. void SetCameraOptions()
  659. {
  660.     GrafPtr currPort;
  661.     ControlHandle handle ;
  662.     Handle tempHandle ;
  663.     Rect r, tempRect ;
  664.     int itype ;
  665.     Str255 output ;
  666.     DialogPtr myDialog = 0L;
  667.     ControlHandle temp ;
  668.     short hitItem = 0, tempItem;
  669.     char exit = 0 ;
  670.     Vector pos, lookp, up, lookdir ;
  671.     Float aperture, fov, focaldist ;
  672.     
  673.     pos = Camera.pos ;
  674.     lookp = Camera.lookp ;
  675.     up = Camera.up ;
  676.     aperture = Camera.aperture ;
  677.     fov = Camera.hfov ;
  678.     focaldist = Camera.focaldist ;
  679.  
  680.     myDialog = GetNewDialog(cameraoptionsR, 0L, (WindowPtr)-1);
  681.     
  682.     SetFloatEditText(myDialog,observerxET,pos.x) ;
  683.     SetFloatEditText(myDialog,observeryET,pos.y) ;
  684.     SetFloatEditText(myDialog,observerzET,pos.z) ;
  685.  
  686.     SetFloatEditText(myDialog,targetxET,lookp.x) ;
  687.     SetFloatEditText(myDialog,targetyET,lookp.y) ;
  688.     SetFloatEditText(myDialog,targetzET,lookp.z) ;
  689.  
  690.     SetFloatEditText(myDialog,upvectorxET,up.x) ;
  691.     SetFloatEditText(myDialog,upvectoryET,up.y) ;
  692.     SetFloatEditText(myDialog,upvectorzET,up.z) ;
  693.     
  694.     SetFloatEditText(myDialog,apertureET,aperture) ;
  695.     SetFloatEditText(myDialog,fieldofvisionET,fov) ;
  696.     SetFloatEditText(myDialog,focaldistanceET,focaldist) ;
  697.     
  698.     GetPort(&currPort);
  699.     SetPort(myDialog);
  700.     DrawDialog(myDialog);
  701.     DrawHilite(myDialog,camerauseBU) ;
  702.     do {
  703.         ModalDialog((ModalFilterProcPtr)cameraoptionsfilter, &hitItem);
  704.         
  705.         switch(hitItem) {
  706.             case crosshair2observerBU:
  707.                 SetFloatEditText(myDialog,observerxET,crosshair.x) ;
  708.                 SetFloatEditText(myDialog,observeryET,crosshair.y) ;
  709.                 SetFloatEditText(myDialog,observerzET,crosshair.z) ;
  710.                 break;
  711.             case crosshair2targetBU:
  712.                 SetFloatEditText(myDialog,targetxET,crosshair.x) ;
  713.                 SetFloatEditText(myDialog,targetyET,crosshair.y) ;
  714.                 SetFloatEditText(myDialog,targetzET,crosshair.z) ;
  715.                 break;
  716.             case crosshair2upvectorBU:
  717.                 SetFloatEditText(myDialog,upvectorxET,crosshair.x) ;
  718.                 SetFloatEditText(myDialog,upvectoryET,crosshair.y) ;
  719.                 SetFloatEditText(myDialog,upvectorzET,crosshair.z) ;
  720.                 break;
  721.             case cameracancelBU:
  722.                 /* Easy this one... */
  723.                 exit = 1 ;
  724.                 break ;
  725.             case camerauseBU:
  726.                 if(GetFloatEditText(myDialog,observerxET,&pos.x) &&
  727.                         GetFloatEditText(myDialog,observeryET,&pos.y) &&
  728.                         GetFloatEditText(myDialog,observerzET,&pos.z) &&
  729.                         GetFloatEditText(myDialog,targetxET,&lookp.x) &&
  730.                         GetFloatEditText(myDialog,targetyET,&lookp.y) &&
  731.                         GetFloatEditText(myDialog,targetzET,&lookp.z) &&
  732.                         GetFloatEditText(myDialog,upvectorxET,&up.x) &&
  733.                         GetFloatEditText(myDialog,upvectoryET,&up.y) &&
  734.                         GetFloatEditText(myDialog,upvectorzET,&up.z) &&
  735.                         GetFloatEditText(myDialog,apertureET,&Camera.aperture) &&
  736.                         GetFloatEditText(myDialog,focaldistanceET,&Camera.focaldist) &&
  737.                         GetFloatEditText(myDialog,fieldofvisionET,&Camera.hfov)) {
  738.                     lookdir.x = lookp.x-pos.x;
  739.                     lookdir.y = lookp.y-pos.y;
  740.                     lookdir.z = lookp.z-pos.z;
  741.                     VecNormalize(&up);
  742.                     VecNormalize(&lookdir);
  743.                     if(equal(lookdir.x,up.x) && equal(lookdir.y,up.y) && equal(lookdir.z,up.z)) {
  744.                         RLerror(RL_WARN,"Look direction and up vector are identical !",0,0,0);
  745.                         break;
  746.                     }
  747.                     Camera.pos = pos;
  748.                     Camera.lookp = lookp;
  749.                     Camera.up = up;
  750.                     exit = 1 ;
  751.                 }
  752.                 else
  753.                     SysBeep(1);
  754.                 break ;
  755.         } ;
  756.     } while (!exit);
  757.     DisposDialog(myDialog);
  758.     if(editorDialog) {
  759.         SetPort(editorDialog);
  760.         InvalRect(&editorDialog->portRect) ;
  761.     }
  762.     SetPort(currPort);
  763. }
  764.  
  765. pascal Boolean 
  766. cameraoptionsfilter(DialogPtr dialer, EventRecord *myDialogEvent, short *theDialogItem)
  767. {
  768.     WindowPtr temp;
  769.     char theKey;
  770.     Rect tempRect;
  771.     short tempItem, myItem;
  772.     Handle tempHandle;
  773.     long tilticks;
  774.     Boolean returnVal = false;
  775.     Str31 myStr;
  776.     short myitem ;
  777.  
  778.     GetPort(&temp);
  779.     SetPort(dialer);
  780.     myItem = ((DialogPeek)dialer)->editField + 1 ;
  781.     /* Some key filtering schemes follow.  The first is the standard filter to
  782.      * recognize 'return' as Use and 'ESC' as Cancel.
  783.      */
  784.  
  785.     if ((myDialogEvent->what == keyDown) || (myDialogEvent->what == autoKey)) {
  786.         theKey = myDialogEvent->message & charCodeMask;
  787.         switch (theKey) {
  788.             case kReturnKey:
  789.             case kEnterKey:
  790.                 *theDialogItem = camerauseBU ;
  791.                 HiliteControl(SnatchHandle(dialer, camerauseBU), inButton);
  792.                 Delay(8, &tilticks); 
  793.                 HiliteControl(SnatchHandle(dialer, camerauseBU), false);
  794.                 SetPort(temp);
  795.                 returnVal = true;
  796.                 break;
  797.             case kEscKey:
  798.                 *theDialogItem = cameracancelBU;
  799.                 HiliteControl(SnatchHandle(dialer, cameracancelBU), inButton);
  800.                 Delay(8, &tilticks);
  801.                 HiliteControl(SnatchHandle(dialer, cameracancelBU), false);
  802.                 SetPort(temp);
  803.                 returnVal = true;
  804.                 break;
  805.             case kTabKey:
  806.                 returnVal = false ;
  807.                 break ;
  808.             default:
  809.                 /* All non numeric key presses are removed here and a beep is sounded */
  810.                 if(!isdigit(theKey) && !IsEditKey(theKey) && (theKey != '.') && (theKey != '-')) {
  811.                     SysBeep(1);
  812.                     returnVal = true ;
  813.                 }
  814.                 else {                        
  815.                     GetDItem(dialer, myItem, &tempItem, &tempHandle, &tempRect);
  816.                     GetIText(tempHandle, myStr);
  817.                     
  818.                     if (myStr[0] > 10) {
  819.                         if (IsEditKey(theKey))
  820.                             returnVal = false;
  821.                         else {
  822.                             SysBeep(1);
  823.                             returnVal = true;
  824.                         }
  825.                     }
  826.                 }
  827.                 break ;
  828.         }
  829.     }
  830.     return(returnVal);
  831. }
  832.  
  833. void RSAlert(type, pat, arg1, arg2, arg3)
  834. char *type, *pat, *arg1, *arg2, *arg3;
  835. {
  836.     Str255 message ;
  837.     DialogPtr alertDialog = 0L;
  838.     Handle temp ;
  839.     short hitItem = 0;
  840.     Rect r ;
  841.     short itype ;
  842.  
  843.     sprintf(&message[1], pat, arg1, arg2, arg3);
  844.     message[0] = strlen(&message[1]) ;
  845.     if(message[message[0]] == '\n') message[0]-- ;
  846.     alertDialog = GetNewDialog(erroralertR, 0L, (WindowPtr)-1);
  847.     DrawDialog(alertDialog);
  848.     GetDItem(alertDialog,3,&itype,&temp,&r) ;
  849.     SetIText(temp,&message) ;
  850.     DrawHilite(alertDialog,1) ;
  851.     do {
  852.         ModalDialog(0L, &hitItem);
  853.     } while (hitItem != 1);
  854.     DisposDialog(alertDialog);
  855. }
  856.  
  857. /* Dialog toolbox routines */
  858.  
  859. /* Highlight a dialog item  with a rounded rectangle */
  860. pascal void DrawHilite(DialogPtr theDialog, short itemNo)
  861. {
  862.     PenState saveState;
  863.     short itemType;
  864.     Handle itemHandle;
  865.     Rect itemBox;
  866.     GrafPtr currPort ;
  867.         
  868.     GetPort(&currPort);
  869.     SetPort(theDialog);
  870.     GetDItem(theDialog, itemNo, &itemType, &itemHandle, &itemBox);
  871.     GetPenState(&saveState);
  872.     PenSize(3,3);
  873.     InsetRect(&itemBox, -4, -4);
  874.     FrameRoundRect(&itemBox, 16, 16);
  875.     SetPenState(&saveState);
  876.     SetPort(currPort) ;
  877. }
  878.  
  879. /* Get the control handle for a dialog item */
  880. ControlHandle SnatchHandle(DialogPtr thebox, short theGetItem)
  881. {
  882.     short itemtype;
  883.     Rect itemrect;
  884.     Handle thandle;
  885.     
  886.     GetDItem(thebox, theGetItem, &itemtype, &thandle, &itemrect);
  887.     return((ControlHandle)thandle);
  888. }
  889.  
  890. /* Check to see if key is left arrow, delete, backspace etc */
  891. Boolean IsEditKey(char theKey)
  892. {
  893.     register qq;
  894.     char editChars[5] =  {
  895.         kLeftArrow, kUpArrow, kRightArrow, kDownArrow, kBackSpace 
  896.     };
  897.     for (qq = 0; qq < 5; qq++) {
  898.         if (theKey == editChars[qq])
  899.             return(true);
  900.     }
  901.     return(false);
  902. }
  903.  
  904. void SetFloatEditText(DialogPtr myDialog, short itemno, Float value)
  905. {
  906.     Str255 number ;
  907.     Rect itemRect ;
  908.     ControlHandle itemHandle ;
  909.     long itemType ;
  910.  
  911.     sprintf(&number[1],"%.3f",(float)value) ;
  912.     number[0] = strlen(&number[1]) ;
  913.     GetDItem(myDialog,itemno,&itemType,&itemHandle,&itemRect) ;
  914.     SetIText(itemHandle,&number) ;
  915. }
  916.  
  917. void SetFloatStringText(DialogPtr myDialog, short itemno, char *str, Float value)
  918. {
  919.     Str255 number ;
  920.     Rect itemRect ;
  921.     ControlHandle itemHandle ;
  922.     long itemType ;
  923.  
  924.     sprintf(&number[1],"%s %.3f",str,(float)value) ;
  925.     number[0] = strlen(&number[1]) ;
  926.     GetDItem(myDialog,itemno,&itemType,&itemHandle,&itemRect) ;
  927.     SetIText(itemHandle,&number) ;
  928. }
  929.  
  930.  
  931. char GetFloatEditText(DialogPtr myDialog, short theItem, Float *value)
  932. {
  933.     Str255 number ;
  934.  
  935.     GetIText(SnatchHandle(myDialog,theItem), number) ;
  936.     return StrtoFloat(number,value) ;
  937. }
  938.  
  939. char GetIntEditText(DialogPtr myDialog, short theItem, int *value) 
  940. {
  941.     Str255 number ;
  942.  
  943.     GetIText(SnatchHandle(myDialog,theItem), number) ;
  944.     if(number[0]==0)
  945.         return 0;
  946.     else {
  947.         StringToNum(number,value) ;            
  948.         return 1;
  949.     }
  950. }
  951.  
  952. void SetIntEditText(DialogPtr myDialog, short itemno, int value)
  953. {
  954.     Str255 number ;
  955.     Rect itemRect ;
  956.     ControlHandle itemHandle ;
  957.     long itemType ;
  958.  
  959.     sprintf(&number[1],"%d",value) ;
  960.     number[0] = strlen(&number[1]) ;
  961.     GetDItem(myDialog,itemno,&itemType,&itemHandle,&itemRect) ;
  962.     SetIText(itemHandle,&number) ;
  963. }
  964.  
  965. void SetIntStringText(DialogPtr myDialog, short itemno, char *str, int value)
  966. {
  967.     Str255 number ;
  968.     Rect itemRect ;
  969.     ControlHandle itemHandle ;
  970.     long itemType ;
  971.  
  972.     sprintf(&number[1],"%s %d",str,value) ;
  973.     number[0] = strlen(&number[1]) ;
  974.     GetDItem(myDialog,itemno,&itemType,&itemHandle,&itemRect) ;
  975.     SetIText(itemHandle,&number) ;
  976. }
  977.  
  978. int StrtoFloat(Str255 num, Float *result) 
  979. {
  980.     char *number;
  981.     char len ;
  982.     
  983.     len = num[0] ;
  984.     if(len == 0) return 0;
  985.     number = &num[1] ;
  986.     number[len] = '\0' ;
  987.     return(sscanf(number,"%lf", result));
  988. }
  989.  
  990. char ValidFloat(Float min, Float Max, Str255 num)
  991. {
  992.     Float realnum;
  993.  
  994.     return (StrtoFloat(num, &realnum));
  995. }
  996.  
  997. /* Wait for a mouse click from the user */
  998. void GetClick()
  999. {
  1000.     EventRecord e;
  1001.     
  1002.     while (!GetNextEvent(mDownMask, &e)) ;
  1003.     while (WaitMouseUp()) ;
  1004. }