void TopCanvas::CreateGLX(_XDisplay *_x_display, X11Window x_window, GLXFBConfig *fb_cfg) { x_display = _x_display; glx_context = glXCreateNewContext(_x_display, *fb_cfg, GLX_RGBA_TYPE, nullptr, true); if (glx_context == nullptr) { fprintf(stderr, "Failed to create GLX context\n"); exit(EXIT_FAILURE); } glx_window = glXCreateWindow(_x_display, *fb_cfg, x_window, nullptr); XSync(x_display, false); if (!glXMakeContextCurrent(_x_display, glx_window, glx_window, glx_context)) { fprintf(stderr, "Failed to attach GLX context to GLX window\n"); exit(EXIT_FAILURE); } const PixelSize effective_size = GetNativeSize(); if (effective_size.cx <= 0 || effective_size.cy <= 0) { fprintf(stderr, "Failed to query GLX drawable size\n"); exit(EXIT_FAILURE); } OpenGL::SetupContext(); SetupViewport(effective_size); }
void COpenGLView::OnSize(UINT nType, int cx, int cy) { CView::OnSize(nType, cx, cy); // TODO: Add your message handler code here GLdouble aspect_ratio; // width/height ratio if ( 0 >= cx || 0 >= cy ) { return; } SetupViewport( cx, cy ); // select the projection matrix and clear it ::glMatrixMode( GL_PROJECTION ); ::glLoadIdentity(); // compute the aspect ratio // this will keep all dimension scales equal aspect_ratio = (GLdouble)cx/(GLdouble)cy; // select the viewing volumn SetupViewingFrustum( aspect_ratio ); // switch back to the modelview matrix ::glMatrixMode( GL_MODELVIEW ); ::glLoadIdentity(); // now perform any viewing transformations SetupViewingTransform(); }
int Pause_Keydown(struct Game *game, ALLEGRO_EVENT *ev) { if ((game->menu.menustate==MENUSTATE_OPTIONS) && ((ev->keyboard.keycode==ALLEGRO_KEY_ESCAPE) || ((ev->keyboard.keycode==ALLEGRO_KEY_ENTER) && (game->menu.selected==3)))) { al_play_sample_instance(game->menu.click); ChangeMenuState(game,MENUSTATE_PAUSE); } else if ((game->menu.menustate==MENUSTATE_VIDEO) && ((ev->keyboard.keycode==ALLEGRO_KEY_ESCAPE) || ((ev->keyboard.keycode==ALLEGRO_KEY_ENTER) && (game->menu.selected==3)))) { al_play_sample_instance(game->menu.click); ChangeMenuState(game,MENUSTATE_OPTIONS); if (game->menu.options.fullscreen!=game->fullscreen) { al_toggle_display_flag(game->display, ALLEGRO_FULLSCREEN_WINDOW, game->menu.options.fullscreen); al_clear_to_color(al_map_rgb(0,0,0)); al_flip_display(); game->fullscreen = game->menu.options.fullscreen; if (game->fullscreen) al_hide_mouse_cursor(game->display); else al_show_mouse_cursor(game->display); Shared_Unload(game); al_clear_to_color(al_map_rgb(0,0,0)); al_flip_display(); SetupViewport(game); Shared_Load(game); #ifndef __clang__ void Progress(struct Game *game, float p) { al_set_target_bitmap(al_get_backbuffer(game->display)); al_clear_to_color(al_map_rgb(0,0,0)); al_draw_text_with_shadow(game->font, al_map_rgb(255,255,255), game->viewportWidth*0.0234, game->viewportHeight*0.84, ALLEGRO_ALIGN_LEFT, "Loading..."); al_draw_filled_rectangle(0, game->viewportHeight*0.985, game->viewportWidth, game->viewportHeight, al_map_rgba(128,128,128,128)); al_draw_filled_rectangle(0, game->viewportHeight*0.985, p*game->viewportWidth, game->viewportHeight, al_map_rgba(255,255,255,255)); al_flip_display(); }
bool Rcsgedit::RenderLoop() { double timeDelta = 1.0f/(double)GLManager::FPS_TARGET; double lastTime = (double)glfwGetTime(); while (GLManager::GetManager()->running) { // Draw and swap buffers Render(glfwGetTime()); glfwSwapBuffers(pWindow); // Handle events. glfwPollEvents(); if (glfwGetKey(pWindow, GLFW_KEY_ESCAPE) == GLFW_PRESS || glfwWindowShouldClose(pWindow)) { GLManager::GetManager()->running = false; } if (InputSystem::ResizeEvent(GLManager::GetManager()->width, GLManager::GetManager()->height)) { SetupViewport(); } // Update timer and try to sleep for the FPS Target. timeDelta = (double)glfwGetTime() - lastTime; lastTime = (double)glfwGetTime(); std::chrono::milliseconds sleepTime ((int)(1.0/(double)GLManager::FPS_TARGET - 1000*timeDelta)); if (sleepTime > std::chrono::milliseconds(0)) { std::this_thread::sleep_for(sleepTime); } } return true; }
heXoCam::heXoCam(Context *context, MasterControl *masterControl): Object(context), yaw_{0.0f}, pitch_{0.0f}, yawDelta_{0.0f}, pitchDelta_{0.0f}, forceMultiplier{1.0f} { masterControl_ = masterControl; SubscribeToEvent(E_SCENEUPDATE, URHO3D_HANDLER(heXoCam, HandleSceneUpdate)); rootNode_ = masterControl_->world.scene->CreateChild("Camera"); Node* leftEye = rootNode_->CreateChild("Left Eye"); leftEye->SetPosition(Vector3::LEFT); stereoCam_.first_ = leftEye->CreateComponent<Camera>(); Node* rightEye = rootNode_->CreateChild("Right Eye"); rightEye->SetPosition(Vector3::RIGHT); stereoCam_.second_ = rightEye->CreateComponent<Camera>(); camera_ = rootNode_->CreateComponent<Camera>(); camera_->SetFarClip(128.0f); rootNode_->SetPosition(Vector3(0.0f, 42.0f, -23.0f)); rootNode_->SetRotation(Quaternion(65.0f, 0.0f, 0.0f)); rigidBody_ = rootNode_->CreateComponent<RigidBody>(); rigidBody_->SetAngularDamping(10.0f); CollisionShape* collisionShape = rootNode_->CreateComponent<CollisionShape>(); collisionShape->SetSphere(0.1f); rigidBody_->SetMass(1.0f); SetupViewport(); }
void D3DOverdrawWindow:: Reshape(int w, int h) { Superclass::Reshape(w, h); SetupViewport(); PostRedisplay(); }
void Game::OnResize(int width, int height) { // TODO: Add resize functionality // m_width = width; m_height = height; SetupViewport(); }
void TopCanvas::SetDisplayOrientation(DisplayOrientation orientation) { const auto native_size = GetNativeSize(); if (native_size.cx <= 0 || native_size.cy <= 0) return; OpenGL::display_orientation = orientation; SetupViewport(PixelSize(OpenGL::window_size.x, OpenGL::window_size.y)); }
bool TopCanvas::CheckResize(PixelSize new_native_size) { if ((unsigned)new_native_size.cx == OpenGL::window_size.x && (unsigned)new_native_size.cy == OpenGL::window_size.y) return false; SetupViewport(new_native_size); return true; }
void ViewContext::OnApply(const Rect &size, SCREEN_ORIENTATION_ANGLE screenOrientation) { SetupViewport(size, screenOrientation); // ensures it's set up for rendering immediately when this call returns // NOTE: we assume OnApply() is going to be called in some other class's // OnRender() event only (like, e.g. if a new framebuffer is bound) if (m_camera != NULL) m_camera->OnRender(); }
void TopCanvas::Create(PixelSize new_size, bool full_screen, bool resizable) { #ifdef USE_EGL display = eglGetDisplay(EGL_DEFAULT_DISPLAY); surface = eglGetCurrentSurface(EGL_DRAW); #endif OpenGL::SetupContext(); SetupViewport(new_size); }
void D3DOverdrawWindow:: SetupDraw(int iViewpoint) { SetupViewport(); SetupWorld(); SetupView(iViewpoint); SetupProjection(); SetupTransforms(); SetupUniforms(); Clear(); }
void SignedDistanceFieldText::Start() { // Execute base class startup Sample::Start(); // Create the scene content CreateScene(); // Create the UI content CreateInstructions(); // Setup the viewport for displaying the scene SetupViewport(); // Hook up to the frame update events SubscribeToEvents(); }
void Ragdolls::Start() { // Execute base class startup Sample::Start(); // Create the scene content CreateScene(); // Create the UI content CreateInstructions(); // Setup the viewport for displaying the scene SetupViewport(); // Hook up to the frame update and render post-update events SubscribeToEvents(); Sample::InitMouseMode(MM_FREE); }
bool Game::OnInit() { // Init the external dependencies // bool success = SDLInit() && GlewInit(); if (!success) { m_state = GameState::INIT_FAILED; return false; } // Setup the viewport // SetupViewport(); // Change game state // m_state = GameState::INIT_SUCCESSFUL; return true; }
void CVisionTestDlg::OnSelchangeChannelportlist() { int channel; CString strComplete; // Return if there is no selection in the channel list if ( m_lChannelList.GetCurSel() == LB_ERR ) return; // Get the selected channel channel = (int)m_lChannelList.GetItemData( m_lChannelList.GetCurSel() ); m_lChannelPortList.GetText(m_lChannelPortList.GetCurSel(), strComplete ); // Extract the port and component strings m_Channels[channel].strComponentName = strComplete.Left( strComplete.Find(".") ); m_Channels[channel].strPortName = strComplete.Right( strComplete.GetLength() - strComplete.Find(".") - 1 ); // Now enable the viewport at the vision object SetupViewport( channel ); }
// Performs visual OpenGL setup, bool Rcsgedit::ApplicationSetup() { if (!WindowInitialization()) { std::cout << "Failed to initialize the OpenGL window!" << std::endl; return false; } // Only works if faces are positioned appropriately, glEnable(GL_CULL_FACE); glFrontFace(GL_CCW); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); SetupViewport(); // Now actually perform application-specific setup glGenVertexArrays(1, &vao); glBindVertexArray(vao); // Setup of vertex transfer (note we're using the "vertex" object in CodeGell) glGenBuffers(1, &pointBuffer); glBindBuffer(GL_ARRAY_BUFFER, pointBuffer); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(colorVertex), (GLvoid*)offsetof(colorVertex, x)); glEnableVertexAttribArray(0); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(colorVertex), (GLvoid*)offsetof(colorVertex, r)); glEnableVertexAttribArray(1); boringProgram = GLManager::GetManager()->CompileShaderProgram("render"); mv_location = glGetUniformLocation(boringProgram, "mv_matrix"); proj_location = glGetUniformLocation(boringProgram, "proj_matrix"); return true; }
int main(int argc, char **argv){ signal(SIGSEGV, derp); srand(time(NULL)); al_set_org_name("Super Derpy"); al_set_app_name("Back to the Browser Wars"); #ifdef ALLEGRO_MACOSX char exe_path[MAXPATHLEN]; char link_path[MAXPATHLEN]; uint32_t size = sizeof(exe_path); _NSGetExecutablePath(exe_path, &size); realpath(exe_path, link_path); chdir(link_path); #endif if(!al_init()) { fprintf(stderr, "failed to initialize allegro!\n"); return -1; } struct Game game; InitConfig(&game); game._priv.fps_count.frames_done = 0; game._priv.fps_count.fps = 0; game._priv.fps_count.old_time = 0; game._priv.font_bsod = NULL; game._priv.console = NULL; game.config.fullscreen = atoi(GetConfigOptionDefault(&game, "SuperDerpy", "fullscreen", "0")); game.config.music = atoi(GetConfigOptionDefault(&game, "SuperDerpy", "music", "10")); game.config.voice = atoi(GetConfigOptionDefault(&game, "SuperDerpy", "voice", "10")); game.config.fx = atoi(GetConfigOptionDefault(&game, "SuperDerpy", "fx", "10")); game.config.debug = atoi(GetConfigOptionDefault(&game, "SuperDerpy", "debug", "0")); game.config.width = atoi(GetConfigOptionDefault(&game, "SuperDerpy", "width", "1280")); if (game.config.width<320) game.config.width=320; game.config.height = atoi(GetConfigOptionDefault(&game, "SuperDerpy", "height", "720")); if (game.config.height<180) game.config.height=180; if(!al_init_image_addon()) { fprintf(stderr, "failed to initialize image addon!\n"); /*al_show_native_message_box(display, "Error", "Error", "Failed to initialize al_init_image_addon!", NULL, ALLEGRO_MESSAGEBOX_ERROR);*/ return -1; } if(!al_init_acodec_addon()){ fprintf(stderr, "failed to initialize audio codecs!\n"); return -1; } if(!al_install_audio()){ fprintf(stderr, "failed to initialize audio!\n"); return -1; } if(!al_install_keyboard()){ fprintf(stderr, "failed to initialize keyboard!\n"); return -1; } if(!al_init_primitives_addon()){ fprintf(stderr, "failed to initialize primitives!\n"); return -1; } if(!al_install_mouse()) { fprintf(stderr, "failed to initialize the mouse!\n"); return -1; } al_init_font_addon(); if(!al_init_ttf_addon()){ fprintf(stderr, "failed to initialize fonts!\n"); return -1; } if (game.config.fullscreen) al_set_new_display_flags(ALLEGRO_FULLSCREEN_WINDOW); else al_set_new_display_flags(ALLEGRO_WINDOWED); al_set_new_display_option(ALLEGRO_VSYNC, 2-atoi(GetConfigOptionDefault(&game, "SuperDerpy", "vsync", "1")), ALLEGRO_SUGGEST); al_set_new_display_option(ALLEGRO_OPENGL, atoi(GetConfigOptionDefault(&game, "SuperDerpy", "opengl", "1")), ALLEGRO_SUGGEST); #ifdef ALLEGRO_WINDOWS al_set_new_window_position(20, 40); // workaround nasty Windows bug with window being created off-screen #endif game.display = al_create_display(game.config.width, game.config.height); if(!game.display) { fprintf(stderr, "failed to create display!\n"); return -1; } SetupViewport(&game); PrintConsole(&game, "Viewport %dx%d", game.viewport.width, game.viewport.height); ALLEGRO_BITMAP *icon = al_load_bitmap(GetDataFilePath(&game, "icons/bttbw.png")); al_set_window_title(game.display, "Back to the Browser Wars"); al_set_display_icon(game.display, icon); al_destroy_bitmap(icon); if (game.config.fullscreen) al_hide_mouse_cursor(game.display); al_inhibit_screensaver(true); al_set_new_bitmap_flags(ALLEGRO_MIN_LINEAR); game._priv.gamestates = NULL; game._priv.event_queue = al_create_event_queue(); if(!game._priv.event_queue) { FatalError(&game, true, "Failed to create event queue."); al_destroy_display(game.display); return -1; } game.audio.v = al_create_voice(44100, ALLEGRO_AUDIO_DEPTH_INT16, ALLEGRO_CHANNEL_CONF_2); game.audio.mixer = al_create_mixer(44100, ALLEGRO_AUDIO_DEPTH_FLOAT32, ALLEGRO_CHANNEL_CONF_2); game.audio.fx = al_create_mixer(44100, ALLEGRO_AUDIO_DEPTH_FLOAT32, ALLEGRO_CHANNEL_CONF_2); game.audio.music = al_create_mixer(44100, ALLEGRO_AUDIO_DEPTH_FLOAT32, ALLEGRO_CHANNEL_CONF_2); game.audio.voice = al_create_mixer(44100, ALLEGRO_AUDIO_DEPTH_FLOAT32, ALLEGRO_CHANNEL_CONF_2); al_attach_mixer_to_voice(game.audio.mixer, game.audio.v); al_attach_mixer_to_mixer(game.audio.fx, game.audio.mixer); al_attach_mixer_to_mixer(game.audio.music, game.audio.mixer); al_attach_mixer_to_mixer(game.audio.voice, game.audio.mixer); al_set_mixer_gain(game.audio.fx, game.config.fx/10.0); al_set_mixer_gain(game.audio.music, game.config.music/10.0); al_set_mixer_gain(game.audio.voice, game.config.voice/10.0); al_register_event_source(game._priv.event_queue, al_get_display_event_source(game.display)); al_register_event_source(game._priv.event_queue, al_get_mouse_event_source()); al_register_event_source(game._priv.event_queue, al_get_keyboard_event_source()); game._priv.showconsole = game.config.debug; al_clear_to_color(al_map_rgb(0,0,0)); game._priv.timer = al_create_timer(ALLEGRO_BPS_TO_SECS(60)); // logic timer if(!game._priv.timer) { FatalError(&game, true, "Failed to create logic timer."); return -1; } al_register_event_source(game._priv.event_queue, al_get_timer_event_source(game._priv.timer)); al_flip_display(); al_start_timer(game._priv.timer); setlocale(LC_NUMERIC, "C"); game.shuttingdown = false; game.restart = false; game.mediator.lives = 3; game.mediator.score = 0; game.mediator.modificator = 1; game.mediator.heart = CreateCharacter(&game, "heart"); RegisterSpritesheet(&game, game.mediator.heart, "heart"); RegisterSpritesheet(&game, game.mediator.heart, "blank"); LoadSpritesheets(&game, game.mediator.heart); SelectSpritesheet(&game, game.mediator.heart, "heart"); char* gamestate = strdup("dosowisko"); // FIXME: don't hardcore gamestate int c; while ((c = getopt (argc, argv, "l:s:")) != -1) switch (c) { case 'l': free(gamestate); gamestate = strdup("levelX"); gamestate[5] = optarg[0]; break; case 's': free(gamestate); gamestate = strdup(optarg); break; } LoadGamestate(&game, gamestate); game._priv.gamestates->showLoading = false; // we have only one gamestate right now StartGamestate(&game, gamestate); free(gamestate); char libname[1024] = {}; snprintf(libname, 1024, "libsuperderpy-%s-loading" LIBRARY_EXTENTION, "bttbw"); void *handle = dlopen(libname, RTLD_NOW); if (!handle) { FatalError(&game, true, "Error while initializing loading screen %s", dlerror()); exit(1); } else { #define GS_LOADINGERROR FatalError(&game, true, "Error on resolving loading symbol: %s", dlerror()); exit(1); if (!(game._priv.loading.Draw = dlsym(handle, "Draw"))) { GS_LOADINGERROR; } if (!(game._priv.loading.Load = dlsym(handle, "Load"))) { GS_LOADINGERROR; } if (!(game._priv.loading.Start = dlsym(handle, "Start"))) { GS_LOADINGERROR; } if (!(game._priv.loading.Stop = dlsym(handle, "Stop"))) { GS_LOADINGERROR; } if (!(game._priv.loading.Unload = dlsym(handle, "Unload"))) { GS_LOADINGERROR; } } game._priv.loading.data = (*game._priv.loading.Load)(&game); bool redraw = false; while(1) { ALLEGRO_EVENT ev; if (redraw && al_is_event_queue_empty(game._priv.event_queue)) { struct Gamestate *tmp = game._priv.gamestates; int toLoad = 0, loaded = 0; // FIXME: move to function // TODO: support dependences while (tmp) { if ((tmp->pending_start) && (tmp->started)) { PrintConsole(&game, "Stopping gamestate \"%s\"...", tmp->name); (*tmp->api.Gamestate_Stop)(&game, tmp->data); tmp->started = false; tmp->pending_start = false; } if ((tmp->pending_load) && (!tmp->loaded)) toLoad++; tmp=tmp->next; } tmp = game._priv.gamestates; // FIXME: move to function // TODO: support dependences double t = -1; while (tmp) { if ((tmp->pending_load) && (tmp->loaded)) { PrintConsole(&game, "Unloading gamestate \"%s\"...", tmp->name); al_stop_timer(game._priv.timer); tmp->loaded = false; tmp->pending_load = false; (*tmp->api.Gamestate_Unload)(&game, tmp->data); dlclose(tmp->handle); tmp->handle = NULL; al_start_timer(game._priv.timer); } else if ((tmp->pending_load) && (!tmp->loaded)) { PrintConsole(&game, "Loading gamestate \"%s\"...", tmp->name); al_stop_timer(game._priv.timer); // TODO: take proper game name char libname[1024]; snprintf(libname, 1024, "libsuperderpy-%s-%s" LIBRARY_EXTENTION, "bttbw", tmp->name); tmp->handle = dlopen(libname,RTLD_NOW); if (!tmp->handle) { //PrintConsole(&game, "Error while loading gamestate \"%s\": %s", tmp->name, dlerror()); FatalError(&game, false, "Error while loading gamestate \"%s\": %s", tmp->name, dlerror()); tmp->pending_load = false; tmp->pending_start = false; } else { #define GS_ERROR FatalError(&game, false, "Error on resolving gamestate symbol: %s", dlerror()); tmp->pending_load = false; tmp->pending_start = false; tmp=tmp->next; continue; if (!(tmp->api.Gamestate_Draw = dlsym(tmp->handle, "Gamestate_Draw"))) { GS_ERROR; } if (!(tmp->api.Gamestate_Logic = dlsym(tmp->handle, "Gamestate_Logic"))) { GS_ERROR; } if (!(tmp->api.Gamestate_Load = dlsym(tmp->handle, "Gamestate_Load"))) { GS_ERROR; } if (!(tmp->api.Gamestate_Start = dlsym(tmp->handle, "Gamestate_Start"))) { GS_ERROR; } if (!(tmp->api.Gamestate_Pause = dlsym(tmp->handle, "Gamestate_Pause"))) { GS_ERROR; } if (!(tmp->api.Gamestate_Resume = dlsym(tmp->handle, "Gamestate_Resume"))) { GS_ERROR; } if (!(tmp->api.Gamestate_Stop = dlsym(tmp->handle, "Gamestate_Stop"))) { GS_ERROR; } if (!(tmp->api.Gamestate_Unload = dlsym(tmp->handle, "Gamestate_Unload"))) { GS_ERROR; } if (!(tmp->api.Gamestate_ProcessEvent = dlsym(tmp->handle, "Gamestate_ProcessEvent"))) { GS_ERROR; } if (!(tmp->api.Gamestate_Reload = dlsym(tmp->handle, "Gamestate_Reload"))) { GS_ERROR; } if (!(tmp->api.Gamestate_ProgressCount = dlsym(tmp->handle, "Gamestate_ProgressCount"))) { GS_ERROR; } int p = 0; void progress(struct Game *game) { p++; DrawGamestates(game); float progress = ((p / (*(tmp->api.Gamestate_ProgressCount) ? (float)*(tmp->api.Gamestate_ProgressCount) : 1))/(float)toLoad)+(loaded/(float)toLoad); if (game->config.debug) PrintConsole(game, "[%s] Progress: %d% (%d/%d)", tmp->name, (int)(progress*100), p, *(tmp->api.Gamestate_ProgressCount)); if (tmp->showLoading) (*game->_priv.loading.Draw)(game, game->_priv.loading.data, progress); DrawConsole(game); if (al_get_time() - t >= 1/60.0) { al_flip_display(); } t = al_get_time(); } t = al_get_time(); // initially draw loading screen with empty bar DrawGamestates(&game); if (tmp->showLoading) { (*game._priv.loading.Draw)(&game, game._priv.loading.data, loaded/(float)toLoad); } DrawConsole(&game); if (al_get_time() - t >= 1/60.0) { al_flip_display(); } t = al_get_time(); tmp->data = (*tmp->api.Gamestate_Load)(&game, &progress); // feel free to replace "progress" with empty function if you want to compile with clang loaded++; tmp->loaded = true; tmp->pending_load = false; } al_start_timer(game._priv.timer); } tmp=tmp->next; } bool gameActive = false; tmp=game._priv.gamestates; while (tmp) { if ((tmp->pending_start) && (!tmp->started) && (tmp->loaded)) { PrintConsole(&game, "Starting gamestate \"%s\"...", tmp->name); al_stop_timer(game._priv.timer); (*tmp->api.Gamestate_Start)(&game, tmp->data); al_start_timer(game._priv.timer); tmp->started = true; tmp->pending_start = false; } if ((tmp->started) || (tmp->pending_start) || (tmp->pending_load)) gameActive = true; tmp=tmp->next; } if (!gameActive) { PrintConsole(&game, "No gamestates left, exiting..."); break; } DrawGamestates(&game); DrawConsole(&game); al_flip_display(); redraw = false; } else {
void ViewContext::OnResize(const Rect &size, SCREEN_ORIENTATION_ANGLE screenOrientation) { SetupViewport(size, screenOrientation); }
//--------------------------------------------------------------------------- // InitializeInstance // // Performs a per-instance initialization of WTD. The WTD Command Line // parser is first called - if a valid command line was given, it does NOT // RETURN from that call, since the WTD BASIC engine is invoked straight // from there, and then the program exits. // // However, if an invalid command line (or none at all) is given, we come // back here and create the frame window, and an MDI child. // // RETURNS: TRUE if successful, or FALSE if not //--------------------------------------------------------------------------- BOOL APIENTRY InitializeInstance(LPSTR lpCmdLine, INT nCmdShow) { extern HWND hwndMDIClient; CHAR sz[320]; CHAR *def = "", *szCreate = "-2147450880"; /* this is really 0x80008000 */ INT i, j, FrameState, VPstate, flags, len; INT actions[3] = {IDD_NEVER, IDD_ALWAYS, IDD_QUERY}; HANDLE *hScr; #ifdef DEBUG auxport = 0; #endif // Set up the helpfile name and the INI file name //----------------------------------------------------------------------- SetHelpFileName (); len = GetModuleFileName (GetModuleHandle (szModName), szIni, sizeof(szIni)); while (szIni[len] != '\\') len--; szIni[len+1] = 0; strcat (szIni, szIniName); UseIniInclude ("INCLUDE", szDrvr, szIni); // Initialize the pre-defined symbol space. //----------------------------------------------------------------------- for (i=0; i<16; i++) DefPtrs[i] = DefSym[i]; // Get Window state information (max'd, hidden, etc) //----------------------------------------------------------------------- FrameState = GetPrivateProfileInt (szDrvr, "FrameState", 0, szIni); VPstate = GetPrivateProfileInt (szDrvr, "VPState", 0, szIni); ChildState = GetPrivateProfileInt (szDrvr, "MDIState", 0, szIni); GetPrivateProfileString (szDrvr, "FramePos", szCreate, sz, 80, szIni); Frx = LOWORD(atol (sz)); Fry = HIWORD(atol (sz)); GetPrivateProfileString (szDrvr, "FrameSize", szCreate, sz, 80, szIni); Frh = LOWORD(atol (sz)); Frw = HIWORD(atol (sz)); GetPrivateProfileString (szDrvr, "VPPos", szCreate, sz, 80, szIni); VPx = LOWORD(atol (sz)); VPy = HIWORD(atol (sz)); GetPrivateProfileString (szDrvr, "VPSize", szCreate, sz, 80, szIni); VPh = LOWORD(atol (sz)); VPw = HIWORD(atol (sz)); // Read the "Get XY-Coords" dialog settings //----------------------------------------------------------------------- flags = GetPrivateProfileInt (szXY, "Opts", XY_VIEWPORT | XY_STATBAR, szIni); fInsEdit = flags & XY_INSEDIT; fInsClip = flags & XY_INSCLIP; fVP = flags & XY_VIEWPORT; fStatbar = flags & XY_STATBAR; iFmtIndex = GetPrivateProfileInt (szXY, "Format", 0, szIni); // Read the search/replace vars //----------------------------------------------------------------------- GetPrivateProfileString (szDrvr, "SR", def, sz, 80, szIni); SRx = LOWORD(atol (sz)); SRy = HIWORD(atol (sz)); GetPrivateProfileString (szDrvr, "Srch", def, szSrchbuf, sizeof(szSrchbuf), szIni); GetPrivateProfileString (szDrvr, "Repl", def, szReplbuf, sizeof(szSrchbuf), szIni); // Get the environment dialog options //----------------------------------------------------------------------- flags = GetPrivateProfileInt (szDrvr, "EnvFlags", ENV_SAVEASK | ENV_CMPDLG | ENV_BACKUP, szIni); SaveAction = actions[flags & ENV_SAVEACTION]; AutoMini = flags & ENV_AUTOMINI; AutoRest = flags & ENV_AUTOREST; qsave = flags & ENV_QUERYSAVE; ChgArgs = flags & ENV_RTARGS; fBackup = flags & ENV_BACKUP; fDoCmpDlg = flags & ENV_CMPDLG; TabStops = GetPrivateProfileInt (szDrvr, "TabStops", 4, szIni); // Find and Search/Replace options //----------------------------------------------------------------------- flags = GetPrivateProfileInt (szDrvr, "SearchFlags", 0, szIni); fSrchCase = flags & SRCH_SRCHCASE; WholeWord = flags & SRCH_WHOLEWORD; // Recorder options -- the 0x3C is 60 decimal, which is the default // string length //----------------------------------------------------------------------- iRecPause = GetPrivateProfileInt (szRecorder, "Pause", 2000, szIni); flags = GetPrivateProfileInt (szRecorder, "Flags", 0x3C00 | REC_KEYS | REC_CLICKS | REC_INCDECL | REC_BALANCE, szIni); iRecInsert = flags & REC_INSERT; fRecKeys = flags & REC_KEYS; fRecClicks = flags & REC_CLICKS; fRecMoves = flags & REC_MOVES; fRecRelWnd = flags & REC_RELWND; fRecIncDecl = flags & REC_INCDECL; fRecBalance = flags & REC_BALANCE; iRecLen = HIBYTE (flags); // Runtime options //----------------------------------------------------------------------- flags = GetPrivateProfileInt (szDrvr, "RTFlags", RF_SAVERTA | #ifdef WIN32 RF_CDECL | #endif RF_ARRAYCHECK, szIni); SaveRTA = flags & RF_SAVERTA; ArrayCheck = flags & RF_ARRAYCHECK; PointerCheck = flags & RF_PTRCHECK; CdeclCalls = flags & RF_CDECL; ExpDeclare = flags & RF_EXPDECL; GetPrivateProfileString (szDrvr, "Cmd", def, cmdbuf, sizeof (cmdbuf), szIni); GetPrivateProfileString (szDrvr, "Tm", def, tmbuf, sizeof (tmbuf), szIni); GetPrivateProfileString (szDrvr, "Defc", def, sz, 80, szIni); SymCount = min (atoi (sz), 16); GetPrivateProfileString (szDrvr, "Defs", def, sz, 320, szIni); def = sz; while (*def == ' ') def++; j = 0; for (i=0; i<SymCount; i++) { while ((*def) && (*def != ' ')) DefSym[i][j++] = *def++; DefSym[i][j] = 0; def++; j = 0; } // Create the ViewPort window first //----------------------------------------------------------------------- hwndViewPort = SetupViewport (); if (!hwndViewPort) return (FALSE); if ((VPstate & 3) == 1) ShowWindow (hwndViewPort, SW_SHOWMAXIMIZED); else if ((VPstate & 3) == 2) ShowWindow (hwndViewPort, SW_SHOWMINIMIZED); // Parse the command line - if this function returns NULL, then we're // done -- no need to continue //----------------------------------------------------------------------- if (!(hScr = ParseCommandLine (lpCmdLine))) { DestroyWindow (hwndViewPort); return (FALSE); } // Get the names of the last four files opened and store them in the // list //----------------------------------------------------------------------- iFileCount = GetPrivateProfileInt (szDrvr, "fCount", 0, szIni); for (i=0; i<iFileCount; i++) { CHAR buf[10]; wsprintf (buf, "File%d", i+1); GetPrivateProfileString (szDrvr, buf, def, sz, 128, szIni); pFileOpened[i] = (PSTR)LptrAlloc (lstrlen(sz)+1); if (!pFileOpened[i]) { MPError (NULL, MB_OK | MB_ICONSTOP, IDS_OUTOFMEM); DestroyWindow (hwndViewPort); return (FALSE); } lstrcpy (pFileOpened[i], sz); } // Get the base window title //----------------------------------------------------------------------- LoadString (hInst, IDS_APPNAME, sz, sizeof(sz)); // Create the frame //----------------------------------------------------------------------- hwndFrame = CreateWindow (szFrame, sz, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN, Frx, Fry, Frw, Frh, NULL, NULL, hInst, NULL); if ((!hwndFrame) || (!hwndMDIClient) || (!hwndViewPort)) return (FALSE); // Display the frame window //----------------------------------------------------------------------- if (nCmdShow != SW_SHOWNORMAL) ShowWindow (hwndFrame, nCmdShow); else if (FrameState == 1) ShowWindow (hwndFrame, SW_SHOWMAXIMIZED); else if (FrameState == 2) ShowWindow (hwndFrame, SW_SHOWMINIMIZED); else ShowWindow (hwndFrame, SW_SHOWNORMAL); // Show the viewport if we're supposed to (sending it a WM_COMMAND msg // with the IDM_WINDOWSHOW parm... //----------------------------------------------------------------------- if (!(VPstate & 4)) SendMessage (hwndFrame, WM_COMMAND, IDM_WINDOWSHOW, 0L); // Load main menu accelerators //----------------------------------------------------------------------- if (!(hAccel = LoadAccelerators (hInst, IDMULTIPAD))) return (FALSE); UpdateWindow (hwndFrame); // Load the scripts given on the command line. //----------------------------------------------------------------------- NextFile = 0; for (i=0; hScr[i]; i++) { CHAR *scr; // If this is the first file and it has nothing in it, we add an // untitled script and we're done. //------------------------------------------------------------------- scr = LocalLock (hScr[i]); if ((!i) && (!*scr)) { AddFile (NULL); break; } // Check for an extension -- if not there, append default. Then, // load the file if it isn't already loaded. //--------------------------------------------------------------- EnsureExt (scr, 80); if (!AlreadyOpen (scr)) AddFile (scr); LocalUnlock (hScr[i]); LocalFree (hScr[i]); } for (i = 0 ; i < 4 ; i++) { wsprintf (sz, "wattrec%d", i + 1); hBitmap [i] = LoadBitmap (hInst, (LPSTR) sz); if (!hBitmap [i]) return FALSE; } // We're done. //----------------------------------------------------------------------- return (TRUE); }
static inline void HandleEvent(struct Game* game, ALLEGRO_EVENT* ev) { switch (ev->type) { case ALLEGRO_EVENT_DISPLAY_HALT_DRAWING: PauseExecution(game); al_acknowledge_drawing_halt(game->display); break; case ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING: al_acknowledge_drawing_resume(game->display); ReloadGamestates(game); ResumeExecution(game); break; case ALLEGRO_EVENT_DISPLAY_SWITCH_OUT: if (game->config.autopause) { PrintConsole(game, "Focus lost, autopausing..."); PauseExecution(game); } break; case ALLEGRO_EVENT_DISPLAY_SWITCH_IN: if (game->config.autopause) { if (game->config.debug.enabled && game->config.debug.livereload) { ReloadCode(game); } ResumeExecution(game); } break; case ALLEGRO_EVENT_DISPLAY_RESIZE: PrintConsole(game, "Resize event: %dx%d", ev->display.width, ev->display.height); #ifdef LIBSUPERDERPY_IMGUI ImGui_ImplAllegro5_InvalidateDeviceObjects(); #endif al_acknowledge_resize(game->display); #ifdef LIBSUPERDERPY_IMGUI ImGui_ImplAllegro5_CreateDeviceObjects(); #endif // SetupViewport can be expensive, so don't do it when the resize event is already outdated or doesn't change anything if (((ev->display.width != game->_priv.window_width) || (ev->display.height != game->_priv.window_height)) && (ev->display.width == al_get_display_width(game->display)) && (ev->display.height == al_get_display_height(game->display))) { SetupViewport(game); } break; case ALLEGRO_EVENT_KEY_DOWN: #ifdef ALLEGRO_ANDROID if ((ev->keyboard.keycode == ALLEGRO_KEY_MENU) || (ev->keyboard.keycode == ALLEGRO_KEY_TILDE) || (ev->keyboard.keycode == ALLEGRO_KEY_BACKQUOTE)) { #else if ((ev->keyboard.keycode == ALLEGRO_KEY_TILDE) || (ev->keyboard.keycode == ALLEGRO_KEY_BACKQUOTE)) { #endif game->_priv.showconsole = !game->_priv.showconsole; if ((ev->keyboard.modifiers & ALLEGRO_KEYMOD_CTRL) && (game->config.debug.enabled)) { game->_priv.showtimeline = game->_priv.showconsole; } } if (ev->keyboard.keycode == ALLEGRO_KEY_F12) { DrawGamestates(game); int flags = al_get_new_bitmap_flags(); al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); ALLEGRO_BITMAP* bitmap = al_create_bitmap(al_get_display_width(game->display), al_get_display_height(game->display)); al_set_new_bitmap_flags(flags); ALLEGRO_BITMAP* target = al_get_target_bitmap(); al_set_target_bitmap(bitmap); al_draw_bitmap(al_get_backbuffer(game->display), 0, 0, 0); al_set_target_bitmap(target); PrintConsole(game, "Screenshot made! Storing..."); struct ScreenshotThreadData* data = malloc(sizeof(struct ScreenshotThreadData)); data->game = game; data->bitmap = bitmap; #ifndef LIBSUPERDERPY_SINGLE_THREAD al_run_detached_thread(ScreenshotThread, data); #else ScreenshotThread(data); #endif } break; default: break; } #ifdef MAEMO5 // on Maemo we get mouse events instead of touch ones, so we'll rewrite them by ourselves if ((ev->type == ALLEGRO_EVENT_MOUSE_AXES) || (ev->type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN) || (ev->type == ALLEGRO_EVENT_MOUSE_BUTTON_UP)) { switch (ev->type) { case ALLEGRO_EVENT_MOUSE_BUTTON_DOWN: ev->type = ALLEGRO_EVENT_TOUCH_BEGIN; break; case ALLEGRO_EVENT_MOUSE_BUTTON_UP: ev->type = ALLEGRO_EVENT_TOUCH_END; break; case ALLEGRO_EVENT_MOUSE_AXES: ev->type = ALLEGRO_EVENT_TOUCH_MOVE; break; default: break; } ALLEGRO_DISPLAY* display = ev->mouse.display; float dx = ev->mouse.dx; float dy = ev->mouse.dy; float x = ev->mouse.x; float y = ev->mouse.y; double timestamp = ev->mouse.timestamp; ev->touch.display = display; ev->touch.dx = dx; ev->touch.dy = dy; ev->touch.id = 0; ev->touch.primary = true; ev->touch.source = (ALLEGRO_TOUCH_INPUT*)al_get_touch_input_event_source(); ev->touch.timestamp = timestamp; ev->touch.x = x; ev->touch.y = y; } #endif } static inline void HandleDebugEvent(struct Game* game, ALLEGRO_EVENT* ev) { switch (ev->type) { case ALLEGRO_EVENT_KEY_DOWN: switch (ev->keyboard.keycode) { case ALLEGRO_KEY_F1: if (!game->_priv.paused) { PauseExecution(game); } else { ReloadCode(game); ResumeExecution(game); } break; case ALLEGRO_KEY_F9: game->_priv.speed = ALLEGRO_BPS_TO_SECS(60.0); game->_priv.showconsole = true; PrintConsole(game, "DEBUG: Gameplay speed: 1.00x"); break; case ALLEGRO_KEY_F10: { double speed = ALLEGRO_BPS_TO_SECS(game->_priv.speed); // inverting speed -= 10; if (speed < 10) { speed = 10; } game->_priv.speed = ALLEGRO_BPS_TO_SECS(speed); game->_priv.showconsole = true; PrintConsole(game, "DEBUG: Gameplay speed: %.2fx", speed / 60.0); } break; case ALLEGRO_KEY_F11: { double speed = ALLEGRO_BPS_TO_SECS(game->_priv.speed); // inverting speed += 10; if (speed > 600) { speed = 600; } game->_priv.speed = ALLEGRO_BPS_TO_SECS(speed); game->_priv.showconsole = true; PrintConsole(game, "DEBUG: Gameplay speed: %.2fx", speed / 60.0); } break; } break; default: break; } } static inline bool MainloopEvents(struct Game* game) { do { ALLEGRO_EVENT ev; if (game->_priv.paused && !IS_EMSCRIPTEN) { // there's no frame flipping when paused, so avoid pointless busylooping al_wait_for_event(game->_priv.event_queue, &ev); } else if (!al_get_next_event(game->_priv.event_queue, &ev)) { break; } #ifdef LIBSUPERDERPY_IMGUI ImGui_ImplAllegro5_ProcessEvent(&ev); switch (ev.type) { case ALLEGRO_EVENT_KEY_CHAR: case ALLEGRO_EVENT_KEY_DOWN: case ALLEGRO_EVENT_KEY_UP: if (igGetIO()->WantCaptureKeyboard) { continue; } break; case ALLEGRO_EVENT_MOUSE_AXES: case ALLEGRO_EVENT_MOUSE_BUTTON_DOWN: case ALLEGRO_EVENT_MOUSE_BUTTON_UP: case ALLEGRO_EVENT_TOUCH_BEGIN: case ALLEGRO_EVENT_TOUCH_CANCEL: case ALLEGRO_EVENT_TOUCH_END: case ALLEGRO_EVENT_TOUCH_MOVE: if (igGetIO()->WantCaptureMouse) { continue; } break; default: break; } #endif if (game->_priv.params.handlers.event) { if ((*game->_priv.params.handlers.event)(game, &ev)) { continue; } } if (ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { EventGamestates(game, &ev); return false; } HandleEvent(game, &ev); if (game->config.debug.enabled) { HandleDebugEvent(game, &ev); } EventGamestates(game, &ev); } while (!al_is_event_queue_empty(game->_priv.event_queue)); return true; } static inline bool MainloopTick(struct Game* game) { if (game->_priv.paused) { return true; } struct Gamestate* tmp = game->_priv.gamestates; #ifdef __EMSCRIPTEN__ emscripten_pause_main_loop(); #endif game->_priv.loading.to_load = 0; game->_priv.loading.loaded = 0; game->_priv.loading.lock = true; game->loading.progress = 0; // TODO: support gamestate dependences/ordering while (tmp) { if (tmp->pending_stop) { PrintConsole(game, "Stopping gamestate \"%s\"...", tmp->name); game->_priv.current_gamestate = tmp; (*tmp->api->stop)(game, tmp->data); tmp->started = false; tmp->pending_stop = false; PrintConsole(game, "Gamestate \"%s\" stopped successfully.", tmp->name); } if (tmp->pending_load) { game->_priv.loading.to_load++; } tmp = tmp->next; } tmp = game->_priv.gamestates; while (tmp) { if (tmp->pending_unload) { #ifdef __EMSCRIPTEN__ al_detach_voice(game->audio.v); #endif PrintConsole(game, "Unloading gamestate \"%s\"...", tmp->name); tmp->loaded = false; tmp->pending_unload = false; game->_priv.current_gamestate = tmp; (*tmp->api->unload)(game, tmp->data); PrintConsole(game, "Gamestate \"%s\" unloaded successfully.", tmp->name); #ifdef __EMSCRIPTEN__ al_attach_mixer_to_voice(game->audio.mixer, game->audio.v); #endif } if (tmp->pending_load) { #ifdef __EMSCRIPTEN__ al_detach_voice(game->audio.v); #endif if (tmp->show_loading && game->_priv.loading.gamestate->open) { (*game->_priv.loading.gamestate->api->start)(game, game->_priv.loading.gamestate->data); } if (!tmp->api) { if (!OpenGamestate(game, tmp, true) || !LinkGamestate(game, tmp)) { tmp->pending_load = false; tmp->pending_start = false; continue; } } if (tmp->api) { PrintConsole(game, "Loading gamestate \"%s\"...", tmp->name); game->_priv.loading.progress = 0; game->_priv.loading.current = tmp; game->_priv.current_gamestate = tmp; struct GamestateLoadingThreadData data = {.game = game, .gamestate = tmp, .bitmap_flags = al_get_new_bitmap_flags()}; game->_priv.loading.in_progress = true; double time = al_get_time(); game->_priv.loading.time = time; CalculateProgress(game); if (tmp->show_loading) { game->loading.shown = true; DrawGamestates(game); DrawConsole(game); al_flip_display(); #ifdef __EMSCRIPTEN__ emscripten_sleep(0); #endif } #ifndef LIBSUPERDERPY_SINGLE_THREAD al_run_detached_thread(GamestateLoadingThread, &data); while (game->_priv.loading.in_progress) { double delta = al_get_time() - game->_priv.loading.time; game->time += delta; // TODO: ability to disable passing time during loading game->_priv.loading.time += delta; if (game->loading.shown && game->_priv.loading.gamestate->open) { (*game->_priv.loading.gamestate->api->logic)(game, game->_priv.loading.gamestate->data, delta); } DrawGamestates(game); if (game->_priv.texture_sync) { al_convert_memory_bitmaps(); game->_priv.texture_sync = false; al_signal_cond(game->_priv.texture_sync_cond); game->_priv.loading.time = al_get_time(); // TODO: rethink time management during loading } DrawConsole(game); al_flip_display(); if (game->_priv.bsod_sync) { al_set_target_bitmap(NULL); game->_priv.bsod_sync = false; al_signal_cond(game->_priv.bsod_cond); } al_lock_mutex(game->_priv.bsod_mutex); while (game->_priv.in_bsod) { al_wait_cond(game->_priv.bsod_cond, game->_priv.bsod_mutex); } al_unlock_mutex(game->_priv.bsod_mutex); } #else GamestateLoadingThread(&data); DrawGamestates(game); DrawConsole(game); al_flip_display(); #ifdef __EMSCRIPTEN__ emscripten_sleep(0); #endif al_convert_memory_bitmaps(); #endif al_set_new_bitmap_flags(data.bitmap_flags); ReloadShaders(game, false); if (tmp->api->post_load) { PrintConsole(game, "[%s] Post-loading...", tmp->name); tmp->api->post_load(game, tmp->data); } game->_priv.loading.progress++; CalculateProgress(game); PrintConsole(game, "Gamestate \"%s\" loaded successfully in %f seconds.", tmp->name, al_get_time() - time); game->_priv.loading.loaded++; DrawGamestates(game); DrawConsole(game); al_flip_display(); #ifdef __EMSCRIPTEN__ emscripten_sleep(0); #endif tmp->loaded = true; tmp->pending_load = false; } if (tmp->show_loading && game->_priv.loading.gamestate->open) { (*game->_priv.loading.gamestate->api->stop)(game, game->_priv.loading.gamestate->data); } tmp->show_loading = true; game->loading.shown = false; game->_priv.timestamp = al_get_time(); #ifdef __EMSCRIPTEN__ al_attach_mixer_to_voice(game->audio.mixer, game->audio.v); #endif } tmp = tmp->next; }
void Gamestate_ProcessEvent(struct Game *game, struct MenuResources* data, ALLEGRO_EVENT *ev) { if ((data->menustate == MENUSTATE_ABOUT) && (ev->type == ALLEGRO_EVENT_KEY_DOWN)) { ChangeMenuState(game, data, MENUSTATE_MAIN); return; } if (ev->type != ALLEGRO_EVENT_KEY_DOWN) return; if (data->starting) return; if (ev->keyboard.keycode==ALLEGRO_KEY_UP) { data->selected--; if ((data->selected == 2) && ((data->menustate==MENUSTATE_VIDEO) || (data->menustate==MENUSTATE_OPTIONS) || (data->menustate==MENUSTATE_AUDIO))) { data->selected --; } if ((data->menustate==MENUSTATE_VIDEO) && (data->selected==1) && (data->options.fullscreen)) data->selected--; al_play_sample_instance(data->click); } else if (ev->keyboard.keycode==ALLEGRO_KEY_DOWN) { data->selected++; if ((data->menustate==MENUSTATE_VIDEO) && (data->selected==1) && (data->options.fullscreen)) data->selected++; if ((data->selected == 2) && ((data->menustate==MENUSTATE_VIDEO) || (data->menustate==MENUSTATE_OPTIONS) || (data->menustate==MENUSTATE_AUDIO))) { data->selected ++; } al_play_sample_instance(data->click); } if (ev->keyboard.keycode==ALLEGRO_KEY_ENTER) { char *text; al_play_sample_instance(data->click); switch (data->menustate) { case MENUSTATE_MAIN: switch (data->selected) { case 0: StartGame(game, data); break; case 1: ChangeMenuState(game,data,MENUSTATE_OPTIONS); break; case 2: ChangeMenuState(game,data,MENUSTATE_ABOUT); break; case 3: UnloadGamestate(game, "menu"); break; } break; case MENUSTATE_HIDDEN: ChangeMenuState(game,data,MENUSTATE_MAIN); break; case MENUSTATE_AUDIO: text = malloc(255*sizeof(char)); switch (data->selected) { case 0: game->config.music--; if (game->config.music<0) game->config.music=10; snprintf(text, 255, "%d", game->config.music); SetConfigOption(game, "SuperDerpy", "music", text); al_set_mixer_gain(game->audio.music, game->config.music/10.0); break; case 1: game->config.fx--; if (game->config.fx<0) game->config.fx=10; snprintf(text, 255, "%d", game->config.fx); SetConfigOption(game, "SuperDerpy", "fx", text); al_set_mixer_gain(game->audio.fx, game->config.fx/10.0); break; case 2: game->config.voice--; if (game->config.voice<0) game->config.voice=10; snprintf(text, 255, "%d", game->config.voice); SetConfigOption(game, "SuperDerpy", "voice", text); al_set_mixer_gain(game->audio.voice, game->config.voice/10.0); break; case 3: ChangeMenuState(game,data,MENUSTATE_OPTIONS); break; } free(text); break; case MENUSTATE_OPTIONS: switch (data->selected) { case 0: ChangeMenuState(game,data,MENUSTATE_VIDEO); break; case 1: ChangeMenuState(game,data,MENUSTATE_AUDIO); break; case 3: ChangeMenuState(game,data,MENUSTATE_MAIN); break; default: break; } break; case MENUSTATE_VIDEO: switch (data->selected) { case 0: data->options.fullscreen = !data->options.fullscreen; if (data->options.fullscreen) SetConfigOption(game, "SuperDerpy", "fullscreen", "1"); else SetConfigOption(game, "SuperDerpy", "fullscreen", "0"); al_set_display_flag(game->display, ALLEGRO_FULLSCREEN_WINDOW, data->options.fullscreen); SetupViewport(game); PrintConsole(game, "Fullscreen toggled"); break; case 1: data->options.resolution++; int max = 0, i = 0; for (i=0; i < al_get_num_video_adapters(); i++) { ALLEGRO_MONITOR_INFO aminfo; al_get_monitor_info(i , &aminfo); int desktop_width = aminfo.x2 - aminfo.x1 + 1; int desktop_height = aminfo.y2 - aminfo.y1 + 1; int localmax = desktop_width / 320; if (desktop_height / 180 < localmax) localmax = desktop_height / 180; if (localmax > max) max = localmax; } if (data->options.resolution > max) data->options.resolution = 1; text = malloc(255*sizeof(char)); snprintf(text, 255, "%d", data->options.resolution * 320); SetConfigOption(game, "SuperDerpy", "width", text); snprintf(text, 255, "%d", data->options.resolution * 180); SetConfigOption(game, "SuperDerpy", "height", text); free(text); al_resize_display(game->display, data->options.resolution * 320, data->options.resolution * 180); if ((al_get_display_width(game->display) < (data->options.resolution * 320)) || (al_get_display_height(game->display) < (data->options.resolution * 180))) { SetConfigOption(game, "SuperDerpy", "width", "320"); SetConfigOption(game, "SuperDerpy", "height", "180"); data->options.resolution = 1; al_resize_display(game->display, 320, 180); } SetupViewport(game); PrintConsole(game, "Resolution changed"); break; case 3: ChangeMenuState(game,data,MENUSTATE_OPTIONS); break; default: break; } break; case MENUSTATE_ABOUT: break; default: UnloadGamestate(game, "menu"); return; break; } } else if (ev->keyboard.keycode==ALLEGRO_KEY_ESCAPE) { switch (data->menustate) { case MENUSTATE_OPTIONS: ChangeMenuState(game,data,MENUSTATE_MAIN); break; case MENUSTATE_ABOUT: ChangeMenuState(game,data,MENUSTATE_MAIN); break; case MENUSTATE_HIDDEN: UnloadGamestate(game, "menu"); break; case MENUSTATE_VIDEO: ChangeMenuState(game,data,MENUSTATE_OPTIONS); break; case MENUSTATE_AUDIO: ChangeMenuState(game,data,MENUSTATE_OPTIONS); break; default: ChangeMenuState(game,data,MENUSTATE_HIDDEN); data->selected = -1; data->title_pos = 0; return; } } if (data->selected==-1) data->selected=3; if (data->selected==4) data->selected=0; return; }