/* Bridge Window Management Functions: int BridgeInit(int argc, char *argv[]) void BridgeDraw(int portion) void BridgeDrawSchedualed(void) int BridgeManage(CEvent *event) void BridgeSetFocus(int focus) void BridgeMap(void) void BridgeUnmap(void) void BridgeDestroy(void) --- */ #include #include "../include/unvmath.h" #include "net.h" #include "swterm.h" #define MIN(a,b) (((a) < (b)) ? (a) : (b)) #define MAX(a,b) (((a) > (b)) ? (a) : (b)) /* * Initializes the bridge window and all its resources. */ int BridgeInit(int argc, char *argv[]) { int i; int lines_visable = 3; CDisplay *display = NULL; if(total_curses_displays > 0) display = curses_display[0]; if(display == NULL) return(-1); bridge_win.x = 0; bridge_win.y = 0; bridge_win.width = CWRootWidth(display); bridge_win.height = CWRootHeight(display); bridge_win.vs_zoom = 0.3; bridge_win.screen_type = BRIDGE_SCREEN_TYPE_MAIN_MENU; /* Initialize prompt. */ PromptInit( display, &bridge_win.prompt, display->root_win, 1, CWRootHeight(display) - 5, MAX(CWRootWidth(display) - 2, 10), 1, 256, "Prompt:", NULL, BridgePromptCB ); bridge_win.prompt_mode = PROMPT_MODE_NONE; /* Allocate message buffers. */ bridge_win.total_messages = 10; bridge_win.message = (bridge_win_mesg_struct **)calloc( bridge_win.total_messages, sizeof(bridge_win_mesg_struct *) ); if(bridge_win.message == NULL) { bridge_win.total_messages = 0; return(-1); } for(i = 0; i < bridge_win.total_messages; i++) { bridge_win.message[i] = (bridge_win_mesg_struct *)calloc( 1, sizeof(bridge_win_mesg_struct) ); if(bridge_win.message[i] == NULL) break; bridge_win.message[i]->color = 0; } bridge_win.message_scroll_pos = bridge_win.total_messages - lines_visable; return(0); } /* * Redraws the bridge window. */ void BridgeDraw(int portion) { CDisplay *display = NULL; if(total_curses_displays > 0) display = curses_display[0]; if(display == NULL) return; /* Check which screen to draw. */ switch(bridge_win.screen_type) { default: /* Redraw messages. */ BridgeDrawMessages(display); /* Redraw title. */ BridgeDrawTitle(display); /* Redraw everything else. */ BridgeDrawSchedualed(); break; } return; } /* * Redraws things on the bridge window that need to be * redrawn often. */ void BridgeDrawSchedualed(void) { int object_num; xsw_object_struct *obj_ptr; CDisplay *display = NULL; if(total_curses_displays > 0) display = curses_display[0]; if(display == NULL) return; /* Change screen type as needed. */ switch(bridge_win.screen_type) { case BRIDGE_SCREEN_TYPE_MAIN_MENU: if(net_parms.connection_state != CON_STATE_NOT_CONNECTED) bridge_win.screen_type = BRIDGE_SCREEN_TYPE_VIEWSCREEN; break; case BRIDGE_SCREEN_TYPE_VIEWSCREEN: if(net_parms.connection_state == CON_STATE_NOT_CONNECTED) bridge_win.screen_type = BRIDGE_SCREEN_TYPE_MAIN_MENU; break; } /* Check which screen to draw. */ switch(bridge_win.screen_type) { case BRIDGE_SCREEN_TYPE_MAIN_MENU: BridgeDrawClearVS(display); BridgeDrawStatusBar(display); break; case BRIDGE_SCREEN_TYPE_VIEWSCREEN: object_num = net_parms.player_obj_num; if(DBIsObjectGarbage(object_num)) obj_ptr = NULL; else obj_ptr = xsw_object[object_num]; /* Clear viewscreen area. */ BridgeDrawClearVS(display); /* Draw player stats. */ BridgeDrawPlayerStats(display, object_num); /* Draw locked on subject object. */ BridgeDrawSubjectStats( display, ((obj_ptr == NULL) ? -1 : obj_ptr->locked_on) ); /* Draw objects on viewscreen. */ BridgeDrawVSObjects(display); /* Draw status bar. */ BridgeDrawStatusBar(display); break; case BRIDGE_SCREEN_TYPE_HELP: BridgeDrawClearVS(display); BridgeDrawHelp(display); BridgeDrawStatusBar(display); break; } return; } /* * Manages the bridge window. */ int BridgeManage(CEvent *event) { int key; int object_num; xsw_object_struct *obj_ptr; CDisplay *display = NULL; int events_handled = 0; if(total_curses_displays > 0) display = curses_display[0]; if((display == NULL) || (event == NULL) ) return(events_handled); /* Check if mapped and in focus? */ if(!bridge_win.map_state || !bridge_win.is_in_focus ) return(events_handled); /* ******************************************************* */ /* Manage bridge prompt first. */ if(bridge_win.prompt_mode != PROMPT_MODE_NONE) { /* Cancel? */ if((event->type == CKeyPress) && (event->ckey.key == KEY_ESC) ) { PromptUnmap(display, &bridge_win.prompt); bridge_win.prompt_mode = PROMPT_MODE_NONE; } else { events_handled += PromptManage( display, &bridge_win.prompt, event ); } if(events_handled > 0) return(events_handled); } /* Manage event normally. */ switch(event->type) { /* ***************************************************** */ case CKeyPress: /* Key press. */ key = event->ckey.key; /* Help screen. */ if(key == KEY_F1) { if(bridge_win.screen_type == BRIDGE_SCREEN_TYPE_HELP) bridge_win.screen_type = BRIDGE_SCREEN_TYPE_VIEWSCREEN; else bridge_win.screen_type = BRIDGE_SCREEN_TYPE_HELP; } /* Turn. */ else if(key == KEY_RIGHT) { /* gctl[0].turn += 0.1; if(gctl[0].turn > 1) gctl[0].turn = 1; */ /* Turn explicitly. */ object_num = net_parms.player_obj_num; obj_ptr = net_parms.player_obj_ptr; if(obj_ptr != NULL) { obj_ptr->heading = SANITIZERADIANS( obj_ptr->heading + (0.043 * time_compensation) ); } } else if(key == KEY_LEFT) { /* gctl[0].turn -= 0.1; if(gctl[0].turn < -1) gctl[0].turn = -1; */ /* Turn explicitly. */ object_num = net_parms.player_obj_num; obj_ptr = net_parms.player_obj_ptr; if(obj_ptr != NULL) { obj_ptr->heading = SANITIZERADIANS( obj_ptr->heading - (0.043 * time_compensation) ); } } /* Throttle. */ else if(key == KEY_UP) { gctl[0].throttle += 0.1; if(gctl[0].throttle > 1) gctl[0].throttle = 1; } else if(key == KEY_DOWN) { gctl[0].throttle -= 0.1; if(gctl[0].throttle < -1) gctl[0].throttle = -1; } /* Viewscreen zoom. */ else if(key == '-') { bridge_win.vs_zoom += 0.01; if(bridge_win.vs_zoom > VS_ZOOM_MAX) bridge_win.vs_zoom = VS_ZOOM_MAX; } else if(key == '_') { bridge_win.vs_zoom += 0.10; if(bridge_win.vs_zoom > VS_ZOOM_MAX) bridge_win.vs_zoom = VS_ZOOM_MAX; } else if(key == '=') { bridge_win.vs_zoom -= 0.01; if(bridge_win.vs_zoom < VS_ZOOM_MIN) bridge_win.vs_zoom = VS_ZOOM_MIN; } else if(key == '+') { bridge_win.vs_zoom -= 0.10; if(bridge_win.vs_zoom < VS_ZOOM_MIN) bridge_win.vs_zoom = VS_ZOOM_MIN; } /* Select previous weapon. */ else if(key == ',') { object_num = net_parms.player_obj_num; obj_ptr = net_parms.player_obj_ptr; if(obj_ptr != NULL) { NetSendSelectWeapon( object_num, ((obj_ptr->selected_weapon > 0) ? obj_ptr->selected_weapon - 1 : obj_ptr->total_weapons - 1 ) ); } } /* Select next weapon. */ else if(key == '.') { object_num = net_parms.player_obj_num; obj_ptr = net_parms.player_obj_ptr; if(obj_ptr != NULL) { NetSendSelectWeapon( object_num, (((obj_ptr->selected_weapon + 1) >= obj_ptr->total_weapons) ? 0 : obj_ptr->selected_weapon + 1 ) ); } } /* Weapons online/offline (weapons padlock). */ else if(key == 'w') { object_num = net_parms.player_obj_num; obj_ptr = net_parms.player_obj_ptr; if(obj_ptr != NULL) { if(local_control.weapons_online) { local_control.weapons_online = 0; MesgAdd( "Weapons have been taken offline.", 0 ); } else { local_control.weapons_online = 1; MesgAdd( "Weapons are now online.", 0 ); } } } /* Fire weapon. */ else if(key == ' ') { /* This section of code comes From REngAction() * we cannot call it since the gctl for fire weapon * cannot be set to 1 and held there due to key board * control limitations. */ int sel_wep_num; long dt; xsw_weapons_struct *wep_ptr; object_num = net_parms.player_obj_num; obj_ptr = net_parms.player_obj_ptr; while(obj_ptr != NULL) { /* Get pointer to selected weapon. */ sel_wep_num = obj_ptr->selected_weapon; if((sel_wep_num < 0) || (sel_wep_num >= obj_ptr->total_weapons) ) break; wep_ptr = obj_ptr->weapons[sel_wep_num]; if(wep_ptr == NULL) break; /* Check if weapons are online. */ if(!local_control.weapons_online) { /* Weapons are offline, play error sound. */ dt = wep_ptr->last_used + wep_ptr->delay; if(dt <= cur_millitime) { BridgeWarnWeaponsOffline(object_num); wep_ptr->last_used = cur_millitime; } break; } /* Check if we've waited the weapon's delay period. */ dt = wep_ptr->last_used + wep_ptr->delay; if(dt >= cur_millitime) break; /* Send the fire weapon command to server. */ if(NetSendFireWeapon( object_num, local_control.weapon_freq )) break; /* Mark last millitime this weapon was used. * The last used time sent by the server is ignored and * the client keeps track of the last used time. Since * the firing times and weapon delay times are synced * (or atleast reasonably synced) there shouldn't be any * problem. */ wep_ptr->last_used = cur_millitime; break; } } /* Message box scroll. */ else if(key == KEY_PAGEUP) { int lines_visable = 3; bridge_win.message_scroll_pos--; if(bridge_win.message_scroll_pos < 0) bridge_win.message_scroll_pos = 0; BridgeDrawMessages(display); } else if(key == KEY_PAGEDOWN) { int n; int lines_visable = 3; bridge_win.message_scroll_pos++; n = bridge_win.total_messages - lines_visable; if(bridge_win.message_scroll_pos > n) bridge_win.message_scroll_pos = n; BridgeDrawMessages(display); } /* Exit. */ else if(key == 'x') { BridgeMapPrompt(PROMPT_MODE_EXIT); } /* Connect. */ else if(key == KEY_F9) { BridgeMapPrompt(PROMPT_MODE_CONNECT); } /* Disconnect. */ else if(key == KEY_F10) { SWTDoDisconnect(); } /* Refresh. */ else if(key == KEY_F11) { SWTDoRefresh(); } /* Connect last. */ else if(key == KEY_F12) { if(net_parms.connection_state == CON_STATE_NOT_CONNECTED) NetOpenConnection(net_parms.address, net_parms.port); } /* Auto interval state toggle. */ else if(key == 'a') { auto_interval_tune.state = !auto_interval_tune.state; } /* Network stream interval tunning. */ else if(key == '[') { net_parms.net_int -= 25; if(net_parms.net_int < MIN_SERVER_UPDATE_INT) net_parms.net_int = MIN_SERVER_UPDATE_INT; NetSendSetInterval(); } /* Network stream interval tunning. */ else if(key == '{') { net_parms.net_int -= 100; if(net_parms.net_int < MIN_SERVER_UPDATE_INT) net_parms.net_int = MIN_SERVER_UPDATE_INT; NetSendSetInterval(); } /* Network stream interval tunning. */ else if(key == ']') { net_parms.net_int += 25; if(net_parms.net_int > MAX_SERVER_UPDATE_INT) net_parms.net_int = MAX_SERVER_UPDATE_INT; NetSendSetInterval(); } /* Network stream interval tunning. */ else if(key == '}') { net_parms.net_int += 100; if(net_parms.net_int > MAX_SERVER_UPDATE_INT) net_parms.net_int = MAX_SERVER_UPDATE_INT; NetSendSetInterval(); } /* Lock next. */ else if(key == KEY_TAB) { object_num = net_parms.player_obj_num; obj_ptr = net_parms.player_obj_ptr; if(obj_ptr != NULL) { NetSendWeaponsLock(object_num, -2); } } /* Unlock weapons. */ else if(key == 'u') { object_num = net_parms.player_obj_num; obj_ptr = net_parms.player_obj_ptr; if(obj_ptr != NULL) { NetSendWeaponsUnlock(object_num); } } /* Unlock tractor beam. */ else if(key == 'U') { object_num = net_parms.player_obj_num; obj_ptr = net_parms.player_obj_ptr; if(obj_ptr != NULL) { NetSendTractorBeamLock(object_num, -1); } } /* Vector lights. */ else if(key == 'l') { object_num = net_parms.player_obj_num; obj_ptr = net_parms.player_obj_ptr; if(obj_ptr != NULL) { if(obj_ptr->lighting & XSW_OBJ_LT_VECTOR) { obj_ptr->lighting &= ~XSW_OBJ_LT_VECTOR; MesgAdd("Vector lights: Off", 0); } else { obj_ptr->lighting |= XSW_OBJ_LT_VECTOR; MesgAdd("Vector lights: On", 0); } NetSendSetLighting( object_num, obj_ptr->lighting ); } } /* Strobe lights. */ else if(key == 'p') { object_num = net_parms.player_obj_num; obj_ptr = net_parms.player_obj_ptr; if(obj_ptr != NULL) { if(obj_ptr->lighting & XSW_OBJ_LT_STROBE) { obj_ptr->lighting &= ~XSW_OBJ_LT_STROBE; MesgAdd("Strobes: Off", 0); } else { obj_ptr->lighting |= XSW_OBJ_LT_STROBE; MesgAdd("Strobes: On", 0); } NetSendSetLighting( object_num, obj_ptr->lighting ); } } /* Engine state. */ else if(key == '`') { object_num = net_parms.player_obj_num; obj_ptr = net_parms.player_obj_ptr; if(obj_ptr != NULL) { if(obj_ptr->engine_state > 0) { NetSendSetEngine(object_num, ENGINE_STATE_OFF); MesgAdd("Engines: Off", 0); } else if(obj_ptr->engine_state == ENGINE_STATE_OFF) { NetSendSetEngine(object_num, ENGINE_STATE_ON); MesgAdd("Engines: On", 0); } } } /* Shields. */ else if(key == 's') { object_num = net_parms.player_obj_num; obj_ptr = net_parms.player_obj_ptr; if(obj_ptr != NULL) { switch(obj_ptr->shield_state) { case SHIELD_STATE_DOWN: NetSendSetShields( object_num, SHIELD_STATE_UP, obj_ptr->shield_frequency ); break; default: NetSendSetShields( object_num, SHIELD_STATE_DOWN, obj_ptr->shield_frequency ); break; } } } /* Cloak. */ else if(key == 'z') { object_num = net_parms.player_obj_num; obj_ptr = net_parms.player_obj_ptr; if(obj_ptr != NULL) { NetSendSetCloak( object_num, ((obj_ptr->cloak_state == CLOAK_STATE_UP) ? CLOAK_STATE_DOWN : CLOAK_STATE_UP ) ); } } /* Weapons online/offline toggle. */ else if(key == 'w') { object_num = net_parms.player_obj_num; obj_ptr = net_parms.player_obj_ptr; if(obj_ptr != NULL) { if(local_control.weapons_online) { local_control.weapons_online = 0; MesgAdd( "Weapons have been taken offline.", xsw_color.standard_text ); } else { local_control.weapons_online = 1; MesgAdd( "Weapons are now online.", xsw_color.standard_text ); } } } /* Send hail. */ else if(key == 'h') { object_num = net_parms.player_obj_num; obj_ptr = net_parms.player_obj_ptr; if(obj_ptr != NULL) { NetSendHail( object_num, -1, obj_ptr->com_channel ); } } /* Set intercept. */ else if(key == 'i') { obj_ptr = net_parms.player_obj_ptr; object_num = net_parms.player_obj_num; if(obj_ptr != NULL) { BridgeMapPrompt(PROMPT_MODE_INTERCEPT); } } /* Shield frequency. */ else if(key == 'f') { obj_ptr = net_parms.player_obj_ptr; object_num = net_parms.player_obj_num; if(obj_ptr != NULL) { BridgeMapPrompt(PROMPT_MODE_SHIELD_FREQ); } } /* Weapon frequency. */ else if(key == 'y') { obj_ptr = net_parms.player_obj_ptr; object_num = net_parms.player_obj_num; if(obj_ptr != NULL) { BridgeMapPrompt(PROMPT_MODE_WEAPON_FREQ); } } /* Set channel. */ else if(key == 'k') { obj_ptr = net_parms.player_obj_ptr; object_num = net_parms.player_obj_num; if(obj_ptr != NULL) { BridgeMapPrompt(PROMPT_MODE_CHANNEL); } } /* Send message. */ else if(key == '\'') { obj_ptr = net_parms.player_obj_ptr; object_num = net_parms.player_obj_num; if(obj_ptr != NULL) { BridgeMapPrompt(PROMPT_MODE_MESSAGE); } } /* Server command. */ else if(key == 'e') { obj_ptr = net_parms.player_obj_ptr; object_num = net_parms.player_obj_num; if(obj_ptr != NULL) { BridgeMapPrompt(PROMPT_MODE_SERVER_CMD); } } events_handled++; break; } return(events_handled); } /* * Changes focus of the bridge window. */ void BridgeSetFocus(int focus) { bridge_win.is_in_focus = focus; return; } /* * Maps the bridge window. */ void BridgeMap(void) { bridge_win.map_state = 1; BridgeDraw(0); return; } /* * Unmaps the bridge window. */ void BridgeUnmap(void) { bridge_win.map_state = 0; return; } /* * Destroys the bridge window, deallocating all its resources. */ void BridgeDestroy(void) { int i; CDisplay *display = NULL; if(total_curses_displays > 0) display = curses_display[0]; if(display == NULL) return; PromptDestroy(display, &bridge_win.prompt); bridge_win.prompt_mode = PROMPT_MODE_NONE; for(i = 0; i < bridge_win.total_messages; i++) { if(bridge_win.message[i] == NULL) continue; free(bridge_win.message[i]->message); free(bridge_win.message[i]); } free(bridge_win.message); bridge_win.message = NULL; bridge_win.total_messages = 0; return; }