#include "InterfaceManager.h" #include "GameManager.h" static GLuint LoadTexture() { FSSpec fileSpec; FSRef fileRef; OSStatus error; Rect bounds; GraphicsImportComponent importComponent; ComponentResult result; GWorldPtr gWorld; CFURLRef URL; CFBundleRef bundle; CFStringRef string; GLuint texture; unsigned char * pixels; string = CFStringCreateWithCString(NULL, "vectorized.png", kCFStringEncodingUTF8); bundle = CFBundleGetMainBundle(); URL = CFBundleCopyResourceURL(bundle, string, NULL, NULL); if (URL) { CFURLGetFSRef(URL, &fileRef); error = FSGetCatalogInfo(&fileRef, kFSCatInfoNone, NULL, NULL, &fileSpec, NULL); CFRelease(URL); } else { error = fnfErr; } CFRelease(string); if (error != noErr) return 0; error = GetGraphicsImporterForFile(&fileSpec, &importComponent); if (error != noErr) return 0; result = GraphicsImportGetNaturalBounds(importComponent, &bounds); if (result != noErr) return 0; if ((bounds.right & (bounds.right - 1)) != 0 || (bounds.bottom & (bounds.bottom - 1)) != 0) return 0; pixels = malloc(4 * bounds.bottom * bounds.right); error = QTNewGWorldFromPtr(&gWorld, k32ARGBPixelFormat, &bounds, NULL, NULL, 0, pixels, (4 * bounds.right)); if (error != noErr) { free(pixels); return 0; } GraphicsImportSetGWorld(importComponent, gWorld, NULL); /* I thought this was the cause of trashed memory, so I disabled it, but it turns out it was a problem elsewhere in my code. This would probably work just fine. bounds.top = bounds.bottom; bounds.bottom = 0; GraphicsImportSetBoundsRect(importComponent, &bounds); */ GraphicsImportDraw(importComponent); glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bounds.right, bounds.bottom, 0, GL_BGRA, #ifdef __BIG_ENDIAN__ GL_UNSIGNED_INT_8_8_8_8_REV, #else GL_UNSIGNED_INT_8_8_8_8, #endif pixels); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); CloseComponent(importComponent); DisposeGWorld(gWorld); free(pixels); return texture; } static pascal OSStatus MouseEventHandler(EventHandlerCallRef nextEvent, EventRef theEvent, void * userData) { #pragma unused(nextEvent) VGame * g; Point screenMouseLoc; GLfloat worldMouseLoc[2]; Rect gameWindowBounds; g = (VGame *) userData; if (g->Status != MENU) return eventNotHandledErr; if (GetEventKind(theEvent) == kEventMouseDown && g->Interface.TitleMovement < TITLEMOVE) { g->Interface.SplashUp = 0; g->Interface.SplashAlpha = 0.0; g->Interface.TitleAlpha = 1.0; g->Interface.TitleMovement = TITLEMOVE; return eventNotHandledErr; } g->Interface.TitleOver.Play = 0; g->Interface.TitleOver.Prefs = 0; g->Interface.TitleOver.Quit = 0; GetEventParameter(theEvent, kEventParamMouseLocation, typeQDPoint, NULL, sizeof(Point), NULL, &screenMouseLoc); if (!g->w.IsFullScreen) { GetWindowBounds(g->w.TheWindow, kWindowContentRgn, &gameWindowBounds); screenMouseLoc.h -= gameWindowBounds.left; screenMouseLoc.v -= gameWindowBounds.top; } gameWindowBounds = WindowSize(&g->w); worldMouseLoc[0] = ((screenMouseLoc.h * 800.0) / (float) gameWindowBounds.right); worldMouseLoc[1] = (600.0 - ((screenMouseLoc.v * 600.0) / (float) gameWindowBounds.bottom)); /* Hard coded interface element bounds... */ if (worldMouseLoc[0] > ((TITLEMOVE - 0.05) * 1000.0) && worldMouseLoc[0] < (((TITLEMOVE - 0.05) + (0.013 * 4)) * 1000.0) && worldMouseLoc[1] > (0.09 * 1000.0) && worldMouseLoc[1] < (0.11 * 1000.0)) { switch (GetEventKind(theEvent)) { case kEventMouseDown: SwitchMode(g, PLAYING); break; case kEventMouseMoved: g->Interface.TitleOver.Play = 1; break; } } else if (worldMouseLoc[0] > ((TITLEMOVE - 0.05) * 1000.0) && worldMouseLoc[0] < (((TITLEMOVE - 0.05) + (0.013 * 5)) * 1000.0) && worldMouseLoc[1] > (0.05 * 1000.0) && worldMouseLoc[1] < (0.07 * 1000.0)) { switch (GetEventKind(theEvent)) { case kEventMouseDown: if (g->w.IsFullScreen) { CreateWindowedContext(&g->w); ShowCursor(); if (g->Status & PLAYING && g->Paused) { glClear(GL_DEPTH_BUFFER_BIT); DrawWorld(&g->world, 1.0); aglSwapBuffers(g->w.Windowed); } } OpenSettingsWindow(GetSettings()); break; case kEventMouseMoved: g->Interface.TitleOver.Prefs = 1; break; } } else if (worldMouseLoc[0] > ((TITLEMOVE - 0.05) * 1000.0) && worldMouseLoc[0] < (((TITLEMOVE - 0.05) + (0.013 * 4)) * 1000.0) && worldMouseLoc[1] > (0.01 * 1000.0) && worldMouseLoc[1] < (0.03 * 1000.0)) { switch (GetEventKind(theEvent)) { case kEventMouseDown: QuitApplicationEventLoop(); break; case kEventMouseMoved: g->Interface.TitleOver.Quit = 1; break; } } return eventNotHandledErr; } void InitInterface(VInterface * i, VWindow * w, void * game) { VGame * g; EventTypeSpec eventTypes[2]; g = (VGame * )game; i->w = w; i->SplashTexture = LoadTexture(); i->SplashAlpha = 0; i->SplashUp = true; i->GameWasWon = 0; i->TitleAlpha = 0; i->TitleMovement = -TITLEMOVE; i->Title = "INFILTRATION"; i->TitleDone = false; i->TitleOver.Play = false; i->TitleOver.Prefs = false; i->TitleOver.Quit = false; eventTypes[0].eventClass = kEventClassMouse; eventTypes[0].eventKind = kEventMouseDown; eventTypes[1].eventClass = kEventClassMouse; eventTypes[1].eventKind = kEventMouseMoved; InstallApplicationEventHandler(NewEventHandlerUPP(MouseEventHandler), 2, eventTypes, g, NULL); } void DrawInterface(VInterface * i) { Rect TheSize; TheSize = WindowSize(i->w); OffsetRect(&TheSize, -TheSize.left, -TheSize.top); if(i->SplashAlpha) { glColor4f(1.0, 1.0, 1.0, i->SplashAlpha); glPushMatrix(); glScalef((800.0 / TheSize.right), (600.0 / TheSize.bottom), 0.0); glTranslatef(((TheSize.right / 2) - 256), ((TheSize.bottom / 2) - 256), 0); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, i->SplashTexture); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glBegin(GL_QUADS); glTexCoord3i(0, 0, 0); glVertex2i(0, 512); glTexCoord3i(1, 0, 0); glVertex2i(512, 512); glTexCoord3i(1, 1, 0); glVertex2i(512, 0); glTexCoord3i(0, 1, 0); glVertex2i(0, 0); glEnd(); glDisable(GL_TEXTURE_2D); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glPopMatrix(); } if(i->TitleAlpha) { glEnable(GL_LINE_SMOOTH); glColor4f(1, 0.25, 0, i->TitleAlpha); glPushMatrix(); glScalef(4600.0, 6000.0, 1); glTranslatef(0.01, 0.027, 0); DrawCStringWithVectorFont(i->Title); glPopMatrix(); if (i->GameWasWon) { glPushMatrix(); glScalef(3600.0, 5000.0, 1.0); glTranslatef(0.01, 0.07, 0.0); DrawCStringWithVectorFont("CONGRATULATIONS!"); glPopMatrix(); glPushMatrix(); glScalef(1350.0, 1000.0, 1.0); glTranslatef(0.215, 0.305, 0.0); DrawCStringWithVectorFont("YOU HAVE WON"); glPopMatrix(); } glPushMatrix(); glScalef(1000, 1000, 1); if(i->TitleOver.Prefs) glColor4f(1, 0, 0, 1); else glColor4f(0, 0.8, 0, 1); glPushMatrix(); glTranslatef(-0.05 + i->TitleMovement, 0.05, 0); DrawCStringWithVectorFont("PREFS"); glPopMatrix(); if(i->TitleOver.Quit) glColor4f(1, 0, 0, 1); else glColor4f(0, 0.8, 0, 1); glPushMatrix(); glTranslatef(0.7 - i->TitleMovement, 0.01, 0); DrawCStringWithVectorFont("QUIT"); glPopMatrix(); if(i->TitleOver.Play) glColor4f(1, 0, 0, 1); else glColor4f(0, 0.8, 0, 1); glPushMatrix(); glTranslatef(0.7 - i->TitleMovement, 0.09, 0); DrawCStringWithVectorFont("PLAY"); glPopMatrix(); glPopMatrix(); glDisable(GL_LINE_SMOOTH); } } void RunInterface(VInterface * i, float interval) { if(i->SplashUp) { i->SplashAlpha += (FADESPEED1 / interval); if(i->SplashAlpha >= 1) i->SplashUp = false; } else { if(i->SplashAlpha < 0) i->SplashAlpha = 0; else i->SplashAlpha -= (FADESPEED2 / interval); if(i->TitleAlpha < 1 - 0.00001) i->TitleAlpha += (FADESPEED3 / interval); else if(i->TitleAlpha > 1 + 0.00001) i->TitleAlpha = 1; if(i->TitleMovement < TITLEMOVE - 0.00001) i->TitleMovement += (0.000090 / interval); else if(i->TitleMovement > TITLEMOVE + 0.00001) i->TitleMovement = TITLEMOVE; } }