/* Called by the time manager task in vbl_macintosh.c */ boolean input_controller( void) { if (input_task_active) { if((heartbeat_count-dynamic_world->tick_count) < MAXIMUM_TIME_DIFFERENCE) { if (game_is_networked) // input from network { ; // all handled elsewhere now. (in network.c) } else if (replay.game_is_being_replayed) // input from recorded game file { static short phase= 0; /* When this gets to 0, update the world */ /* Minimum replay speed is a pause. */ if(replay.replay_speed != MINIMUM_REPLAY_SPEED) { if (replay.replay_speed > 0 || (--phase<=0)) { short flag_count= MAX(replay.replay_speed, 1); if (!pull_flags_from_recording(flag_count)) // oops. silly me. { if (replay.have_read_last_chunk) { assert(get_game_state()==_game_in_progress || get_game_state()==_switch_demo); set_game_state(_switch_demo); } } else { /* Increment the heartbeat.. */ heartbeat_count+= flag_count; } /* Reset the phase-> doesn't matter if the replay speed is positive */ /* +1 so that replay_speed 0 is different from replay_speed 1 */ phase= -(replay.replay_speed) + 1; } } } else // then getting input from the keyboard/mouse { long action_flags= parse_keymap(); process_action_flags(local_player_index, &action_flags, 1); heartbeat_count++; // ba-doom } } else { // dprintf("Out of phase.. (%d);g", heartbeat_count - dynamic_world->tick_count); } } return TRUE; // tells the time manager library to reschedule this task }
void handle_global_checkbox_toggled (GtkToggleButton *togglebutton, gpointer data) { if (get_game_state () != GAME_NOT_RUNNING) { GtkWidget *frame; frame = glade_xml_get_widget (pref_xml, "frame_mouse_props"); gtk_widget_set_sensitive (GTK_WIDGET (frame), FALSE); g_signal_handlers_disconnect_by_func (togglebutton, G_CALLBACK (handle_global_checkbox_toggled), data); gtk_toggle_button_set_active (togglebutton, !gtk_toggle_button_get_active (togglebutton)); } else { gnome_property_box_changed (GNOME_PROPERTY_BOX (data)); } }
bool Run() { Layout(); bool result = false; if (m_dialog.run() == 0) { result = true; } if (get_game_state() == _game_in_progress) update_game_window(); return result; }
void update_game_window( WindowPtr window, EventRecord *event) { switch(get_game_state()) { case _game_in_progress: assert(event); update_screen_window(window, event); break; case _display_quit_screens: case _display_intro_screens_for_demo: case _display_intro_screens: case _display_chapter_heading: case _display_prologue: case _display_epilogue: case _display_credits: case _display_main_menu: update_interface_display(); break; case _quit_game: case _close_game: case _switch_demo: case _change_level: case _revert_game: case _begin_display_of_epilogue: case _displaying_network_game_dialogs: break; default: halt(); break; } return; }
void process_game_key( EventRecord *event, short key) { switch(get_game_state()) { case _game_in_progress: if ((event->modifiers&cmdKey) && event->what==keyDown) { long menu_key= MenuKey(key); short menuID, menuItem; menuID= menu_key>>16; menuItem= menu_key & 0x0000ffff; if(menuID) { assert(menuID==mGame); do_menu_item_command(menuID, menuItem, has_cheat_modifiers(event)); } else { handle_game_key(event, key); } } else {
void mouse_idle(short type) { if (mouse_active) { //DCW Not present on ios /*#ifdef __APPLE__ // In raw mode, get unaccelerated deltas from HID system if (input_preferences->raw_mouse_input) OSX_Mouse_GetMouseMovement(&snapshot_delta_x, &snapshot_delta_y); #endif*/ // Calculate axis deltas float dx = snapshot_delta_x; float dy = -snapshot_delta_y; snapshot_delta_x = 0; snapshot_delta_y = 0; slurpMouseDelta(&dx, &dy); if(dx>0 || dy>0) { snapshot_delta_x = 0; snapshot_delta_y = 0; } // Mouse inversion if (TEST_FLAG(input_preferences->modifiers, _inputmod_invert_mouse)) dy = -dy; // scale input by sensitivity const float sensitivityScale = 1.f / (66.f * FIXED_ONE); float sx = sensitivityScale * input_preferences->sens_horizontal; float sy = sensitivityScale * input_preferences->sens_vertical; switch (input_preferences->mouse_accel_type) { case _mouse_accel_classic: sx *= MIX(1.f, fabs(dx * sx) * 4.f, input_preferences->mouse_accel_scale); sy *= MIX(1.f, fabs(dy * sy) * 4.f, input_preferences->mouse_accel_scale); break; case _mouse_accel_none: default: break; } dx *= sx; dy *= sy; //Add post-sensitivity lost precision, in case we can use it this time around. dx += lost_x; dy += lost_y; // 1 dx unit = 1 * 2^ABSOLUTE_YAW_BITS * (360 deg / 2^ANGULAR_BITS) // = 90 deg // // 1 dy unit = 1 * 2^ABSOLUTE_PITCH_BITS * (360 deg / 2^ANGULAR_BITS) // = 22.5 deg // Largest dx for which both -dx and +dx can be represented in 1 action flags bitset float dxLimit = 0.5f - 1.f / (1<<ABSOLUTE_YAW_BITS); // 0.4921875 dx units (~44.30 deg) // Largest dy for which both -dy and +dy can be represented in 1 action flags bitset float dyLimit = 0.5f - 1.f / (1<<ABSOLUTE_PITCH_BITS); // 0.46875 dy units (~10.55 deg) dxLimit = MIN(dxLimit, input_preferences->mouse_max_speed); dyLimit = MIN(dyLimit, input_preferences->mouse_max_speed); dx = PIN(dx, -dxLimit, dxLimit); dy = PIN(dy, -dyLimit, dyLimit); snapshot_delta_yaw = static_cast<_fixed>(dx * FIXED_ONE); snapshot_delta_pitch = static_cast<_fixed>(dy * FIXED_ONE); //DCW what the f**k is the point of keeping the lower 9 or whatever bits in there? They just get thrown out later anyway... //Lets bitshift off the unused bits, so we can add in that lost precision the next time around. snapshot_delta_yaw >>= (FIXED_FRACTIONAL_BITS-ABSOLUTE_YAW_BITS); snapshot_delta_yaw <<= (FIXED_FRACTIONAL_BITS-ABSOLUTE_YAW_BITS); snapshot_delta_pitch >>= (FIXED_FRACTIONAL_BITS-ABSOLUTE_PITCH_BITS); snapshot_delta_pitch <<= (FIXED_FRACTIONAL_BITS-ABSOLUTE_PITCH_BITS); //DCW Lets track how much precision we lost, so we can stuff it back into the input next time this function is called. lost_x = (dx * (float)FIXED_ONE) - (float)snapshot_delta_yaw; lost_y = (dy * (float)FIXED_ONE) - (float)snapshot_delta_pitch; lost_x /= (float)FIXED_ONE; lost_y /= (float)FIXED_ONE; short game_state = get_game_state(); smooth_mouselook = smoothMouselookPreference() ;//&& (game_state==_game_in_progress || game_state ==_switch_demo) && (game_state==_single_player || game_state==_network_player); } }
static void main_event_loop(void) { uint32 last_event_poll = 0; short game_state; while ((game_state = get_game_state()) != _quit_game) { uint32 cur_time = SDL_GetTicks(); bool yield_time = false; bool poll_event = false; switch (game_state) { case _game_in_progress: case _change_level: if (Console::instance()->input_active() || cur_time - last_event_poll >= TICKS_BETWEEN_EVENT_POLL) { poll_event = true; last_event_poll = cur_time; } else { SDL_PumpEvents (); // This ensures a responsive keyboard control } break; case _display_intro_screens: case _display_main_menu: case _display_chapter_heading: case _display_prologue: case _display_epilogue: case _begin_display_of_epilogue: case _display_credits: case _display_intro_screens_for_demo: case _display_quit_screens: case _displaying_network_game_dialogs: yield_time = interface_fade_finished(); poll_event = true; break; case _close_game: case _switch_demo: case _revert_game: yield_time = poll_event = true; break; } if (poll_event) { global_idle_proc(); while (true) { SDL_Event event; bool found_event = SDL_PollEvent(&event); if (yield_time) { // The game is not in a "hot" state, yield time to other // processes by calling SDL_Delay() but only try for a maximum // of 30ms int num_tries = 0; while (!found_event && num_tries < 3) { SDL_Delay(10); found_event = SDL_PollEvent(&event); num_tries++; } yield_time = false; } else if (!found_event) break; if (found_event) process_event(event); } } execute_timer_tasks(SDL_GetTicks()); idle_game_state(SDL_GetTicks()); if (game_state == _game_in_progress && !graphics_preferences->hog_the_cpu && (TICKS_PER_SECOND - (SDL_GetTicks() - cur_time)) > 10) { SDL_Delay(1); } } }
void dump_screen(void) { // Find suitable file name FileSpecifier file; int i = 0; do { char name[256]; const char* suffix; #ifdef HAVE_PNG suffix = "png"; #else suffix = "bmp"; #endif if (get_game_state() == _game_in_progress) { sprintf(name, "%s_%04d.%s", to_alnum(static_world->level_name).c_str(), i, suffix); } else { sprintf(name, "Screenshot_%04d.%s", i, suffix); } file = screenshots_dir + name; i++; } while (file.Exists()); #ifdef HAVE_PNG // build some nice metadata std::vector<IMG_PNG_text> texts; std::map<std::string, std::string> metadata; metadata["Source"] = expand_app_variables("$appName$ $appVersion$ ($appPlatform$)"); time_t rawtime; time(&rawtime); char time_string[32]; strftime(time_string, 32,"%d %b %Y %H:%M:%S +0000", gmtime(&rawtime)); metadata["Creation Time"] = time_string; if (get_game_state() == _game_in_progress) { const float FLOAT_WORLD_ONE = float(WORLD_ONE); const float AngleConvert = 360/float(FULL_CIRCLE); metadata["Level"] = static_world->level_name; char map_file_name[256]; FileSpecifier fs = environment_preferences->map_file; fs.GetName(map_file_name); metadata["Map File"] = map_file_name; if (Scenario::instance()->GetName().size()) { metadata["Scenario"] = Scenario::instance()->GetName(); } metadata["Polygon"] = boost::lexical_cast<std::string>(world_view->origin_polygon_index); metadata["X"] = boost::lexical_cast<std::string>(world_view->origin.x / FLOAT_WORLD_ONE); metadata["Y"] = boost::lexical_cast<std::string>(world_view->origin.y / FLOAT_WORLD_ONE); metadata["Z"] = boost::lexical_cast<std::string>(world_view->origin.z / FLOAT_WORLD_ONE); metadata["Yaw"] = boost::lexical_cast<std::string>(world_view->yaw * AngleConvert); short pitch = world_view->pitch; if (pitch > HALF_CIRCLE) pitch -= HALF_CIRCLE; metadata["Pitch"] = boost::lexical_cast<std::string>(pitch * AngleConvert); } for (std::map<std::string, std::string>::const_iterator it = metadata.begin(); it != metadata.end(); ++it) { IMG_PNG_text text; text.key = const_cast<char*>(it->first.c_str()); text.value = const_cast<char*>(it->second.c_str()); texts.push_back(text); } IMG_PNG_text* textp = texts.size() ? &texts[0] : 0; #endif // Without OpenGL, dumping the screen is easy if (!MainScreenIsOpenGL()) { //#ifdef HAVE_PNG // aoIMG_SavePNG(file.GetPath(), MainScreenSurface(), IMG_COMPRESS_DEFAULT, textp, texts.size()); #ifdef HAVE_SDL_IMAGE IMG_SavePNG(MainScreenSurface(), file.GetPath()); #else SDL_SaveBMP(MainScreenSurface(), file.GetPath()); #endif return; } int video_w = MainScreenPixelWidth(); int video_h = MainScreenPixelHeight(); #ifdef HAVE_OPENGL // Otherwise, allocate temporary surface... SDL_Surface *t = SDL_CreateRGBSurface(SDL_SWSURFACE, video_w, video_h, 24, #if SDL_BYTEORDER == SDL_LIL_ENDIAN 0x000000ff, 0x0000ff00, 0x00ff0000, 0); #else 0x00ff0000, 0x0000ff00, 0x000000ff, 0); #endif if (t == NULL) return; // ...and pixel buffer void *pixels = malloc(video_w * video_h * 3); if (pixels == NULL) { SDL_FreeSurface(t); return; } // Read OpenGL frame buffer glPixelStorei(GL_PACK_ALIGNMENT, 1); glReadPixels(0, 0, video_w, video_h, GL_RGB, GL_UNSIGNED_BYTE, pixels); glPixelStorei(GL_PACK_ALIGNMENT, 4); // return to default // Copy pixel buffer (which is upside-down) to surface for (int y = 0; y < video_h; y++) memcpy((uint8 *)t->pixels + t->pitch * y, (uint8 *)pixels + video_w * 3 * (video_h - y - 1), video_w * 3); free(pixels); // Save surface //#ifdef HAVE_PNG // aoIMG_SavePNG(file.GetPath(), t, IMG_COMPRESS_DEFAULT, textp, texts.size()); #ifdef HAVE_SDL_IMAGE IMG_SavePNG(t, file.GetPath()); #else SDL_SaveBMP(t, file.GetPath()); #endif SDL_FreeSurface(t); #endif }
static void process_event(const SDL_Event &event) { switch (event.type) { case SDL_MOUSEMOTION: if (get_game_state() == _game_in_progress) { mouse_moved(event.motion.xrel, event.motion.yrel); } break; case SDL_MOUSEWHEEL: if (get_game_state() == _game_in_progress) { bool up = (event.wheel.y > 0); #if SDL_VERSION_ATLEAST(2,0,4) if (event.wheel.direction == SDL_MOUSEWHEEL_FLIPPED) up = !up; #endif mouse_scroll(up); } break; case SDL_MOUSEBUTTONDOWN: if (get_game_state() == _game_in_progress) { if (!get_keyboard_controller_status()) { hide_cursor(); validate_world_window(); set_keyboard_controller_status(true); } else { SDL_Event e2; memset(&e2, 0, sizeof(SDL_Event)); e2.type = SDL_KEYDOWN; e2.key.keysym.sym = SDLK_UNKNOWN; e2.key.keysym.scancode = (SDL_Scancode)(AO_SCANCODE_BASE_MOUSE_BUTTON + event.button.button - 1); process_game_key(e2); } } else process_screen_click(event); break; case SDL_JOYBUTTONDOWN: if (get_game_state() == _game_in_progress) { SDL_Event e2; memset(&e2, 0, sizeof(SDL_Event)); e2.type = SDL_KEYDOWN; e2.key.keysym.sym = SDLK_UNKNOWN; e2.key.keysym.scancode = (SDL_Scancode)(AO_SCANCODE_BASE_JOYSTICK_BUTTON + event.button.button); process_game_key(e2); } break; case SDL_KEYDOWN: process_game_key(event); break; case SDL_TEXTINPUT: if (Console::instance()->input_active()) { Console::instance()->textEvent(event); } break; case SDL_QUIT: set_game_state(_quit_game); break; case SDL_WINDOWEVENT: switch (event.window.event) { case SDL_WINDOWEVENT_FOCUS_LOST: if (get_game_state() == _game_in_progress && get_keyboard_controller_status() && !Movie::instance()->IsRecording()) { darken_world_window(); set_keyboard_controller_status(false); show_cursor(); } break; case SDL_WINDOWEVENT_EXPOSED: #if !defined(__APPLE__) && !defined(__MACH__) // double buffering :) #ifdef HAVE_OPENGL if (MainScreenIsOpenGL()) MainScreenSwap(); else #endif update_game_window(); #endif break; } break; } }
static void process_game_key(const SDL_Event &event) { switch (get_game_state()) { case _game_in_progress: #if defined(__APPLE__) && defined(__MACH__) if ((event.key.keysym.mod & KMOD_GUI)) #else if ((event.key.keysym.mod & KMOD_ALT) || (event.key.keysym.mod & KMOD_GUI)) #endif { int item = -1; switch (event.key.keysym.sym) { case SDLK_p: item = iPause; break; case SDLK_s: item = iSave; break; case SDLK_r: item = iRevert; break; // ZZZ: Alt+F4 is also a quit gesture in Windows #ifdef __WIN32__ case SDLK_F4: #endif case SDLK_q: item = iQuitGame; break; case SDLK_RETURN: item = 0; toggle_fullscreen(); break; default: break; } if (item > 0) do_menu_item_command(mGame, item, event_has_cheat_modifiers(event)); else if (item != 0) handle_game_key(event); } else handle_game_key(event); break; case _display_intro_screens: case _display_chapter_heading: case _display_prologue: case _display_epilogue: case _display_credits: case _display_quit_screens: if (interface_fade_finished()) force_game_state_change(); else stop_interface_fade(); break; case _display_intro_screens_for_demo: stop_interface_fade(); display_main_menu(); break; case _quit_game: case _close_game: case _revert_game: case _switch_demo: case _change_level: case _begin_display_of_epilogue: case _displaying_network_game_dialogs: break; case _display_main_menu: { if (!interface_fade_finished()) stop_interface_fade(); int item = -1; switch (event.key.keysym.sym) { case SDLK_n: item = iNewGame; break; case SDLK_o: item = iLoadGame; break; case SDLK_g: item = iGatherGame; break; case SDLK_j: item = iJoinGame; break; case SDLK_p: item = iPreferences; break; case SDLK_r: item = iReplaySavedFilm; break; case SDLK_c: item = iCredits; break; // ZZZ: Alt+F4 is also a quit gesture in Windows #ifdef __WIN32__ case SDLK_F4: #endif case SDLK_q: item = iQuit; break; case SDLK_F9: dump_screen(); break; case SDLK_RETURN: #if defined(__APPLE__) && defined(__MACH__) if ((event.key.keysym.mod & KMOD_GUI)) #else if ((event.key.keysym.mod & KMOD_GUI) || (event.key.keysym.mod & KMOD_ALT)) #endif { toggle_fullscreen(); } break; case SDLK_a: item = iAbout; break; default: break; } if (item > 0) { draw_menu_button_for_command(item); do_menu_item_command(mInterface, item, event_has_cheat_modifiers(event)); } break; } } }
void preferences_show_dialog (void) { GtkWidget *dlg; GtkWidget *radio_keyboard; GtkWidget *radio_mouse; GtkWidget *check_hide_cursor; GtkWidget *check_lazy_dragging; GtkWidget *check_score_time; GtkWidget *scroll_sensitivity; GtkAdjustment *adjustment; pref_xml = glade_xml_new (GLADE_FILE, "dlg_properties", NULL); dlg = glade_xml_get_widget (pref_xml, "dlg_properties"); g_signal_connect (dlg, "apply", G_CALLBACK (handle_apply), NULL); /* get widget */ radio_keyboard = glade_xml_get_widget (pref_xml, "radio_keyboard"); radio_mouse = glade_xml_get_widget (pref_xml, "radio_mouse"); check_hide_cursor = glade_xml_get_widget (pref_xml, "check_hide_cursor"); check_lazy_dragging = glade_xml_get_widget (pref_xml, "check_lazy_dragging"); check_score_time = glade_xml_get_widget (pref_xml, "check_score_time"); scroll_sensitivity = glade_xml_get_widget (pref_xml, "scroll_sensitivity"); /* set widget state */ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio_mouse), preferences->mouse_control); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio_keyboard), preferences->keyboard_control); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_hide_cursor), preferences->hide_cursor); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_lazy_dragging), preferences->lazy_dragging); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_score_time), preferences->score_time_enabled); adjustment = gtk_range_get_adjustment (GTK_RANGE (scroll_sensitivity)); gtk_adjustment_set_value (GTK_ADJUSTMENT (adjustment), (preferences->mouse_sensitivity / 2)); /* enable according to game state */ if (get_game_state () != GAME_NOT_RUNNING) { GtkWidget *frame; frame = glade_xml_get_widget (pref_xml, "frame_constraints"); gtk_widget_set_sensitive (GTK_WIDGET (frame), FALSE); gtk_widget_set_sensitive (GTK_WIDGET (check_score_time), FALSE); } /* if keyboard control selected, disable mouse properties */ if (preferences->keyboard_control) { GtkWidget *frame = glade_xml_get_widget (pref_xml, "frame_mouse_props"); gtk_widget_set_sensitive (frame, FALSE); } /* connect widgets with handlers */ g_signal_connect (radio_mouse, "toggled", G_CALLBACK (handle_mouse_ctrl_toggled), dlg); g_signal_connect (radio_keyboard, "toggled", G_CALLBACK (handle_widget_changed), dlg); g_signal_connect (check_hide_cursor, "toggled", G_CALLBACK (handle_widget_changed), dlg); g_signal_connect (check_lazy_dragging, "toggled", G_CALLBACK (handle_widget_changed), dlg); g_signal_connect (check_score_time, "toggled", G_CALLBACK (handle_global_checkbox_toggled), dlg); g_signal_connect (adjustment, "value-changed", G_CALLBACK (handle_widget_changed), dlg); /* show dialog */ gtk_widget_show (dlg); }
static void change_panel_state( short player_index, short panel_side_index) { short state, make_sound= FALSE; struct side_data *side= get_side_data(panel_side_index); struct player_data *player= get_player_data(player_index); struct control_panel_definition *definition= get_control_panel_definition(side->control_panel_type); state= GET_CONTROL_PANEL_STATUS(side); /* Do the right thing, based on the panel type.. */ switch (definition->panel_class) { case _panel_is_oxygen_refuel: case _panel_is_shield_refuel: case _panel_is_double_shield_refuel: case _panel_is_triple_shield_refuel: #ifndef VULCAN player->control_panel_side_index= player->control_panel_side_index==panel_side_index ? NONE : panel_side_index; state= get_recharge_status(panel_side_index); SET_CONTROL_PANEL_STATUS(side, state); if (!state) set_control_panel_texture(side); #endif break; case _panel_is_computer_terminal: #ifndef VULCAN if (get_game_state()==_game_in_progress && !PLAYER_HAS_CHEATED(player) && !PLAYER_HAS_MAP_OPEN(player)) { /* this will handle changing levels, if necessary (i.e., if weÕre finished) */ enter_computer_interface(player_index, side->control_panel_permutation, calculate_level_completion_state()); } #endif break; case _panel_is_tag_switch: if (definition->item==NONE || (!state && try_and_subtract_player_item(player_index, definition->item))) { state= !state; make_sound= set_tagged_light_statuses(side->control_panel_permutation, state); if (try_and_change_tagged_platform_states(side->control_panel_permutation, state)) make_sound= TRUE; if (!side->control_panel_permutation) make_sound= TRUE; if (make_sound) { SET_CONTROL_PANEL_STATUS(side, state); set_control_panel_texture(side); } } break; case _panel_is_light_switch: state= !state; make_sound= set_light_status(side->control_panel_permutation, state); break; case _panel_is_platform_switch: state= !state; make_sound= try_and_change_platform_state(get_polygon_data(side->control_panel_permutation)->permutation, state); break; case _panel_is_pattern_buffer: #ifndef VULCAN if (dynamic_world->tick_count-player->ticks_at_last_successful_save>MINIMUM_RESAVE_TICKS && player_controlling_game() && !PLAYER_HAS_CHEATED(local_player) && !game_is_networked) { play_control_panel_sound(panel_side_index, _activating_sound); // fade_out_background_music(30); /* Assume a successful save- prevents vidding of the save game key.. */ player->ticks_at_last_successful_save= dynamic_world->tick_count; if (!save_game()) { // AMR 3/12/97 vidding happens with InputSprocket with this here //player->ticks_at_last_successful_save= 0; } // fade_in_background_music(30); } #endif break; default: halt(); } if (make_sound) { play_control_panel_sound(panel_side_index, state ? _activating_sound : _deactivating_sound); } return; }