osx.cpp   osx.cpp 
skipping to change at line 43 skipping to change at line 43
#include <stdarg.h> #include <stdarg.h>
#ifdef HAVE_SYS_TIME_H #ifdef HAVE_SYS_TIME_H
#include <sys/time.h> #include <sys/time.h>
#endif #endif
#include <drawstuff/drawstuff.h> #include <drawstuff/drawstuff.h>
#include <drawstuff/version.h> #include <drawstuff/version.h>
#include "internal.h" #include "internal.h"
#include <Carbon/Carbon.h> #include <OpenGL/gl.h>
#include <AGL/agl.h> #include <GLUT/glut.h>
// Global variables // Global variables
static bool running = true; // 1 if simulation running
static bool paused = false; // 1 if in `pause' mode static bool paused = false; // 1 if in `pause' mode
static bool singlestep = false; // 1 if single step key pres sed static bool singlestep = false; // 1 if single step key pres sed
static bool writeframes = false; // 1 if frame files to be written static bool writeframes = false; // 1 if frame files to be written
static int windowWidth = -1; static int windowWidth = -1;
static int windowHeight = -1; static int windowHeight = -1;
static UInt32 modifierMask = 0;
static int mouseButtonMode = 0; static int mouseButtonMode = 0;
static bool mouseWithOption = fa lse; // Set if dragging the mouse with alt pressed static bool mouseWithOption = fa lse; // Set if dragging the mouse with alt pressed
static bool mouseWithControl = f alse; // Set if dragging the mouse with ctrl pressed static bool mouseWithControl = f alse; // Set if dragging the mouse with ctrl pressed
static dsFunctions* functions = NULL; static dsFunctions* functions = NULL;
static WindowRef windowReference; static int windowReference;
static AGLContext aglContext; static int frame = 1;
static int prev_x = 0;
static EventHandlerUPP mouseUPP = NULL; static int prev_y = 0;
static EventHandlerUPP keyboardUPP = NULL;
static EventHandlerUPP windowUPP = NULL;
// Describes the window-events we are interested in
EventTypeSpec OSX_WINDOW_EVENT_TYPES[] = {
{ kEventClassWindow, kEventWindowBoundsChanged },
{ kEventClassWindow, kEventWindowClose },
{ kEventClassWindow, kEventWindowDrawContent }
};
// Describes the mouse-events we are interested in
EventTypeSpec OSX_MOUSE_EVENT_TYPES[] = {
{ kEventClassMouse, kEventMouseDown },
{ kEventClassMouse, kEventMouseUp },
{ kEventClassMouse, kEventMouseMoved },
{ kEventClassMouse, kEventMouseDragged }
};
// Describes the key-events we are interested in
EventTypeSpec OSX_KEY_EVENT_TYPES[] = {
{ kEventClassKeyboard, kEventRawKeyDown },
// { kEventClassKeyboard, kEventRawKeyUp },
{ kEventClassKeyboard, kEventRawKeyModifiersChanged }
};
//************************************************************************* ** //************************************************************************* **
// error handling for unix // error handling for unix
static void printMessage (const char *msg1, const char *msg2, va_list ap) static void printMessage (const char *msg1, const char *msg2, va_list ap)
{ {
fflush (stderr); fflush (stderr);
fflush (stdout); fflush (stdout);
fprintf (stderr,"\n%s: ",msg1); fprintf (stderr,"\n%s: ",msg1);
vfprintf (stderr,msg2,ap); vfprintf (stderr,msg2,ap);
skipping to change at line 145 skipping to change at line 119
if( !f ){ if( !f ){
dsError( "can't open \"%s\" for writing", s ); dsError( "can't open \"%s\" for writing", s );
} }
fprintf( f,"P6\n%d %d\n255\n", windowWidth, windowHeight ); fprintf( f,"P6\n%d %d\n255\n", windowWidth, windowHeight );
for( int y=windowHeight-1; y>-1; y-- ){ for( int y=windowHeight-1; y>-1; y-- ){
fwrite( buffer[y*windowWidth], 3*windowWidth, 1, f ); fwrite( buffer[y*windowWidth], 3*windowWidth, 1, f );
} }
fclose (f); fclose (f);
} }
extern "C" void dsStop(){ extern "C" void dsStop()
{
running = false;
} }
extern "C" double dsElapsedTime() extern "C" double dsElapsedTime()
{ {
#if HAVE_GETTIMEOFDAY #if HAVE_GETTIMEOFDAY
static double prev=0.0; static double prev=0.0;
timeval tv ; timeval tv ;
gettimeofday(&tv, 0); gettimeofday(&tv, 0);
double curr = tv.tv_sec + (double) tv.tv_usec / 1000000.0 ; double curr = tv.tv_sec + (double) tv.tv_usec / 1000000.0 ;
skipping to change at line 170 skipping to change at line 143
double retval = curr-prev; double retval = curr-prev;
prev=curr; prev=curr;
if (retval>1.0) retval=1.0; if (retval>1.0) retval=1.0;
if (retval<dEpsilon) retval=dEpsilon; if (retval<dEpsilon) retval=dEpsilon;
return retval; return retval;
#else #else
return 0.01666; // Assume 60 fps return 0.01666; // Assume 60 fps
#endif #endif
} }
OSStatus osxKeyEventHandler( EventHandlerCallRef handlerCallRef, EventRef e int osxGetModifierMask()
vent, void *userData ){ {
return glutGetModifiers() & ~GLUT_ACTIVE_SHIFT;
}
UInt32 keyCode; void osxKeyEventHandler( unsigned char key, int x, int y )
UInt32 state = 0; {
void* KCHR = NULL; unsigned char uppercase;
char charCode = 0; if (key >= 'a' && key <= 'z')
char uppercase = 0; uppercase = key - ('a' - 'A');
else
switch( GetEventKind( event ) ){ uppercase = key;
case kEventRawKeyDown:
if( GetEventParameter( event, kEventParamKeyCode, ty int modifierMask = osxGetModifierMask();
peUInt32, NULL, sizeof( UInt32 ), NULL, &keyCode ) != noErr ){ if (modifierMask == 0)
break; {
} if( key >= ' ' && key <= 126 && functions -> command )
KCHR = (void *)GetScriptVariable( smCurrentScript, s functions -> command( key );
mKCHRCache ); }
charCode = (char)KeyTranslate( KCHR, keyCode, &state else if (modifierMask & GLUT_ACTIVE_CTRL)
); {
uppercase = charCode; // ctrl+key was pressed
UppercaseText( &uppercase, 1, smSystemScript ); uppercase += 'A' - 1;
//printf( "Character %d [%c] [%c] modifiers [%d]\n", switch(uppercase ){
charCode, charCode, uppercase, modifierMask ); case 'T':
dsSetTextures( !dsGetTextures() );
if( modifierMask == 0 ){ break;
if( charCode >= ' ' && charCode <= 126 && fu case 'S':
nctions -> command ){ dsSetShadows( !dsGetShadows() );
functions -> command( charCode ); break;
} case 'X':
} exit(0);
else if( ( modifierMask & controlKey ) ){ break;
// ctrl+key was pressed case 'P':
switch(uppercase ){ paused = !paused;
case 'T': singlestep = false;
dsSetTextures( !dsGetTexture break;
s() ); case 'O':
break; if( paused ){
case 'S': singlestep = true;
dsSetShadows( !dsGetShadows( }
) ); break;
break; case 'V': {
case 'X': float xyz[3],hpr[3];
running = false; dsGetViewpoint( xyz,hpr );
break; printf( "Viewpoint = (%.4f,%.4f,%.4f,%.4f,%.4f,%.4f)\n", xy
case 'P': z[0], xyz[1], xyz[2], hpr[0], hpr[1], hpr[2] );
paused = !paused; break;
singlestep = false; }
break; case 'W':
case 'O': writeframes = !writeframes;
if( paused ){ if( writeframes ){
singlestep = true; printf( "Now writing frames to PPM files\n" );
} }
break; break;
case 'V': { }
float xyz[3],hpr[3];
dsGetViewpoint( xyz,hpr );
printf( "Viewpoint = (%.4f,%
.4f,%.4f,%.4f,%.4f,%.4f)\n", xyz[0], xyz[1], xyz[2], hpr[0], hpr[1], hpr[2]
);
break;
}
case 'W':
writeframes = !writeframes;
if( writeframes ){
printf( "Now writing
frames to PPM files\n" );
}
break;
}
}
return noErr;
case kEventRawKeyModifiersChanged:
if( GetEventParameter( event, kEventParamKeyModifier
s, typeUInt32, NULL, sizeof( UInt32 ), NULL, &modifierMask ) == noErr ){
if( ( mouseWithOption && !( modifierMask & o
ptionKey ) ) || ( mouseWithControl && !( modifierMask & controlKey ) ) ){
// The mouse was being dragged using
either the command-key or the option-key modifier to emulate
// the right button or both left + r
ight.
// Now the modifier-key has been rel
eased so the mouseButtonMode must be changed accordingly
// The following releases the right-
button.
mouseButtonMode &= (~4);
mouseWithOption = false;
mouseWithControl = false;
}
return noErr;
}
break;
} }
return eventNotHandledErr;
} }
OSStatus osxMouseEventHandler( EventHandlerCallRef handlerCallRef, EventRef void osxMouseEventHandler(int button, int state, int x, int y)
event, void *userData ){ {
prev_x = x;
prev_y = y;
bool buttonDown = false; bool buttonDown = false;
HIPoint mouseLocation; switch( state ){
case GLUT_DOWN:
switch( GetEventKind( event ) ){
case kEventMouseDown:
buttonDown = true; buttonDown = true;
case kEventMouseUp: case GLUT_UP:
if( GetEventParameter( event, kEventParamWindowMouse if( button == GLUT_LEFT_BUTTON ){
Location, typeHIPoint, NULL, sizeof( HIPoint ), NULL, &mouseLocation ) != n int modifierMask = osxGetModifierMask();
oErr ){ if( modifierMask & GLUT_ACTIVE_CTRL ){
break; // Ctrl+button == right
} button = GLUT_RIGHT_BUTTON;
EventMouseButton button; mouseWithControl = true;
if( GetEventParameter( event, kEventParamMouseButton }
, typeMouseButton, NULL, sizeof( EventMouseButton ), NULL, &button ) == noE else if( modifierMask & GLUT_ACTIVE_ALT ){
rr ){ // Alt+button == left+right
mouseButtonMode = 5;
if( button == kEventMouseButtonPrimary ){ mouseWithOption = true;
if( modifierMask & controlKey ){ return;
// Ctrl+button == right }
button = kEventMouseButtonSe }
condary; if( buttonDown ){
mouseWithControl = true; if( button == GLUT_LEFT_BUTTON ) mouseButtonMode |= 1;
} // Left
else if( modifierMask & optionKey ){ if( button == GLUT_MIDDLE_BUTTON ) mouseButtonMode |= 2;
// Alt+button == left+right // Middle
mouseButtonMode = 5; if( button == GLUT_RIGHT_BUTTON ) mouseButtonMode |= 4;
mouseWithOption = true; // Right
return noErr; }
} else{
} if( button == GLUT_LEFT_BUTTON ) mouseButtonMode &= (~1);
if( buttonDown ){ // Left
if( button == kEventMouseButtonPrima if( button == GLUT_MIDDLE_BUTTON ) mouseButtonMode &= (~2);
ry ) mouseButtonMode |= 1; // Left // Middle
if( button == kEventMouseButtonTerti if( button == GLUT_RIGHT_BUTTON ) mouseButtonMode &= (~4);
ary ) mouseButtonMode |= 2; // Middle // Right
if( button == kEventMouseButtonSecon }
dary ) mouseButtonMode |= 4; // Right return;
}
else{
if( button == kEventMouseButtonPrima
ry ) mouseButtonMode &= (~1); // Left
if( button == kEventMouseButtonTerti
ary ) mouseButtonMode &= (~2); // Middle
if( button == kEventMouseButtonSecon
dary ) mouseButtonMode &= (~4);// Right
}
return noErr;
}
break;
case kEventMouseMoved:
// NO-OP
return noErr;
case kEventMouseDragged:
// Carbon provides mouse-position deltas, so we don'
t have to store the old state ourselves
if( GetEventParameter( event, kEventParamMouseDelta,
typeHIPoint, NULL, sizeof( HIPoint ), NULL, &mouseLocation ) == noErr ){
//printf( "Mode %d\n", mouseButtonMode );
dsMotion( mouseButtonMode, (int)mouseLocatio
n.x, (int)mouseLocation.y );
return noErr;
}
break;
case kEventMouseWheelMoved:
// NO-OP
break;
} }
return eventNotHandledErr;
} }
static void osxCloseMainWindow(){ void osxMotionEventHandler(int x, int y)
{
if( windowUPP != NULL ){ dsMotion( mouseButtonMode, x - prev_x, y - prev_y );
DisposeEventHandlerUPP( windowUPP ); prev_x = x;
windowUPP = NULL; prev_y = y;
}
if( aglContext != NULL ){
aglSetCurrentContext( NULL );
aglSetDrawable( aglContext, NULL );
aglDestroyContext( aglContext );
aglContext = NULL;
}
if( windowReference != NULL ){
ReleaseWindow( windowReference );
windowReference = NULL;
}
} }
OSStatus osxWindowEventHandler( EventHandlerCallRef handlerCallRef, EventRe void osxWindowReshapeEventHandler(int width, int height)
f event, void *userData ){ {
windowWidth = width;
//printf( "WindowEvent\n" ); windowHeight = height;
switch( GetEventKind(event) ){ }
case kEventWindowBoundsChanged:
WindowRef window;
GetEventParameter( event, kEventParamDirectObject, typeWindo
wRef, NULL, sizeof(WindowRef), NULL, &window );
Rect rect;
GetWindowPortBounds( window, &rect );
windowWidth = rect.right;
windowHeight = rect.bottom;
aglUpdateContext( aglContext );
break;
case kEventWindowClose:
osxCloseMainWindow();
exit( 0 );
return noErr;
case kEventWindowDrawContent:
// NO-OP
break;
}
return eventNotHandledErr;
}
static void osxCreateMainWindow( int width, int height ){
int redbits = 4;
int greenbits = 4;
int bluebits = 4;
int alphabits = 4;
int depthbits = 16;
OSStatus error;
// create pixel format attribute list
GLint pixelFormatAttributes[256];
int numAttrs = 0;
pixelFormatAttributes[numAttrs++] = AGL_RGBA;
pixelFormatAttributes[numAttrs++] = AGL_DOUBLEBUFFER;
pixelFormatAttributes[numAttrs++] = AGL_RED_SIZE;
pixelFormatAttributes[numAttrs++] = redbits;
pixelFormatAttributes[numAttrs++] = AGL_GREEN_SIZE;
pixelFormatAttributes[numAttrs++] = greenbits;
pixelFormatAttributes[numAttrs++] = AGL_BLUE_SIZE;
pixelFormatAttributes[numAttrs++] = bluebits;
pixelFormatAttributes[numAttrs++] = AGL_ALPHA_SIZE;
pixelFormatAttributes[numAttrs++] = alphabits;
pixelFormatAttributes[numAttrs++] = AGL_DEPTH_SIZE;
pixelFormatAttributes[numAttrs++] = depthbits;
pixelFormatAttributes[numAttrs++] = AGL_NONE;
// create pixel format.
AGLDevice mainMonitor = GetMainDevice();
AGLPixelFormat pixelFormat = aglChoosePixelFormat( &mainMonitor, 1, pix
elFormatAttributes );
if( pixelFormat == NULL ){
return;
}
aglContext = aglCreateContext( pixelFormat, NULL );
aglDestroyPixelFormat( pixelFormat );
if( aglContext == NULL ){
osxCloseMainWindow();
return;
}
Rect windowContentBounds;
windowContentBounds.left = 0;
windowContentBounds.top = 0;
windowContentBounds.right = width;
windowContentBounds.bottom = height;
int windowAttributes = kWindowCloseBoxAttribute
| kWindowFullZoomAttribute
| kWindowCollapseBoxAttribute
| kWindowResizableAttribute
| kWindowStandardHandlerAttribute
| kWindowLiveResizeAttribute;
error = CreateNewWindow( kDocumentWindowClass, windowAttributes, &windo
wContentBounds, &windowReference );
if( ( error != noErr ) || ( windowReference == NULL ) ){
osxCloseMainWindow();
return;
}
windowUPP = NewEventHandlerUPP( osxWindowEventHandler );
error = InstallWindowEventHandler( windowReference, windowUPP,GetEve
ntTypeCount( OSX_WINDOW_EVENT_TYPES ), OSX_WINDOW_EVENT_TYPES, NULL, NULL )
;
if( error != noErr ){
osxCloseMainWindow();
return;
}
// The process-type must be changed for a ForegroundApplication
// Unless it is a foreground-process, the application will not show
in the dock or expose and the window
// will not behave properly.
ProcessSerialNumber currentProcess;
GetCurrentProcess( &currentProcess );
TransformProcessType( &currentProcess, kProcessTransformToForeground
Application );
SetFrontProcess( &currentProcess );
SetWindowTitleWithCFString( windowReference, CFSTR( "ODE - Drawstuff" )
);
RepositionWindow( windowReference, NULL, kWindowCenterOnMainScreen );
ShowWindow( windowReference );
if( !aglSetDrawable( aglContext, GetWindowPort( windowReference ) )
){
osxCloseMainWindow();
return;
}
if( !aglSetCurrentContext( aglContext ) ){ static void osxCreateMainWindow( int width, int height )
osxCloseMainWindow(); {
} int argc = 1;
char* argv[2];
argv[0] = (char*)"";
argv[1] = NULL;
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowSize(width, height);
windowReference = glutCreateWindow("ODE - Drawstuff");
windowWidth = width; windowWidth = width;
windowHeight = height; windowHeight = height;
} }
int osxInstallEventHandlers(){ void osxRedisplayEventHandler()
{
OSStatus error; dsDrawFrame( windowWidth, windowHeight, functions, paused && !singleste
p );
mouseUPP = NewEventHandlerUPP( osxMouseEventHandler ); singlestep = false;
glutSwapBuffers();
error = InstallEventHandler( GetApplicationEventTarget(), mouseUPP, Get
EventTypeCount( OSX_MOUSE_EVENT_TYPES ), OSX_MOUSE_EVENT_TYPES, NULL, NULL // capture frames if necessary
); if( !paused && writeframes ){
if( error != noErr ){ captureFrame( frame );
return GL_FALSE; frame++;
} }
}
keyboardUPP = NewEventHandlerUPP( osxKeyEventHandler ); void osxTimerEventHandler(int);
error = InstallEventHandler( GetApplicationEventTarget(), keyboardUPP, void osxInstallTimerHandler()
GetEventTypeCount( OSX_KEY_EVENT_TYPES ), OSX_KEY_EVENT_TYPES, NULL, NULL ) {
; glutTimerFunc(1000/60, osxTimerEventHandler, 0);
if( error != noErr ){ }
return GL_FALSE;
} void osxTimerEventHandler(int)
{
glutPostRedisplay();
osxInstallTimerHandler();
}
int osxInstallEventHandlers()
{
glutKeyboardFunc(osxKeyEventHandler);
glutMouseFunc(osxMouseEventHandler);
glutMotionFunc(osxMotionEventHandler);
glutDisplayFunc(osxRedisplayEventHandler);
glutReshapeFunc(osxWindowReshapeEventHandler);
osxInstallTimerHandler();
return GL_TRUE; return GL_TRUE;
} }
extern void dsPlatformSimLoop( int givenWindowWidth, int givenWindowHeight, dsFunctions *fn, int givenPause ){ extern void dsPlatformSimLoop( int givenWindowWidth, int givenWindowHeight, dsFunctions *fn, int givenPause ){
functions = fn; functions = fn;
paused = givenPause; paused = givenPause;
osxCreateMainWindow( givenWindowWidth, givenWindowHeight ); osxCreateMainWindow( givenWindowWidth, givenWindowHeight );
skipping to change at line 514 skipping to change at line 341
" Left button - pan and tilt.\n" " Left button - pan and tilt.\n"
" Right button (or Ctrl + button) - forward and sideways. \n" " Right button (or Ctrl + button) - forward and sideways. \n"
" Left + Right button (or middle button, or Alt + button) - sideways and up.\n" " Left + Right button (or middle button, or Alt + button) - sideways and up.\n"
"\n",DS_VERSION >> 8,DS_VERSION & 0xff "\n",DS_VERSION >> 8,DS_VERSION & 0xff
); );
firsttime = false; firsttime = false;
} }
if( fn -> start ) fn->start(); if( fn -> start ) fn->start();
int frame = 1; glutMainLoop();
running = true;
while( running ){
// read in and process all pending events for the main windo
w
EventRef event;
EventTargetRef eventDispatcher = GetEventDispatcherTarget();
while( ReceiveNextEvent( 0, NULL, 0.0, TRUE, &event ) == noE
rr ){
SendEventToEventTarget( event, eventDispatcher );
ReleaseEvent( event );
}
dsDrawFrame( windowWidth, windowHeight, fn, paused && !singl
estep );
singlestep = false;
glFlush();
aglSwapBuffers( aglContext );
// capture frames if necessary
if( !paused && writeframes ){
captureFrame( frame );
frame++;
}
}
if( fn->stop ) fn->stop();
dsStopGraphics();
osxCloseMainWindow();
} }
 End of changes. 22 change blocks. 
394 lines changed or deleted 153 lines changed or added

This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/