Esempio n. 1
0
//--------- Begin of function Nation::capture_build_camp --------//
//
int Nation::capture_build_camp(int townRecno, int raceId)
{
	Town* captureTown = town_array[townRecno];

	//---- find the best available general for the capturing action ---//

	int targetResistance;

	int unitRecno = find_best_capturer(townRecno, raceId, targetResistance);

	if( !unitRecno )
		unitRecno = hire_best_capturer(townRecno, raceId);

	if( !unitRecno )
	{
		//--- if we have plenty of cash and can use cash to decrease the resistance of the independent villagers ---//

		if( should_use_cash_to_capture() )
		{
			char resultFlag;

			Unit* skilledUnit = find_skilled_unit(SKILL_LEADING, raceId,
									  captureTown->center_x, captureTown->center_y, resultFlag);

			if( skilledUnit )
				unitRecno = skilledUnit->sprite_recno;
		}

		if( !unitRecno )
			return 0;
	}

	//------- locate a place to build the camp -------//

	short buildXLoc, buildYLoc;

	if( !find_best_firm_loc(FIRM_CAMP, captureTown->loc_x1, captureTown->loc_y1, buildXLoc, buildYLoc) )
	{
		captureTown->no_neighbor_space = 1;
		return 0;
	}

	//--- if the picked unit is an overseer of an existng camp ---//

	if( !mobilize_capturer(unitRecno) )
		return 0;

	//---------- add the action to the queue now ----------//

	err_when( captureTown->nation_recno==0 &&
				 unit_array[unitRecno]->race_id != captureTown->majority_race() );

	int actionRecno = add_action( buildXLoc, buildYLoc, captureTown->loc_x1, captureTown->loc_y1,
							ACTION_AI_BUILD_FIRM, FIRM_CAMP, 1, unitRecno );

	if( actionRecno )
		process_action(actionRecno);

	return 1;
}
Esempio n. 2
0
/*
**		Execute the last action according the server ret.
**		If action is look => prepare next actions.
**		Look is every time last of the queue.
*/
int		execute_action(int const fd, t_player *p, char *data)
{
  int		i;
  int		action_id;

  i = 0;
  if (!check_elevation(p, data))
    return (1);
  while (p->actions[i] >= 0)
    i += 1;
  if (i > 0)
    {
      i = -1;
      action_id = p->actions[0];
      while (++i < 9 && p->actions[i + 1] >= 0)
	p->actions[i] = p->actions[i + 1];
      p->actions[i] = -1;
      if ((action_id < NBR_ACTIONS &&
	   (!process_action(p, data, g_actions[action_id]) ||
	    (!i && !broadcast_if_needed(fd, p)))) ||
	  write_actions(p, fd, i - 1) == EXIT_FAILURE)
	return (EXIT_FAILURE);
    }
  return (1);
}
Esempio n. 3
0
static inline int process_input(int fd)
{
   int j,k;

   k=AS_BUF_SIZE-(my_as->u.as.ac_buffer.len);
again:
   if(0>(j=read(fd,my_as->u.as.ac_buffer.s+my_as->u.as.ac_buffer.len,k))){
      if(errno==EINTR)
	 goto again;
      LM_ERR("reading data for as %.*s (%s)\n",my_as->name.len,my_as->name.s,strerror(errno));
      return -1;
   }else if(j==0){
      pkg_free(my_as->u.as.ac_buffer.s);
      close(fd);
      LM_ERR("read 0 bytes from AS:%.*s\n",my_as->name.len,my_as->name.s);
      /** we return, so we will exit, so our parent (Event Dispatcher) will receive a sigchld and know
       * it should tear down the corresponding AS
       * what still is not clear is what will happen to events that were put in the pipe...
       */
      return -2;
   }
   (my_as->u.as.ac_buffer.len)+=j;
   LM_DBG("read %d bytes from AS action socket (total = %d)\n",j,my_as->u.as.ac_buffer.len);
   if(use_stats)
      receivedplus();
   if(my_as->u.as.ac_buffer.len>=10){
      process_action(&my_as->u.as);
      LM_DBG("(Action dispatched,buffer.len=%d)\n",my_as->u.as.ac_buffer.len);
   }
   return 0;
}
Esempio n. 4
0
void
Menu::event(const SDL_Event& ev)
{
  switch(ev.type) {
    case SDL_MOUSEBUTTONDOWN:
    if(ev.button.button == SDL_BUTTON_LEFT)
    {
      Vector mouse_pos = VideoSystem::current()->get_renderer().to_logical(ev.motion.x, ev.motion.y);
      int x = int(mouse_pos.x);
      int y = int(mouse_pos.y);

      if(x > pos.x - get_width()/2 &&
         x < pos.x + get_width()/2 &&
         y > pos.y - get_height()/2 &&
         y < pos.y + get_height()/2)
      {
        process_action(MENU_ACTION_HIT);
      }
    }
    break;

    case SDL_MOUSEMOTION:
    {
      Vector mouse_pos = VideoSystem::current()->get_renderer().to_logical(ev.motion.x, ev.motion.y);
      float x = mouse_pos.x;
      float y = mouse_pos.y;

      if(x > pos.x - get_width()/2 &&
         x < pos.x + get_width()/2 &&
         y > pos.y - get_height()/2 &&
         y < pos.y + get_height()/2)
      {
        int new_active_item
          = static_cast<int> ((y - (pos.y - get_height()/2)) / 24);

        /* only change the mouse focus to a selectable item */
        if ((items[new_active_item]->kind != MN_HL)
            && (items[new_active_item]->kind != MN_LABEL)
            && (items[new_active_item]->kind != MN_INACTIVE))
          active_item = new_active_item;

        if(MouseCursor::current())
          MouseCursor::current()->set_state(MC_LINK);
      }
      else
      {
        if(MouseCursor::current())
          MouseCursor::current()->set_state(MC_NORMAL);
      }
    }
    break;

    default:
      break;
  }
}
Esempio n. 5
0
//----- Begin of function Nation::think_diplomacy -----//
//
void Nation::think_diplomacy()
{
	//--- process incoming messages first, so we won't send out the same request to nation which has already proposed the same thing ---//

	int nationRecno = nation_recno;

	process_action(0, ACTION_AI_PROCESS_TALK_MSG);

	if( nation_array.is_deleted(nationRecno) )		// the nation may have been deleted, if the nation accepts a purchase kingdom offer
		return;

	//---- thinking about war first -----//

	if( think_declare_war() )
		return;

	//----- think buy food first -------//

	think_request_buy_food();   // don't return even if this request is sent

	//----- think request cease fire ----//

	if( think_request_cease_war() )
		return;

	//------ thinking about treaty ---------//

	if( think_trade_treaty() )
		return;

	if( think_propose_alliance_treaty() )		// try proposing alliance treaty first, then try proposing friendly treaty
		return;

	if( think_propose_friendly_treaty() )
		return;

	if( think_end_treaty() )
		return;

	//-------- think about other matters --------//

	if( think_demand_tribute_aid() )
		return;

	if( think_give_tech() )
		return;

	if( think_demand_tech() )
		return;

	//---- think about offering to purchase throne ----//

	if( think_request_surrender() )
		return;
}
Esempio n. 6
0
//------- Begin of function Nation::process_action_id --------//
//
// Process a specific action.
//
int Nation::process_action_id(int actionId)
{
	for( int i=action_count() ; i>0 ; i-- )
	{
		if( is_action_deleted(i) )
			continue;

		if( get_action(i)->action_id == actionId )
		{
			process_action(i);
			return 1;
		}
	}

	return 0;
}
Esempio n. 7
0
/** \brief Take a key event (key press or key release) and processes it.
 *
 * FIXME: Needs documentation.
 */
void process_record(keyrecord_t *record)
{
    if (IS_NOEVENT(record->event)) { return; }

    if(!process_record_quantum(record))
        return;

    action_t action = store_or_get_action(record->event.pressed, record->event.key);
    dprint("ACTION: "); debug_action(action);
#ifndef NO_ACTION_LAYER
    dprint(" layer_state: "); layer_debug();
    dprint(" default_layer_state: "); default_layer_debug();
#endif
    dprintln();

    process_action(record, action);
}
Esempio n. 8
0
void action_exec(keyevent_t event)
{
    if (!IS_NOEVENT(event)) {
        dprint("\n---- action_exec: start -----\n");
        dprint("EVENT: "); debug_event(event); dprintln();
    }

    keyrecord_t record = { .event = event };

#ifndef NO_ACTION_TAPPING
    action_tapping_process(record);
#else
    process_action(&record);
    if (!IS_NOEVENT(record.event)) {
        dprint("processed: "); debug_record(record); dprintln();
    }
#endif
}
Esempio n. 9
0
//--------- Begin of function Nation::add_action --------//
//
// <ActionNode*> actionNode - the action node to be added.
// [int] immediateProcess   - process this action immediately
//
int Nation::add_action(ActionNode* actionNode, int immediateProcess)
{
	//----------- reset some vars -----------//

	actionNode->add_date    = info.game_date;
	actionNode->action_id   = ++last_action_id;
	actionNode->retry_count = STD_ACTION_RETRY_COUNT;

	actionNode->processing_instance_count = 0;
	actionNode->processed_instance_count  = 0;

	//------- link into action_array --------//

	action_array.linkin( actionNode );

	if( immediateProcess )
		process_action( action_array.recno() );

	return action_array.recno();
}
Esempio n. 10
0
void
Menu::process_input()
{
  int menu_height = (int) get_height();
  if (menu_height > SCREEN_HEIGHT)
  { // Scrolling
    int scroll_offset = (menu_height - SCREEN_HEIGHT) / 2 + 32;
    pos.y = SCREEN_HEIGHT/2 - scroll_offset * ((float(active_item) / (items.size()-1)) - 0.5f) * 2.0f;
  }

  MenuAction menuaction = MENU_ACTION_NONE;
  Controller* controller = InputManager::current()->get_controller();
  /** check main input controller... */
  if(controller->pressed(Controller::UP)) {
    menuaction = MENU_ACTION_UP;
    menu_repeat_time = real_time + MENU_REPEAT_INITIAL;
  }
  if(controller->hold(Controller::UP) &&
     menu_repeat_time != 0 && real_time > menu_repeat_time) {
    menuaction = MENU_ACTION_UP;
    menu_repeat_time = real_time + MENU_REPEAT_RATE;
  }

  if(controller->pressed(Controller::DOWN)) {
    menuaction = MENU_ACTION_DOWN;
    menu_repeat_time = real_time + MENU_REPEAT_INITIAL;
  }
  if(controller->hold(Controller::DOWN) &&
     menu_repeat_time != 0 && real_time > menu_repeat_time) {
    menuaction = MENU_ACTION_DOWN;
    menu_repeat_time = real_time + MENU_REPEAT_RATE;
  }

  if(controller->pressed(Controller::LEFT)) {
    menuaction = MENU_ACTION_LEFT;
    menu_repeat_time = real_time + MENU_REPEAT_INITIAL;
  }
  if(controller->hold(Controller::LEFT) &&
     menu_repeat_time != 0 && real_time > menu_repeat_time) {
    menuaction = MENU_ACTION_LEFT;
    menu_repeat_time = real_time + MENU_REPEAT_RATE;
  }

  if(controller->pressed(Controller::RIGHT)) {
    menuaction = MENU_ACTION_RIGHT;
    menu_repeat_time = real_time + MENU_REPEAT_INITIAL;
  }
  if(controller->hold(Controller::RIGHT) &&
     menu_repeat_time != 0 && real_time > menu_repeat_time) {
    menuaction = MENU_ACTION_RIGHT;
    menu_repeat_time = real_time + MENU_REPEAT_RATE;
  }

  if(controller->pressed(Controller::ACTION)
     || controller->pressed(Controller::MENU_SELECT)) {
    menuaction = MENU_ACTION_HIT;
  }
  if(controller->pressed(Controller::ESCAPE) ||
     controller->pressed(Controller::START) ||
     controller->pressed(Controller::MENU_BACK)) {
    menuaction = MENU_ACTION_BACK;
  }

  if(items.size() == 0)
    return;

  // The menu_action() call can pop() the menu from the stack and thus
  // delete it, so it's important that no further member variables are
  // accessed after this call
  process_action(menuaction);
}
Esempio n. 11
0
//-------- Begin of function GameFileArray::menu --------//
//
// <int> actionMode = -2 - save screen to back buffer
//                    -1 - restore screen to back buffer
//                    1 - save game
//                    2 - load game
//                    3 - load game from main menu
//
// <int *> recno    = if overwritting save game or load game acion 
//                    is succcessful, return the recno of GameFile
//
// return : <int> 1 - game loaded/saved
//                0 - user cancel loading/saving 
//               -1 - loading/saving error
//
int GameFileArray::menu(int actionMode, int *recno)
{
	enum { PAGE_WIDTH = 800, PAGE_HEIGHT = 600 };

	int bx = (VGA_WIDTH - PAGE_WIDTH) / 2;
	int by = (VGA_HEIGHT - PAGE_HEIGHT) / 2;

	if( actionMode == -2 || actionMode == -1)
	{
		// copy or restore screen to back buffer
		int scrnX1, scrnY1, scrnX2, scrnY2;
		scrnX1 = bx;
		scrnY1 = by;
		scrnX2 = scrnX1 + PAGE_WIDTH - 1;
		scrnY2 = scrnY1 + PAGE_HEIGHT - 1;

		return 1;
	}

	action_mode = actionMode;
	pre_game = 0;
	if( actionMode == 3 )		// actionMode = 3 means load game from main menu, so action_mode is still two
	{
		action_mode = 2;
		pre_game = 1;
	}

	if( action_mode==2 && size()==0 )
	{
		box.msg( text_game_menu.str_none_save_game() ); // "You haven't saved any games yet." );
		return 0;
	}

	// load race icon
	char deinitGameSet=0;
	char deinitUnitRes=0;
	char deinitRaceRes=0;
	char deinitMonsterRes=0;

	if( !game_set.set_opened_flag )
	{
		game_set.open_set(1);
		deinitGameSet = 1;
	}
	if( !unit_res.init_flag )
	{
		unit_res.init();
		deinitUnitRes = 1;
	}
	if( !race_res.init_flag )
	{
		race_res.init();
		deinitRaceRes = 1;
	}

	if( !monster_res.init_flag )
	{
		monster_res.init();
		// ##### begin Gilbert 30/10 ######//
		// deinitRaceRes = 1;
		deinitMonsterRes = 1;
		// ##### end Gilbert 30/10 ######//
	}

	//-------------------------------------//

	mouse_cursor.set_icon(CURSOR_NORMAL);
	mouse_cursor.set_frame(0);

	power.win_opened = 1;

	int minRecno = 1;

	//------ set current record no. -------//

	// ####### begin Gilbert 3/5 ########//
	int i;
	if( size() == 0 )
	{
		browse_recno = 0;
	}
	else
	{
		browse_recno = 1;
		for( i=1 ; i<=size() ; i++ )
		{
			if( strcasecmp(last_file_name, game_file_array[i]->file_name)==0 )
			{
				browse_recno = i;
				break;
			}
		}
	}
	// ####### end Gilbert 3/5 ########//

	//---------------------------------//

	browse_top_recno = minRecno;
	// in save game mode, browse_recno = 0 means selecting empty slot
	// in load game mode, browse_recno = 0 means nonthing is selected
	// browse_top_recno = browse_recno ? browse_recno : minRecno;

	// -------- generate palette ------//

	short colorRemapTable[0x100];
	{
		String str(DIR_IMAGE);
		if( pre_game )
			str += "CHOOSE.COL";
		else
			str += "CHOOSE2.COL";

		File palFile;
		palFile.file_open(str);
		ColorTable colorTable;

		BYTE palBuf[0x100][3];
		palFile.file_seek(8);     				// bypass the header info
		palFile.file_read(palBuf, sizeof(palBuf));
		palFile.file_close();

		// ------- palette description -------------//

		PalDesc palBufDesc( palBuf, 3, 0x100, 8 );

		//-------- create color remap table ---------//

		colorTable.generate_table_fast( 0, palBufDesc, ColorTable::bright_func );
		memcpy( colorRemapTable, colorTable.get_table(0), sizeof(colorRemapTable) );
	}

	int retFlag = 0;

#define SLOT_Y_SPACING 80
#define SLOT_X1(n) (bx + 119)
#define SLOT_Y1(n) (by + SLOT_Y_SPACING * (n) + 110)
#define SLOT_X2(n) (bx + 119 + SLOT_WIDTH - 1)
#define SLOT_Y2(n) (by + SLOT_Y_SPACING * (n) + 110 + SLOT_HEIGHT - 1)

	char *arrowBitmap = image_button.read("TRI-R");
	int pageUpX1 = bx + (LSCROLL_X2 + LSCROLL_X1 - ((Bitmap *)arrowBitmap)->get_width()) / 2;
	int pageUpY1 = by + (LSCROLL_Y2 + LSCROLL_Y1 - ((Bitmap *)arrowBitmap)->get_height()) / 2;
	int pageUpX2 = pageUpX1 + ((Bitmap *)arrowBitmap)->get_width() - 1;
	int pageUpY2 = pageUpY1 + ((Bitmap *)arrowBitmap)->get_height() - 1;
	int pageDownX1 = bx + (RSCROLL_X2 + RSCROLL_X1 - ((Bitmap *)arrowBitmap)->get_width()) / 2;
	int pageDownY1 = by + (RSCROLL_Y2 + RSCROLL_Y1 - ((Bitmap *)arrowBitmap)->get_height()) / 2;
	int pageDownX2 = pageDownX1 + ((Bitmap *)arrowBitmap)->get_width() - 1;
	int pageDownY2 = pageDownY1 + ((Bitmap *)arrowBitmap)->get_height() - 1;

	int pageNoX1 = bx + 556;
	int pageNoY1 = by + 87;
	int pageNoX2 = bx + 675;
	int pageNoY2 = by + 107;

	// ------- define save buffer area ----------//

	Blob2DW browseArea[MAX_BROWSE_DISP_REC];		// save bitmap of save game slot areas
	Blob2DW pageUpArea, pageDownArea;
	Blob2DW pageNoArea;

	// ------- define button object ----------//

	Button startButton, cancelButton, delButton;
	Button saveNewButton;

	if( !pre_game )
	{
		startButton.create_text( bx+BUTTON2_X1, by+BUTTON2_Y1, bx+BUTTON2_X2, by+BUTTON2_Y2, 
			action_mode == 1 ? text_game_menu.str_save() : text_game_menu.str_load() );
		if( action_mode == 1 )
			saveNewButton.create_text( bx+BUTTON3_X1, by+BUTTON3_Y1, bx+BUTTON3_X2, by+BUTTON3_Y2, 
				text_game_menu.str_save_new() );
		delButton.create_text( bx+BUTTON7_X1, by+BUTTON7_Y1, bx+BUTTON7_X2, by+BUTTON7_Y2, text_game_menu.str_delete_save() );
		cancelButton.create_text( bx+BUTTON4_X1, by+BUTTON4_Y1, bx+BUTTON4_X2, by+BUTTON4_Y2, text_game_menu.str_cancel() );
	}

//	int i;
	int page, maxPage;
	maxPage = (size()-minRecno+1 + MAX_BROWSE_DISP_REC-1) / MAX_BROWSE_DISP_REC;	// divide but round up
	page = (browse_recno - minRecno) / MAX_BROWSE_DISP_REC;

	while(1)
	{
		//---------- yield --------//

		sys.yield();

		mouse.get_event();

		// --------- display ----------//

				// ------- display image --------//

				File imageFile;
				String str(DIR_IMAGE);
				if( pre_game )
				{
					str += "CHOOSE.ICN";
					imageFile.file_open(str);
					vga.active_buf->put_large_bitmap(bx, by, &imageFile, colorRemapTable);
				}
				else
				{
					str += "CHOOSE2.ICN";
					imageFile.file_open(str);
					vga.active_buf->put_large_bitmap_trans(bx, by, &imageFile, colorRemapTable);
				}

				// ------- display title -------//

				if( action_mode == 1 )
					font_bold_black.center_put( bx+SCROLL_SHEET_X1, by+SCROLL_SHEET_Y1, 
						bx+SCROLL_SHEET_X2, SLOT_Y1(0), text_game_menu.str_save_game() ); // "Save Game" );
				else if( action_mode == 2 )
					font_bold_black.center_put( bx+SCROLL_SHEET_X1, by+SCROLL_SHEET_Y1, 
						bx+SCROLL_SHEET_X2, SLOT_Y1(0), text_game_menu.str_load_game() ); // "Load Game" );

				// display save, save new/ load, delete cancel button

				if( pre_game )
				{
					if( action_mode == 1 )
					{
						font_thin_black.center_put( bx+BUTTON2_X1, by+BUTTON2_Y1, bx+BUTTON2_X2, by+BUTTON2_Y2, text_game_menu.str_save() ); // "Save" );
						font_thin_black.center_put( bx+BUTTON3_X1, by+BUTTON3_Y1, bx+BUTTON3_X2, by+BUTTON3_Y2, text_game_menu.str_save_new() ); // "Save New" );
					}
					else if( action_mode == 2 )
					{
						font_thin_black.center_put( bx+BUTTON2_X1, by+BUTTON2_Y1, bx+BUTTON2_X2, by+BUTTON2_Y2, text_game_menu.str_load() ); // "Load" );
					}
					font_thin_black.center_put( bx+BUTTON4_X1, by+BUTTON4_Y1, bx+BUTTON4_X2, by+BUTTON4_Y2, text_game_menu.str_cancel() ); // "Cancel" );
					font_thin_black.center_put( bx+BUTTON7_X1, by+BUTTON7_Y1, bx+BUTTON7_X2, by+BUTTON7_Y2, text_game_menu.str_delete_save() ); // "Delete" );
				}
				else
				{
					startButton.paint();
					if( action_mode == 1 )
						saveNewButton.paint();
					cancelButton.paint();
					delButton.paint();
				}

				// capture area

				for( i = 0; i < MAX_BROWSE_DISP_REC; ++i )
				{
					browseArea[i].clear();
					browseArea[i].resize(SLOT_X1(i), SLOT_Y1(i), SLOT_WIDTH, SLOT_HEIGHT );
					vga.active_buf->read_bitmapW( SLOT_X1(i), SLOT_Y1(i), SLOT_X2(i), SLOT_Y2(i), browseArea[i].bitmap_ptr() );
				}

				// capture page up area
				pageUpArea.clear();
				pageUpArea.resize( pageUpX1, pageUpY1, ((Bitmap *)arrowBitmap)->get_width(), ((Bitmap *)arrowBitmap)->get_height() );
				vga.active_buf->read_bitmapW( pageUpX1, pageUpY1, pageUpX2, pageUpY2, pageUpArea.bitmap_ptr() );
				pageDownArea.clear();
				pageDownArea.resize( pageDownX1, pageDownY1, ((Bitmap *)arrowBitmap)->get_width(), ((Bitmap *)arrowBitmap)->get_height() );
				vga.active_buf->read_bitmapW( pageDownX1, pageDownY1, pageDownX2, pageDownY2, pageDownArea.bitmap_ptr() );

				// capture page no area
				pageNoArea.clear();
				pageNoArea.resize( pageNoX1, pageNoY1, pageNoX2-pageNoX1+1, pageNoY2-pageNoY1+1 );
				vga.active_buf->read_bitmapW( pageNoX1, pageNoY1, pageNoX2, pageNoY2, pageNoArea.bitmap_ptr() );

			for( i = 0; i < MAX_BROWSE_DISP_REC; ++i )
			{
					int browseSlotX1 = SLOT_X1(i);
					int browseSlotY1 = SLOT_Y1(i);
					int browseSlotX2 = SLOT_X2(i);
					int browseSlotY2 = SLOT_Y2(i);

					// draw save bitmap area
					vga_buffer.put_bitmapW( browseSlotX1, browseSlotY1, browseArea[i].bitmap_ptr() );

					// draw slot content
					int rec = page * MAX_BROWSE_DISP_REC + i + minRecno;
					if( rec == 0 )
					{
						font_bold_black.center_put( browseSlotX1, browseSlotY1, browseSlotX2, browseSlotY2, text_game_menu.str_empty_game_slot() ); // "Empty Game Slot" );
					}
					else if( rec >= 1 && rec <= size() )
					{
						// remain game_file_array[rec]->disp_info() for file find
						operator[](rec)->disp_info( browseSlotX1, browseSlotY1 );		
					}

					// draw selected frame

					if( rec == browse_recno )
					{
						// draw black frame
						vga_buffer.rect( browseSlotX1, browseSlotY1, browseSlotX2, browseSlotY2, 2, V_BLACK );
					}
			}

//				String str;
//				str = "page ";
//				str += page+1;
//				str += "/";
//				str += maxPage;
				vga.active_buf->put_bitmapW( pageNoX1, pageNoY1, pageNoArea.bitmap_ptr() );		
				font_snds.center_put( pageNoX1, pageNoY1, pageNoX2, pageNoY2, text_game_menu.str_page_str(page+1, maxPage) );

				if( page > 0 )
					vga.active_buf->put_bitmap(pageUpX1, pageUpY1, arrowBitmap, 0, 2, true);
				else
					vga.active_buf->put_bitmapW( pageUpX1, pageUpY1, pageUpArea.bitmap_ptr() );

				if( page < maxPage-1 )
					vga.active_buf->put_bitmap(pageDownX1, pageDownY1, arrowBitmap, 0, 2);
				else
					vga.active_buf->put_bitmapW( pageDownX1, pageDownY1, pageDownArea.bitmap_ptr() );

		// ------ detect slots -------//

		int breakWhileFlag = 0;

		for( i = 0; i < MAX_BROWSE_DISP_REC; ++i )
		{
			int rec = page * MAX_BROWSE_DISP_REC + i + minRecno;
			int browseSlotX1 = SLOT_X1(i);
			int browseSlotY1 = SLOT_Y1(i);
			int browseSlotX2 = SLOT_X2(i);
			int browseSlotY2 = SLOT_Y2(i);

			if( rec < minRecno || rec > size() )
				continue;

			if( mouse.double_click(browseSlotX1, browseSlotY1, browseSlotX2, browseSlotY2) )
			{
				// double click on game slot
				if( browse_recno == rec )
				{
					browse_recno = rec;
					if( recno )
						*recno = browse_recno;
					breakWhileFlag = 1;	// signal to break while(1) loop
					retFlag = process_action(0);

//					if( retFlag < 0 )
//						box.msg("Error");
					break;		// BUGHERE : how to break while loop
				}
			}
			else if( mouse.single_click(browseSlotX1, browseSlotY1, browseSlotX2, browseSlotY2) )
			{
				// click on game slot
				if( browse_recno != rec )
				{
					// refresh old slot
					int oldSlot = browse_recno - page * MAX_BROWSE_DISP_REC - minRecno;

					// refresh new slot
					browse_recno = rec;
					break;
				}
			}
		}

		// ------- detect scroll button -------//

		if( page > 0 && mouse.any_click( bx+LSCROLL_X1, by+LSCROLL_Y1, bx+LSCROLL_X2, by+LSCROLL_Y2 ) )
		{
			page--;
		}

		if( page < maxPage-1 && mouse.any_click( bx+RSCROLL_X1, by+RSCROLL_Y1, bx+RSCROLL_X2, by+RSCROLL_Y2 ) )
		{
			page++;
		}

		// -------- detect button at bottom -------//

		if( (pre_game ? mouse.single_click( bx+BUTTON4_X1, by+BUTTON4_Y1, bx+BUTTON4_X2, by+BUTTON4_Y2) : cancelButton.detect())
			|| mouse.key_code == KEY_ESC || mouse.any_click(RIGHT_BUTTON) > 0)		// also when ESC key is pressed or right button
		{
			// cancel button or escape key
			retFlag = 0;
			breakWhileFlag = 1;
			break;		// break while(1)
		}
		else if( (action_mode == 1 || (action_mode == 2 && browse_recno))
			&& (pre_game ? mouse.single_click(bx+BUTTON2_X1, by+BUTTON2_Y1, bx+BUTTON2_X2, by+BUTTON2_Y2) : startButton.detect()) )
		{
			// save / load button
			if( recno )
				*recno = browse_recno;
			retFlag = process_action(0);
			if( retFlag != 0 )
			{
//				if( retFlag < 0 )
//					box.msg("Error");
				breakWhileFlag = 1;
				break;
			}
		}
		else if( action_mode == 1
			&& (pre_game ? mouse.single_click( bx+BUTTON3_X1, by+BUTTON3_Y1, bx+BUTTON3_X2, by+BUTTON3_Y2) : saveNewButton.detect()) )
		{
			// save new button
			retFlag = process_action(1);
			if( retFlag != 0 )
			{
//				if( retFlag < 0 )
//					box.msg("Error");
				breakWhileFlag = 1;
				break;
			}
		}
		else if( browse_recno 
			&& (pre_game ? mouse.single_click( bx+BUTTON7_X1, by+BUTTON7_Y1, bx+BUTTON7_X2, by+BUTTON7_Y2) : delButton.detect()) )
		{
			// delete save game button
			if( browse_recno != 0 )			// cannot del save game slot
			{
				del_game();
				if( browse_recno > size() )
				{
					browse_recno = size();
				}
//				if( browse_top_recno > size()-MAX_BROWSE_DISP_REC+1)
//					browse_top_recno = size()-MAX_BROWSE_DISP_REC+1;
//				if( browse_top_recno < minRecno )
//					browse_top_recno = minRecno;
				// scrollBar.set_view_recno(browse_top_recno);

				// recalculate page
				maxPage = (size()-minRecno+1 + MAX_BROWSE_DISP_REC-1) / MAX_BROWSE_DISP_REC;	// divide but round up
				if( page >= maxPage )
				{
					page = maxPage - 1;
					if( page < 0 )
						page = 0;
				}

				if( action_mode == 2 && size()==0 )
				{
					box.msg( text_game_menu.str_none_save_game()); // "You haven't saved any games yet." );
					return 0;
				}
			}
			else
			{
				box.msg( text_game_menu.str_cannot_delete_slot()); // "Cannot delete this slot");
			}
		}
                vga.flip();

		if( breakWhileFlag )
			break;
	}

	power.win_opened = 0;
	if( retFlag <= 0 )
	{
		// if load game is successful, no need to deinit resource
		if( deinitGameSet )
			game_set.close_set();
		if( deinitUnitRes )
			unit_res.deinit();
		if( deinitRaceRes )
			race_res.deinit();
		if( deinitMonsterRes )
			monster_res.deinit();
	}

	mouse.reset_click();
	return retFlag;

#undef SLOT_X1
#undef SLOT_Y1
#undef SLOT_X2
#undef SLOT_y2
}
Esempio n. 12
0
void
Menu::process_input()
{
  int menu_height = static_cast<int>(get_height());
  if (menu_height > SCREEN_HEIGHT)
  { // Scrolling
    int scroll_offset = (menu_height - SCREEN_HEIGHT) / 2 + 32;
    pos.y = static_cast<float>(SCREEN_HEIGHT) / 2.0f - static_cast<float>(scroll_offset) * ((static_cast<float>(active_item) / static_cast<float>(items.size() - 1)) - 0.5f) * 2.0f;
  }

  MenuAction menuaction = MENU_ACTION_NONE;
  auto controller = InputManager::current()->get_controller();
  /** check main input controller... */
  if(controller->pressed(Controller::UP)) {
    menuaction = MENU_ACTION_UP;
    menu_repeat_time = g_real_time + MENU_REPEAT_INITIAL;
  }
  if(controller->hold(Controller::UP) &&
     menu_repeat_time != 0 && g_real_time > menu_repeat_time) {
    menuaction = MENU_ACTION_UP;
    menu_repeat_time = g_real_time + MENU_REPEAT_RATE;
  }

  if(controller->pressed(Controller::DOWN)) {
    menuaction = MENU_ACTION_DOWN;
    menu_repeat_time = g_real_time + MENU_REPEAT_INITIAL;
  }
  if(controller->hold(Controller::DOWN) &&
     menu_repeat_time != 0 && g_real_time > menu_repeat_time) {
    menuaction = MENU_ACTION_DOWN;
    menu_repeat_time = g_real_time + MENU_REPEAT_RATE;
  }

  if(controller->pressed(Controller::LEFT)) {
    menuaction = MENU_ACTION_LEFT;
    menu_repeat_time = g_real_time + MENU_REPEAT_INITIAL;
  }
  if(controller->hold(Controller::LEFT) &&
     menu_repeat_time != 0 && g_real_time > menu_repeat_time) {
    menuaction = MENU_ACTION_LEFT;
    menu_repeat_time = g_real_time + MENU_REPEAT_RATE;
  }

  if(controller->pressed(Controller::RIGHT)) {
    menuaction = MENU_ACTION_RIGHT;
    menu_repeat_time = g_real_time + MENU_REPEAT_INITIAL;
  }
  if(controller->hold(Controller::RIGHT) &&
     menu_repeat_time != 0 && g_real_time > menu_repeat_time) {
    menuaction = MENU_ACTION_RIGHT;
    menu_repeat_time = g_real_time + MENU_REPEAT_RATE;
  }

  if(controller->pressed(Controller::ACTION)
     || controller->pressed(Controller::MENU_SELECT)
     || (!is_sensitive() && controller->pressed(Controller::MENU_SELECT_SPACE))) {
    menuaction = MENU_ACTION_HIT;
  }
  if(controller->pressed(Controller::ESCAPE) ||
     controller->pressed(Controller::CHEAT_MENU) ||
     controller->pressed(Controller::DEBUG_MENU) ||
     controller->pressed(Controller::MENU_BACK)) {
    menuaction = MENU_ACTION_BACK;
  }

  if(controller->pressed(Controller::REMOVE)) {
    menuaction = MENU_ACTION_REMOVE;
    menu_repeat_time = g_real_time + MENU_REPEAT_INITIAL;
  }
  if(controller->hold(Controller::REMOVE) &&
     menu_repeat_time != 0 && g_real_time > menu_repeat_time) {
    menuaction = MENU_ACTION_REMOVE;
    menu_repeat_time = g_real_time + MENU_REPEAT_RATE;
  }

  if(items.size() == 0)
    return;

  // The menu_action() call can pop() the menu from the stack and thus
  // delete it, so it's important that no further member variables are
  // accessed after this call
  process_action(menuaction);
}
Esempio n. 13
0
//------ Begin of function Nation::ai_settle_to_region ------//
//
// <int> destXLoc, destYLoc - the location of the destination to settle.
// <int> seaActionId			 - SEA_ACTION_???
//
int Nation::ai_settle_to_region(int destXLoc, int destYLoc, int seaActionId)
{
	#define SETTLE_REGION_UNIT_COUNT 	9		// no. of units to move to settle on a new region each time

	//---- think about which town to recruit the people -----//

	int  destRegionId = world.get_region_id(destXLoc, destYLoc);
	int  curRating, bestRating=0, seaRegionId;
	Town *townPtr, *bestTown=NULL;

	for( int i=0 ; i<ai_town_count ; i++ )
	{
		townPtr = town_array[ ai_town_array[i] ];

		if( townPtr->has_linked_own_camp==0 )		// if there is no command base linked to this town, we cannot recruit any peasants from it
			continue;

		if( townPtr->jobless_population < SETTLE_REGION_UNIT_COUNT )		// don't get peasant from this town if the jobless population is less than 20
			continue;

		//--- only send units from this region if we have a harbor in that region ---//

		// ###### patch begin Gilbert 16/3 #######//
		// region_stat_id of a region may be zero
		if( 
//#ifdef AMPLUS
			region_array[townPtr->region_id]->region_stat_id == 0 || 
//#endif
			region_array.get_region_stat(townPtr->region_id)->harbor_nation_count_array[nation_recno-1] == 0 )
		// ###### patch end Gilbert 16/3 #######//
			continue;

		curRating  = world.distance_rating(destXLoc, destYLoc, townPtr->center_x, townPtr->center_y);

		curRating += townPtr->jobless_population;

		curRating += townPtr->average_loyalty();		// select a town with high loyalty

		if( curRating <= bestRating )
			continue;

		//------- see if we have ships ready currently -----//

		seaRegionId = region_array.get_sea_path_region_id(townPtr->region_id, destRegionId);

		if( !ai_find_transport_ship(seaRegionId, townPtr->center_x, townPtr->center_y, 0) )		// 0-don't have to find the best, return immediately whenever a suitable one is found 
			continue;

		bestRating = curRating;
		bestTown   = townPtr;
	}

	if( !bestTown )
		return 0;

	//------- try to recruit 9 units from one of our towns --------//

	short recruitedUnitArray[SETTLE_REGION_UNIT_COUNT];
	int recruitedCount=0;
	int raceId = bestTown->majority_race();
	int unitRecno;
	int loopCount=0;

	while( recruitedCount < SETTLE_REGION_UNIT_COUNT )
	{
		err_when( ++loopCount > 100 );

		if( bestTown->recruitable_race_pop( raceId, 1 ) )
		{
			unitRecno = bestTown->recruit(-1, raceId, COMMAND_AI);

			if( !unitRecno )		// no space for new unit 
				break;

			err_when( unit_array.is_deleted(unitRecno) );
			err_when( !unit_array[unitRecno]->is_visible() );

			recruitedUnitArray[recruitedCount++] = unitRecno;
		}
		else
		{
			raceId = bestTown->pick_random_race(0, 1);		// 0-recruitable only, 1-will also pick spies

			if( !raceId )
				break;
		}
	}

	//--- if due to some reasons that the no. of units recruited is less than half of what we need, do not continue to sea travel.

	if( recruitedCount < SETTLE_REGION_UNIT_COUNT/2 )
		return 0;

	int actionRecno = add_action( destXLoc, destYLoc, 0, 0, ACTION_AI_SEA_TRAVEL, seaActionId,
											recruitedCount, 0, 0, recruitedUnitArray );

	if( actionRecno )						// must process it immediately otherwise the recruited units will do something else
		return process_action(actionRecno);
	else
		return 0;
}
Esempio n. 14
0
//------ Begin of function Nation::ai_patrol_to_region ------//
//
// Look for a military camp for moving all of its soldiers to
// a new region and set up a new military camp to host the soldiers.
//
// <int> destXLoc, destYLoc - the location of the destination to set up
//										a military camp.
// <int> seaActionId			 - SEA_ACTION_???
//
int Nation::ai_patrol_to_region(int destXLoc, int destYLoc, int seaActionId)
{
	#define SETTLE_REGION_UNIT_COUNT 	9		// no. of units to move to settle on a new region each time

	//---- think about which town to recruit the people -----//

	int  		destRegionId = world.get_region_id(destXLoc, destYLoc);
	int  		curRating, bestRating=0, seaRegionId;
	int		kingRecno = nation_array[nation_recno]->king_unit_recno;
	FirmCamp *firmCamp, *bestCamp=NULL;

	for( int i=0 ; i<ai_camp_count ; i++ )
	{
		firmCamp = (FirmCamp*) firm_array[ ai_camp_array[i] ];

		if( !(firmCamp->overseer_recno && firmCamp->worker_count==MAX_WORKER) )		// only when the camp is filled with workers
			continue;

		if( firmCamp->ai_capture_town_recno )     // the base is trying to capture an independent town
			continue;

		if( firmCamp->is_attack_camp )
			continue;

		if( firmCamp->overseer_recno == kingRecno )		// if the king oversees this firm
			continue;

		//--- only send units from this region if we have a harbor in that region ---//

		// ####### patch begin Gilbert 16/3 ########//
		if( 
//#ifdef AMPLUS
			region_array[firmCamp->region_id]->region_stat_id == 0 ||
//#endif
			region_array.get_region_stat(firmCamp->region_id)->harbor_nation_count_array[nation_recno-1] == 0 )
			continue;
		// ####### patch end Gilbert 16/3 ########//

		curRating  = world.distance_rating(destXLoc, destYLoc, firmCamp->center_x, firmCamp->center_y);

		if( curRating <= bestRating )
			continue;

		//------- see if we have ships ready currently -----//

		seaRegionId = region_array.get_sea_path_region_id(firmCamp->region_id, destRegionId);

		if( !ai_find_transport_ship(seaRegionId, firmCamp->center_x, firmCamp->center_y, 0) )		// 0-don't have to find the best, return immediately whenever a suitable one is found
			continue;

		bestRating = curRating;
		bestCamp   = firmCamp;
	}

	if( !bestCamp )
		return 0;

	//----- patrol the camp troop ajnd assign it to a ship -----//

	bestCamp->patrol();

	if( bestCamp->patrol_unit_count > 0 )     // there could be chances that there are no some for mobilizing the units
	{
		int actionRecno = add_action( destXLoc, destYLoc, 0, 0, ACTION_AI_SEA_TRAVEL, seaActionId,
												bestCamp->patrol_unit_count, 0, 0, bestCamp->patrol_unit_array );

		if( actionRecno )						// must process it immediately otherwise the recruited units will do something else
			return process_action(actionRecno);
	}

	return 0;
}
Esempio n. 15
0
/* return true when key event is processed or consumed. */
bool process_tapping(keyrecord_t *keyp)
{
    keyevent_t event = keyp->event;

    // if tapping
    if (IS_TAPPING_PRESSED()) {
        if (WITHIN_TAPPING_TERM(event)) {
            if (tapping_key.tap.count == 0) {
                if (IS_TAPPING_KEY(event.key) && !event.pressed) {
                    // first tap!
                    debug("Tapping: First tap(0->1).\n");
                    tapping_key.tap.count = 1;
                    tapping_key.tap.interrupted  = (waiting_buffer_has_anykey_pressed() ? true : false);
                    debug_tapping_key();
                    process_action(&tapping_key);

                    // enqueue
                    keyp->tap = tapping_key.tap;
                    return false;
                }
#if TAPPING_TERM >= 500
                /* This can prevent from typing some tap keys in a row at a time. */
                else if (!event.pressed && waiting_buffer_typed(event)) {
                    // other key typed. not tap.
                    debug("Tapping: End. No tap. Interfered by typing key\n");
                    process_action(&tapping_key);
                    tapping_key = (keyrecord_t){};
                    debug_tapping_key();

                    // enqueue
                    return false;
                }
#endif
                else {
                    // other key events shall be enq'd till tapping state settles.
                    return false;
                }
            }
            // tap_count > 0
            else {
                if (IS_TAPPING_KEY(event.key) && !event.pressed) {
                    debug("Tapping: Tap release("); debug_dec(tapping_key.tap.count); debug(")\n");
                    keyp->tap = tapping_key.tap;
                    process_action(keyp);
                    tapping_key = *keyp;
                    debug_tapping_key();
                    return true;
                }
                else if (is_tap_key(keyp->event.key) && event.pressed) {
                    if (tapping_key.tap.count > 1) {
                        debug("Tapping: Start new tap with releasing last tap(>1).\n");
                        // unregister key
                        process_action(&(keyrecord_t){
                                .tap = tapping_key.tap,
                                .event.key = tapping_key.event.key,
                                .event.time = event.time,
                                .event.pressed = false
                        });
                    } else {
                        debug("Tapping: Start while last tap(1).\n");
                    }
                    tapping_key = *keyp;
                    waiting_buffer_scan_tap();
                    debug_tapping_key();
                    return true;
                }
                else {
                    if (!IS_NOEVENT(keyp->event)) {
Esempio n. 16
0
void
Menu::event(const SDL_Event& ev)
{
  items[active_item]->event(ev);
  switch(ev.type) {
    case SDL_KEYDOWN:
    case SDL_TEXTINPUT:
      if(((ev.type == SDL_KEYDOWN && ev.key.keysym.sym == SDLK_BACKSPACE) ||
         ev.type == SDL_TEXTINPUT) && items[active_item]->changes_width())
      {
        // Changed item value? Let's recalculate width:
        calculate_width();
      }
    break;

    case SDL_MOUSEBUTTONDOWN:
    if(ev.button.button == SDL_BUTTON_LEFT)
    {
      Vector mouse_pos = VideoSystem::current()->get_viewport().to_logical(ev.motion.x, ev.motion.y);

      if (mouse_pos.x > pos.x - get_width() / 2.0f &&
          mouse_pos.x < pos.x + get_width() / 2.0f &&
          mouse_pos.y > pos.y - get_height() / 2.0f &&
          mouse_pos.y < pos.y + get_height() / 2.0f)
      {
        process_action(MENU_ACTION_HIT);
      }
    }
    break;

    case SDL_MOUSEMOTION:
    {
      Vector mouse_pos = VideoSystem::current()->get_viewport().to_logical(ev.motion.x, ev.motion.y);
      float x = mouse_pos.x;
      float y = mouse_pos.y;

      if(x > pos.x - get_width()/2 &&
         x < pos.x + get_width()/2 &&
         y > pos.y - get_height()/2 &&
         y < pos.y + get_height()/2)
      {
        int new_active_item
          = static_cast<int> ((y - (pos.y - get_height()/2)) / 24);

        /* only change the mouse focus to a selectable item */
        if (!items[new_active_item]->skippable())
          active_item = new_active_item;

        if(MouseCursor::current())
          MouseCursor::current()->set_state(MC_LINK);
      }
      else
      {
        if(MouseCursor::current())
          MouseCursor::current()->set_state(MC_NORMAL);
      }
    }
    break;

    default:
      break;
  }
}
Esempio n. 17
0
int main(int argc, char *argv[])
{
	char *conf_filename;
	int result;
	int sock;
	int wait_count;
	pthread_t schedule_tid;
	struct sigaction act;
	ScheduleEntry scheduleEntries[SCHEDULE_ENTRIES_MAX_COUNT];
	ScheduleArray scheduleArray;
	char pidFilename[MAX_PATH_SIZE];
	bool stop;

	if (argc < 2)
	{
		usage(argv[0]);
		return 1;
	}

	g_current_time = time(NULL);
	g_up_time = g_current_time;

	log_init2();
	trunk_shared_init();

	conf_filename = argv[1];
	if ((result=get_base_path_from_conf_file(conf_filename,
		g_fdfs_base_path, sizeof(g_fdfs_base_path))) != 0)
	{
		log_destroy();
		return result;
	}

	snprintf(pidFilename, sizeof(pidFilename),
		"%s/data/fdfs_storaged.pid", g_fdfs_base_path);
	if ((result=process_action(pidFilename, argv[2], &stop)) != 0)
	{
		if (result == EINVAL)
		{
			usage(argv[0]);
		}
		log_destroy();
		return result;
	}
	if (stop)
	{
		log_destroy();
		return 0;
	}

#if defined(DEBUG_FLAG) && defined(OS_LINUX)
	if (getExeAbsoluteFilename(argv[0], g_exe_name, \
		sizeof(g_exe_name)) == NULL)
	{
		logCrit("exit abnormally!\n");
		log_destroy();
		return errno != 0 ? errno : ENOENT;
	}
#endif

	memset(g_bind_addr, 0, sizeof(g_bind_addr));
	if ((result=storage_func_init(conf_filename, \
			g_bind_addr, sizeof(g_bind_addr))) != 0)
	{
		logCrit("exit abnormally!\n");
		log_destroy();
		return result;
	}

	sock = socketServer(g_bind_addr, g_server_port, &result);
	if (sock < 0)
	{
		logCrit("exit abnormally!\n");
		log_destroy();
		return result;
	}

	if ((result=tcpsetserveropt(sock, g_fdfs_network_timeout)) != 0)
	{
		logCrit("exit abnormally!\n");
		log_destroy();
		return result;
	}

	daemon_init(false);
	umask(0);
	if ((result=write_to_pid_file(pidFilename)) != 0)
	{
		log_destroy();
		return result;
	}

	if ((result=storage_sync_init()) != 0)
	{
		logCrit("file: "__FILE__", line: %d, " \
			"storage_sync_init fail, program exit!", __LINE__);
		g_continue_flag = false;
		return result;
	}

	if ((result=tracker_report_init()) != 0)
	{
		logCrit("file: "__FILE__", line: %d, " \
			"tracker_report_init fail, program exit!", __LINE__);
		g_continue_flag = false;
		return result;
	}

	if ((result=storage_service_init()) != 0)
	{
		logCrit("file: "__FILE__", line: %d, " \
			"storage_service_init fail, program exit!", __LINE__);
		g_continue_flag = false;
		return result;
	}

	if ((result=set_rand_seed()) != 0)
	{
		logCrit("file: "__FILE__", line: %d, " \
			"set_rand_seed fail, program exit!", __LINE__);
		g_continue_flag = false;
		return result;
	}

	memset(&act, 0, sizeof(act));
	sigemptyset(&act.sa_mask);

	act.sa_handler = sigUsrHandler;
	if(sigaction(SIGUSR1, &act, NULL) < 0 || \
		sigaction(SIGUSR2, &act, NULL) < 0)
	{
		logCrit("file: "__FILE__", line: %d, " \
			"call sigaction fail, errno: %d, error info: %s", \
			__LINE__, errno, STRERROR(errno));
		logCrit("exit abnormally!\n");
		return errno;
	}

	act.sa_handler = sigHupHandler;
	if(sigaction(SIGHUP, &act, NULL) < 0)
	{
		logCrit("file: "__FILE__", line: %d, " \
			"call sigaction fail, errno: %d, error info: %s", \
			__LINE__, errno, STRERROR(errno));
		logCrit("exit abnormally!\n");
		return errno;
	}
	
	act.sa_handler = SIG_IGN;
	if(sigaction(SIGPIPE, &act, NULL) < 0)
	{
		logCrit("file: "__FILE__", line: %d, " \
			"call sigaction fail, errno: %d, error info: %s", \
			__LINE__, errno, STRERROR(errno));
		logCrit("exit abnormally!\n");
		return errno;
	}

	act.sa_handler = sigQuitHandler;
	if(sigaction(SIGINT, &act, NULL) < 0 || \
		sigaction(SIGTERM, &act, NULL) < 0 || \
		sigaction(SIGQUIT, &act, NULL) < 0)
	{
		logCrit("file: "__FILE__", line: %d, " \
			"call sigaction fail, errno: %d, error info: %s", \
			__LINE__, errno, STRERROR(errno));
		logCrit("exit abnormally!\n");
		return errno;
	}

#if defined(DEBUG_FLAG)

/*
#if defined(OS_LINUX)
	memset(&act, 0, sizeof(act));
        act.sa_sigaction = sigSegvHandler;
        act.sa_flags = SA_SIGINFO;
        if (sigaction(SIGSEGV, &act, NULL) < 0 || \
        	sigaction(SIGABRT, &act, NULL) < 0)
	{
		logCrit("file: "__FILE__", line: %d, " \
			"call sigaction fail, errno: %d, error info: %s", \
			__LINE__, errno, STRERROR(errno));
		logCrit("exit abnormally!\n");
		return errno;
	}
#endif
*/

	memset(&act, 0, sizeof(act));
	sigemptyset(&act.sa_mask);
	act.sa_handler = sigDumpHandler;
	if(sigaction(SIGUSR1, &act, NULL) < 0 || \
		sigaction(SIGUSR2, &act, NULL) < 0)
	{
		logCrit("file: "__FILE__", line: %d, " \
			"call sigaction fail, errno: %d, error info: %s", \
			__LINE__, errno, STRERROR(errno));
		logCrit("exit abnormally!\n");
		return errno;
	}
#endif

#ifdef WITH_HTTPD
	if (!g_http_params.disabled)
	{
		if ((result=storage_httpd_start(g_bind_addr)) != 0)
		{
			logCrit("file: "__FILE__", line: %d, " \
				"storage_httpd_start fail, " \
				"program exit!", __LINE__);
			return result;
		}
	}
#endif

	if ((result=tracker_report_thread_start()) != 0)
	{
		logCrit("file: "__FILE__", line: %d, " \
			"tracker_report_thread_start fail, " \
			"program exit!", __LINE__);
		g_continue_flag = false;
		storage_func_destroy();
		log_destroy();
		return result;
	}

	scheduleArray.entries = scheduleEntries;

	memset(scheduleEntries, 0, sizeof(scheduleEntries));
	scheduleEntries[0].id = 1;
	scheduleEntries[0].time_base.hour = TIME_NONE;
	scheduleEntries[0].time_base.minute = TIME_NONE;
	scheduleEntries[0].interval = g_sync_log_buff_interval;
	scheduleEntries[0].task_func = log_sync_func;
	scheduleEntries[0].func_args = &g_log_context;

	scheduleEntries[1].id = 2;
	scheduleEntries[1].time_base.hour = TIME_NONE;
	scheduleEntries[1].time_base.minute = TIME_NONE;
	scheduleEntries[1].interval = g_sync_binlog_buff_interval;
	scheduleEntries[1].task_func = fdfs_binlog_sync_func;
	scheduleEntries[1].func_args = NULL;

	scheduleEntries[2].id = 3;
	scheduleEntries[2].time_base.hour = TIME_NONE;
	scheduleEntries[2].time_base.minute = TIME_NONE;
	scheduleEntries[2].interval = g_sync_stat_file_interval;
	scheduleEntries[2].task_func = fdfs_stat_file_sync_func;
	scheduleEntries[2].func_args = NULL;

	scheduleArray.count = 3;
	if (g_if_use_trunk_file)
	{
		scheduleEntries[scheduleArray.count].id = 4;
		scheduleEntries[scheduleArray.count].time_base.hour = TIME_NONE;
		scheduleEntries[scheduleArray.count].time_base.minute=TIME_NONE;
		scheduleEntries[scheduleArray.count].interval = 1;
		scheduleEntries[scheduleArray.count].task_func = \
					trunk_binlog_sync_func;
		scheduleEntries[scheduleArray.count].func_args = NULL;
		scheduleArray.count++;
	}

	if (g_use_access_log)
	{
		scheduleEntries[scheduleArray.count].id = 5;
		scheduleEntries[scheduleArray.count].time_base.hour = TIME_NONE;
		scheduleEntries[scheduleArray.count].time_base.minute=TIME_NONE;
		scheduleEntries[scheduleArray.count].interval = \
					g_sync_log_buff_interval;
		scheduleEntries[scheduleArray.count].task_func = log_sync_func;
		scheduleEntries[scheduleArray.count].func_args = \
					&g_access_log_context;
		scheduleArray.count++;

		if (g_rotate_access_log)
		{
			scheduleEntries[scheduleArray.count].id = 6;
			scheduleEntries[scheduleArray.count].time_base = \
					g_access_log_rotate_time;
			scheduleEntries[scheduleArray.count].interval = \
					24 * 3600;
			scheduleEntries[scheduleArray.count].task_func = \
					log_notify_rotate;
			scheduleEntries[scheduleArray.count].func_args = \
					&g_access_log_context;
			scheduleArray.count++;
		}
	}

	if (g_rotate_error_log)
	{
		scheduleEntries[scheduleArray.count].id = 7;
		scheduleEntries[scheduleArray.count].time_base = \
				g_error_log_rotate_time;
		scheduleEntries[scheduleArray.count].interval = \
				24 * 3600;
		scheduleEntries[scheduleArray.count].task_func = \
				log_notify_rotate;
		scheduleEntries[scheduleArray.count].func_args = \
				&g_log_context;
		scheduleArray.count++;
	}

	if ((result=sched_start(&scheduleArray, &schedule_tid, \
		g_thread_stack_size, (bool * volatile)&g_continue_flag)) != 0)
	{
		logCrit("exit abnormally!\n");
		log_destroy();
		return result;
	}

	if ((result=set_run_by(g_run_by_group, g_run_by_user)) != 0)
	{
		logCrit("exit abnormally!\n");
		log_destroy();
		return result;
	}

	if ((result=storage_dio_init()) != 0)
	{
		logCrit("exit abnormally!\n");
		log_destroy();
		return result;
	}
	log_set_cache(true);

	bTerminateFlag = false;
	bAcceptEndFlag = false;
	
	storage_accept_loop(sock);
	bAcceptEndFlag = true;

	fdfs_binlog_sync_func(NULL);  //binlog fsync

	if (g_schedule_flag)
	{
		pthread_kill(schedule_tid, SIGINT);
	}

	storage_terminate_threads();
	storage_dio_terminate();

	kill_tracker_report_threads();
	kill_storage_sync_threads();

	wait_count = 0;
	while (g_storage_thread_count != 0 || \
		g_dio_thread_count != 0 || \
		g_tracker_reporter_count > 0 || \
		g_schedule_flag)
	{
/*
#if defined(DEBUG_FLAG) && defined(OS_LINUX)
		if (bSegmentFault)
		{
			sleep(5);
			break;
		}
#endif
*/

		usleep(10000);
		if (++wait_count > 6000)
		{
			logWarning("waiting timeout, exit!");
			break;
		}
	}

	tracker_report_destroy();
	storage_service_destroy();
	storage_sync_destroy();
	storage_func_destroy();

	if (g_if_use_trunk_file)
	{
		trunk_sync_destroy();
		storage_trunk_destroy();
	}

	logInfo("exit normally.\n");
	log_destroy();
	
	delete_pid_file(pidFilename);
	return 0;
}
Esempio n. 18
0
//-------- Begin of function GameFileArray::menu --------//
//
// <int> actionMode = -2 - save screen to back buffer
//                    -1 - restore screen to back buffer
//                    1 - save game
//                    2 - load game
//
// <int *> recno    = if overwritting save game or load game acion 
//                    is succcessful, return the recno of GameFile
//
// return : <int> 1 - game loaded/saved
//                0 - user cancel loading/saving 
//               -1 - loading/saving error
//
int GameFileArray::menu(int actionMode, int *recno)
{
	if( actionMode == -2 || actionMode == -1)
	{
		// copy or restore screen to back buffer
		int scrnX1, scrnY1, scrnX2, scrnY2;
		if( game.game_mode==GAME_PREGAME )	  // called from the main menu, not in the game
		{
			scrnX1 = FILE_MAIN_MENU_X1;
			scrnY1 = FILE_MAIN_MENU_Y1;
		}
		else
		{
			scrnX1 = FILE_IN_GAME_MENU_X1;
			scrnY1 = FILE_IN_GAME_MENU_Y1;
		}
		scrnX2 = scrnX1 + FILE_MENU_WIDTH-1;
		scrnY2 = scrnY1 + FILE_MENU_HEIGHT-1;

		mouse.hide_area( scrnX1, scrnY1, scrnX2, scrnY2);

		if( actionMode == -2 )
			// save to back buffer
			IMGcopy(vga_back.buf_ptr(), vga_back.buf_pitch(),
				vga_front.buf_ptr(), vga_front.buf_pitch(),
				scrnX1, scrnY1, scrnX2, scrnY2);
		else
			// restore from back buffer
			IMGcopy(vga_front.buf_ptr(), vga_front.buf_pitch(),
				vga_back.buf_ptr(), vga_back.buf_pitch(),
				scrnX1, scrnY1, scrnX2, scrnY2);

		mouse.show_area();

		return 1;
	}

	// #### begin Gilbert 25/9 ########//
	//#ifdef DEMO          // No game saving in demo version
	//	box.msg( "Sorry, you cannot load/save game in the demo version." );
	//	return -1;
	//#endif
	// #### end Gilbert 25/9 ########//

	action_mode = actionMode;

	if( action_mode==2 && size()==0 )
	{
		box.msg( _("You haven't saved any games yet.") );
		return 0;
	}

	// load race icon
	char deinitGameSet=0;
	char deinitUnitRes=0;
	char deinitRaceRes=0;

	if( !game_set.set_opened_flag )
	{
		game_set.open_set(1);
		deinitGameSet = 1;
	}
	if( !unit_res.init_flag )
	{
		unit_res.init();
		deinitUnitRes = 1;
	}
	if( !race_res.init_flag )
	{
		race_res.init();
		deinitRaceRes = 1;
	}

	//-------------------------------------//

	if( game.game_mode==GAME_PREGAME )	  // called from the main menu, not in the game
	{
		menu_x1 = FILE_MAIN_MENU_X1;
		menu_y1 = FILE_MAIN_MENU_Y1;
	}
	else
	{
		menu_x1 = FILE_IN_GAME_MENU_X1;
		menu_y1 = FILE_IN_GAME_MENU_Y1;
	}

	int x=menu_x1, y=menu_y1+17;

	// vga_back.adjust_brightness( x, y, x+menu_x1-1, y+menu_y1-1, -6 );
	vga_util.blt_buf( x, y, x+menu_x1-1, y+menu_y1-1, 0 );

	mouse_cursor.set_icon(CURSOR_NORMAL);

	power.win_opened = 1;

	int minRecno = action_mode == 1 ? 0 : 1;

	//------ set current record no. -------//

	for( int i=1 ; i<=size() ; i++ )
	{
		if( strcmp(last_file_name, game_file_array[i]->file_name)==0 )
		{
			browse_recno = i;
			break;
		}
	}

	//---------------------------------//

	browse_top_recno = minRecno;
	// in save game mode, browse_recno = 0 means selecting empty slot
	// in load game mode, browse_recno = 0 means nonthing is selected
	// browse_top_recno = browse_recno ? browse_recno : minRecno;

	//--------------------------------------//
	Button3D scrollUp, scrollDown, saveButton, saveNewButton, delButton, cancelButton;
	int retFlag = 0;
	int refreshFlag = LSOPTION_ALL;
	//int scrollButtonY1 = menu_y1+SCROLL_Y1, scrollButtonY2 = menu_y1+SCROLL_Y2;
	//int dragingScrollBar = 0;
	//int dragScrollYDiff;	// when draging begins, mouse.cur_y - scrollButtonY1

	SlideVBar scrollBar;
	scrollBar.init_scroll(menu_x1+SCROLL_X1, menu_y1+SCROLL_Y1, menu_x1+SCROLL_X2, menu_y1+SCROLL_Y2,
		MAX_BROWSE_DISP_REC, disp_scroll_bar_func);
	scrollBar.set(minRecno, size(), browse_top_recno);

	// try to centre the selected record on the browser
	//browse_top_recno = browse_recno - MAX_BROWSE_DISP_REC /2;
	//if( browse_top_recno > size()-MAX_BROWSE_DISP_REC+1)
	//	browse_top_recno = size()-MAX_BROWSE_DISP_REC+1;
	//if( browse_top_recno < minRecno )
	//	browse_top_recno = minRecno;
	browse_top_recno = scrollBar.set_view_recno(browse_recno - MAX_BROWSE_DISP_REC /2);

	Blob browseArea[MAX_BROWSE_DISP_REC];
	Blob scrollArea;

	while(1)
	{
		//---------- yield --------//

		sys.yield();

		mouse.get_event();

		// When called ingame sys.signal_exit_flag is set to 2 by Sys::load_game
		if( sys.signal_exit_flag == 1 )
		{
			retFlag = 0;
			break;
		}

		// --------- display ----------//

		if( refreshFlag )
		{
			if( refreshFlag & LSOPTION_PAGE )
			{
				mouse.hide_area(menu_x1, menu_y1, menu_x1+FILE_MENU_WIDTH, menu_y1+FILE_MENU_HEIGHT);

				image_interface.put_front( menu_x1, menu_y1, actionMode==1 ? (char*)"SAVEGAME" : (char*)"LOADGAME" );

				scrollUp.paint(menu_x1+SCROLL_X1+1,menu_y1+SCROLL_Y1-17, "SV-UP-U", "SV-UP-D");
				scrollDown.paint(menu_x1+SCROLL_X1+1,menu_y1+SCROLL_Y2+1, "SV-DW-U", "SV-DW-D");
				if( action_mode == 1)
				{
					saveButton.paint(menu_x1+34, menu_y1+354, "SAVE", "CANCEL1D");
					saveNewButton.paint(menu_x1+147, menu_y1+354, "SAVE-NEW", "CANCEL1D");
					delButton.paint(menu_x1+260, menu_y1+354, "DELETE", "CANCEL1D");
				}
				else if( action_mode == 2)
				{
					saveButton.paint(menu_x1+34, menu_y1+354, "LOAD", "CANCEL1D");
				}
				cancelButton.paint(menu_x1+473, menu_y1+354, "CANCEL1", "CANCEL1D");

				// capture browseArea, scrollArea
				for( int j = 0; j < MAX_BROWSE_DISP_REC; ++j)
				{
					browseArea[j].resize(2*sizeof(short)+BROWSE_REC_WIDTH*BROWSE_REC_HEIGHT);
					vga_front.read_bitmap( 
						menu_x1+BROWSE_X1, menu_y1+BROWSE_Y1+j*BROWSE_REC_HEIGHT,
						menu_x1+BROWSE_X2, menu_y1+BROWSE_Y1+j*BROWSE_REC_HEIGHT+BROWSE_REC_HEIGHT-1,
						browseArea[j].ptr);
				}

				scrollArea.resize(2*sizeof(short)+SCROLL_WIDTH*SCROLL_HEIGHT);
				vga_front.read_bitmap( menu_x1+SCROLL_X1, menu_y1+SCROLL_Y1, 
					menu_x1+SCROLL_X2, menu_y1+SCROLL_Y2, scrollArea.ptr);

				mouse.show_area();
			}

			if( scrollBar.max_recno != size() )
			{
				scrollBar.set_max_recno(size());
				if( scrollBar.view_recno > scrollBar.max_view_recno() )
				{
					scrollBar.view_recno = scrollBar.max_view_recno();
				}
				refreshFlag |= LSOPTION_SCROLL;
			}

			if( refreshFlag & LSOPTION_SCROLL )
			{
				vga_front.put_bitmap( menu_x1+SCROLL_X1, menu_y1+SCROLL_Y1,
					scrollArea.ptr);
				scrollBar.paint();
			}

			if( refreshFlag & LSOPTION_ALL_SLOTS )
			{
				for(int slot = 0; slot < MAX_BROWSE_DISP_REC; ++slot)
				{
					int rec = slot + scrollBar.view_recno;
					if( refreshFlag & LSOPTION_SLOT(slot) )
					{
						int browseSlotX1 = menu_x1+BROWSE_X1;
						int browseSlotY1 = menu_y1+BROWSE_Y1+slot*BROWSE_REC_HEIGHT;
						int browseSlotX2 = menu_x1+BROWSE_X2;
						int browseSlotY2 = menu_y1+BROWSE_Y1+(slot+1)*BROWSE_REC_HEIGHT-1;

						mouse.hide_area(browseSlotX1, browseSlotY1,
							browseSlotX2, browseSlotY2);
						vga_front.put_bitmap( browseSlotX1, browseSlotY1,
							browseArea[rec%MAX_BROWSE_DISP_REC].ptr);

						if( rec == 0 )
						{
							err_when( action_mode!=1 );
							font_bible.center_put( browseSlotX1, browseSlotY1,
								browseSlotX2, browseSlotY2, _("Empty Game Slot") );
						}
						else if( rec <= size() )
						{
							game_file_array[rec]->disp_info(browseSlotX1, browseSlotY1);
						}
						if( rec == browse_recno )
						{
							vga_front.adjust_brightness( browseSlotX1, browseSlotY1,
								browseSlotX2, browseSlotY2, -2);
							vga_front.put_bitmap_trans_decompress(browseSlotX1, browseSlotY1,
								image_button.read("LS-DWN"));
						}
						mouse.show_area();
					}
				}
				// disp_browse();
			}

			refreshFlag = 0;
		}

		sys.blt_virtual_buf();

		if( scrollBar.detect() == 1 )
		{
			browse_top_recno = scrollBar.view_recno;
			refreshFlag |= LSOPTION_SCROLL | LSOPTION_ALL_SLOTS;
		}
		else if( scrollUp.detect() )
		{
			// click on scroll up
			int oldValue = scrollBar.view_recno;
			if( oldValue != scrollBar.set_view_recno(oldValue-1) )
				refreshFlag |= LSOPTION_SCROLL | LSOPTION_ALL_SLOTS;
			browse_top_recno = scrollBar.view_recno;
		}
		else if( scrollDown.detect() )
		{
			// click on scroll down
			// click on scroll up
			int oldValue = scrollBar.view_recno;
			if( oldValue != scrollBar.set_view_recno(oldValue+1) )
				refreshFlag |= LSOPTION_SCROLL | LSOPTION_ALL_SLOTS;
			browse_top_recno = scrollBar.view_recno;
		}
		else if( mouse.double_click( menu_x1+BROWSE_X1, menu_y1+BROWSE_Y1, 
			menu_x1+BROWSE_X1+BROWSE_REC_WIDTH-1, 
			menu_y1+BROWSE_Y1+ BROWSE_REC_HEIGHT*MAX_BROWSE_DISP_REC -1) )
		{
			// double click on game slot
			int oldValue = browse_recno;
			int newValue = scrollBar.view_recno + (mouse.click_y(0) - BROWSE_Y1 - menu_y1) / BROWSE_REC_HEIGHT;
			if( newValue <= size())
			{
				// ######## begin Gilbert 31/10 ########//
				if( newValue == oldValue )
				{
					browse_recno = newValue;
					refreshFlag |= LSOPTION_SLOT(newValue-scrollBar.view_recno);
					if( oldValue-scrollBar.view_recno >= 0 && oldValue-scrollBar.view_recno < MAX_BROWSE_DISP_REC )
						refreshFlag |= LSOPTION_SLOT(oldValue-scrollBar.view_recno);
					if( recno )
						*recno = browse_recno;
					retFlag = process_action(0);
//					if( retFlag < 0 )
//						box.msg("Error");
					break;
				}
				// ######## end Gilbert 31/10 ########//
			}
		}
		else if( mouse.single_click( menu_x1+BROWSE_X1, menu_y1+BROWSE_Y1, 
			menu_x1+BROWSE_X1+BROWSE_REC_WIDTH-1, 
			menu_y1+BROWSE_Y1+ BROWSE_REC_HEIGHT*MAX_BROWSE_DISP_REC -1) )
		{
			// click on game slot
			int oldValue = browse_recno;
			int newValue = scrollBar.view_recno + (mouse.click_y(0) - BROWSE_Y1 - menu_y1) / BROWSE_REC_HEIGHT;
			if( newValue <= size())
			{
				// ##### begin Gilbert 31/10 #######//
				//if( oldValue == browse_recno )
				//{
				//	browse_recno = newValue;
				//	refreshFlag |= LSOPTION_SLOT(oldValue-scrollBar.view_recno)
				//		| LSOPTION_SLOT(newValue-scrollBar.view_recno);
				//}
				if( newValue != oldValue )
				{
					browse_recno = newValue;
					refreshFlag |= LSOPTION_SLOT(newValue-scrollBar.view_recno);
					if( oldValue-scrollBar.view_recno >= 0 && oldValue-scrollBar.view_recno < MAX_BROWSE_DISP_REC )
						refreshFlag |= LSOPTION_SLOT(oldValue-scrollBar.view_recno);
				}
				// ##### end Gilbert 31/10 #######//
			}
		}
		else if( cancelButton.detect(KEY_ESC) || mouse.any_click(RIGHT_BUTTON) > 0)		// also when ESC key is pressed or right button
		{
			// cancel button or escape key
			refreshFlag = LSOPTION_ALL;
			retFlag = 0;
			break;		// break while(1)
		}
		else if( (action_mode == 1 || (action_mode == 2 && browse_recno))
			&& saveButton.detect() )
		{
			// save / load button
			refreshFlag = LSOPTION_ALL;
			if( recno )
				*recno = browse_recno;
			retFlag = process_action(0);
			// ##### begin Gilbert 15/10 #####//
			if( retFlag != 0 )
			{
//				if( retFlag < 0 )
//					box.msg("Error");
				break;
			}
			// ##### end Gilbert 15/10 #####//
		}
		else if( action_mode == 1 && saveNewButton.detect() )
		{
			// save new button
			refreshFlag = LSOPTION_ALL;
			retFlag = process_action(1);
//			if( retFlag < 0 )
//				box.msg("Error");
			break;
		}
		else if( action_mode == 1 && browse_recno && delButton.detect() )
		{
			// delete save game button
			if( browse_recno != 0 )			// cannot del save game slot
			{
				del_game();
				if( browse_recno > size() )
				{
					browse_recno = size();
				}
				if( browse_top_recno > size()-MAX_BROWSE_DISP_REC+1)
					browse_top_recno = size()-MAX_BROWSE_DISP_REC+1;
				if( browse_top_recno < minRecno )
					browse_top_recno = minRecno;
				scrollBar.set_view_recno(browse_top_recno);
				refreshFlag |= LSOPTION_ALL_SLOTS | LSOPTION_SCROLL;
			}
			else
			{
				box.msg(_("Cannot delete this slot"));
			}
			refreshFlag = LSOPTION_ALL;
		}
	}

	power.win_opened = 0;
	if( retFlag <= 0 )
	{
		// if load game is successful, no need to deinit resource
		if( deinitGameSet )
			game_set.close_set();
		if( deinitUnitRes )
			unit_res.deinit();
		if( deinitRaceRes )
			race_res.deinit();
	}

	mouse.reset_click();
	return retFlag;
}
Esempio n. 19
0
//--------- Begin of function Nation::process_ai --------//
void Nation::process_ai()
{
	//-*********** simulate aat ************-//
#ifdef DEBUG
	if(debug_sim_game_type)
		return;
#endif
	//-*********** simulate aat ************-//

	if( config.disable_ai_flag || game.game_mode == GAME_TEST )
		return;

	//---- if the king has just been killed ----//

	int nationRecno = nation_recno;

	if( !king_unit_recno )
	{
		if( think_succeed_king() )
			return;

		if( think_surrender() )
			return;

		defeated();
		return;
	}

	//-------- process main AI actions ---------//

   process_ai_main();

	if( nation_array.is_deleted(nationRecno) )		// the nation can have surrendered 
		return;

	//------ process queued diplomatic messges first --------//

	// ##### begin Gilbert 4/10 ######//
   if( (info.game_date-nation_recno)%3 == 0 )
	{
		LOG_MSG("begin process_action(0,ACTION_AI_PROCESS_TALK_MSG)");
		process_action(0, ACTION_AI_PROCESS_TALK_MSG);
		LOG_MSG("end process_action(0,ACTION_AI_PROCESS_TALK_MSG)");
		LOG_MSG(misc.get_random_seed());

		if( nation_array.is_deleted(nationRecno) )		// the nation can have surrendered 
			return;
	}

	// ##### end Gilbert 4/10 ######//

   //--------- process queued actions ----------//

	// ##### begin Gilbert 4/10 ######//
   if( (info.game_date-nation_recno)%3 == 0 )
	{
		LOG_MSG("begin process_action()");
		process_action();
		LOG_MSG("end process_action()");
		LOG_MSG(misc.get_random_seed());

		if( nation_array.is_deleted(nationRecno) )		// the nation can have surrendered 
			return;
	}
	// ##### end Gilbert 4/10 ######//

	//--- process action that are on-going and need continous checking ---//

	process_on_going_action();

	//--------- cheat ---------//
	//
	// In tutorial mode only so that your opponent won't surrender
	// and you won't go to the end game screen.
	//
	//-------------------------//

	if( game.game_mode == GAME_TUTORIAL )
	{
		if( cash < 100 )
			add_cheat( (float)200+misc.random(500) );

		if( food < 100 )
			food += 1000;
	}

	//----- think about updating relationship with other nations -----//

	if( info.game_date%360 == nation_recno%360 )
		ai_improve_relation();

	//------ think about surrendering -------//

	if( info.game_date%60 == nation_recno%60 )
	{
		if( think_surrender() )		
			return;

		if( think_unite_against_big_enemy() )
			return;
	}
}
Esempio n. 20
0
void process_action(keyrecord_t *record)
{
    bool do_release_oneshot = false;
    keyevent_t event = record->event;
#ifndef NO_ACTION_TAPPING
    uint8_t tap_count = record->tap.count;
#endif

    if (IS_NOEVENT(event)) { return; }

#if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
    if (has_oneshot_layer_timed_out()) {
        dprintf("Oneshot layer: timeout\n");
        clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED);
    }
#endif

    action_t action = layer_switch_get_action(event.key);
    dprint("ACTION: "); debug_action(action);
#ifndef NO_ACTION_LAYER
    dprint(" layer_state: "); layer_debug();
    dprint(" default_layer_state: "); default_layer_debug();
#endif
    dprintln();


#ifndef NO_ACTION_ONESHOT
    if (is_oneshot_layer_active() && event.pressed) {
        clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED);
        do_release_oneshot = !is_oneshot_layer_active();
    }
#endif

    switch (action.kind.id) {
        /* Key and Mods */
        case ACT_LMODS:
        case ACT_RMODS:
            {
                uint8_t mods = (action.kind.id == ACT_LMODS) ?  action.key.mods :
                                                                action.key.mods<<4;
                if (event.pressed) {
                    if (mods) {
                        add_weak_mods(mods);
                        send_keyboard_report();
                    }
                    register_code(action.key.code);
                } else {
                    unregister_code(action.key.code);
                    if (mods) {
                        del_weak_mods(mods);
                        send_keyboard_report();
                    }
                }
            }
            break;
#ifndef NO_ACTION_TAPPING
        case ACT_LMODS_TAP:
        case ACT_RMODS_TAP:
            {
                uint8_t mods = (action.kind.id == ACT_LMODS_TAP) ?  action.key.mods :
                                                                    action.key.mods<<4;
                switch (action.layer_tap.code) {
    #ifndef NO_ACTION_ONESHOT
                    case MODS_ONESHOT:
                        // Oneshot modifier
                        if (event.pressed) {
                            if (tap_count == 0) {
                                dprint("MODS_TAP: Oneshot: 0\n");
                                register_mods(mods);
                            } else if (tap_count == 1) {
                                dprint("MODS_TAP: Oneshot: start\n");
                                set_oneshot_mods(mods);
                    #if defined(ONESHOT_TAP_TOGGLE) && ONESHOT_TAP_TOGGLE > 1
                            } else if (tap_count == ONESHOT_TAP_TOGGLE) {
                                dprint("MODS_TAP: Toggling oneshot");
                                clear_oneshot_mods();
                                set_oneshot_locked_mods(mods);
                                register_mods(mods);
                    #endif
                            } else {
                                register_mods(mods);
                            }
                        } else {
                            if (tap_count == 0) {
                                clear_oneshot_mods();
                                unregister_mods(mods);
                            } else if (tap_count == 1) {
                                // Retain Oneshot mods
                    #if defined(ONESHOT_TAP_TOGGLE) && ONESHOT_TAP_TOGGLE > 1
                                if (mods & get_mods()) {
                                    clear_oneshot_locked_mods();
                                    clear_oneshot_mods();
                                    unregister_mods(mods);
                                }
                            } else if (tap_count == ONESHOT_TAP_TOGGLE) {
                                // Toggle Oneshot Layer
                    #endif
                            } else {
                                clear_oneshot_mods();
                                unregister_mods(mods);
                            }
                        }
                        break;
    #endif
                    case MODS_TAP_TOGGLE:
                        if (event.pressed) {
                            if (tap_count <= TAPPING_TOGGLE) {
                                register_mods(mods);
                            }
                        } else {
                            if (tap_count < TAPPING_TOGGLE) {
                                unregister_mods(mods);
                            }
                        }
                        break;
                    default:
                        if (event.pressed) {
                            if (tap_count > 0) {
                                if (record->tap.interrupted) {
                                    dprint("MODS_TAP: Tap: Cancel: add_mods\n");
                                    // ad hoc: set 0 to cancel tap
                                    record->tap.count = 0;
                                    register_mods(mods);
                                } else {
                                    dprint("MODS_TAP: Tap: register_code\n");
                                    register_code(action.key.code);
                                }
                            } else {
                                dprint("MODS_TAP: No tap: add_mods\n");
                                register_mods(mods);
                            }
                        } else {
                            if (tap_count > 0) {
                                dprint("MODS_TAP: Tap: unregister_code\n");
                                unregister_code(action.key.code);
                            } else {
                                dprint("MODS_TAP: No tap: add_mods\n");
                                unregister_mods(mods);
                            }
                        }
                        break;
                }
            }
            break;
#endif
#ifdef EXTRAKEY_ENABLE
        /* other HID usage */
        case ACT_USAGE:
            switch (action.usage.page) {
                case PAGE_SYSTEM:
                    if (event.pressed) {
                        host_system_send(action.usage.code);
                    } else {
                        host_system_send(0);
                    }
                    break;
                case PAGE_CONSUMER:
                    if (event.pressed) {
                        host_consumer_send(action.usage.code);
                    } else {
                        host_consumer_send(0);
                    }
                    break;
            }
            break;
#endif
#ifdef MOUSEKEY_ENABLE
        /* Mouse key */
        case ACT_MOUSEKEY:
            if (event.pressed) {
                mousekey_on(action.key.code);
                mousekey_send();
            } else {
                mousekey_off(action.key.code);
                mousekey_send();
            }
            break;
#endif
#ifndef NO_ACTION_LAYER
        case ACT_LAYER:
            if (action.layer_bitop.on == 0) {
                /* Default Layer Bitwise Operation */
                if (!event.pressed) {
                    uint8_t shift = action.layer_bitop.part*4;
                    uint32_t bits = ((uint32_t)action.layer_bitop.bits)<<shift;
                    uint32_t mask = (action.layer_bitop.xbit) ? ~(((uint32_t)0xf)<<shift) : 0;
                    switch (action.layer_bitop.op) {
                        case OP_BIT_AND: default_layer_and(bits | mask); break;
                        case OP_BIT_OR:  default_layer_or(bits | mask);  break;
                        case OP_BIT_XOR: default_layer_xor(bits | mask); break;
                        case OP_BIT_SET: default_layer_and(mask); default_layer_or(bits); break;
                    }
                }
            } else {
                /* Layer Bitwise Operation */
                if (event.pressed ? (action.layer_bitop.on & ON_PRESS) :
                                    (action.layer_bitop.on & ON_RELEASE)) {
                    uint8_t shift = action.layer_bitop.part*4;
                    uint32_t bits = ((uint32_t)action.layer_bitop.bits)<<shift;
                    uint32_t mask = (action.layer_bitop.xbit) ? ~(((uint32_t)0xf)<<shift) : 0;
                    switch (action.layer_bitop.op) {
                        case OP_BIT_AND: layer_and(bits | mask); break;
                        case OP_BIT_OR:  layer_or(bits | mask);  break;
                        case OP_BIT_XOR: layer_xor(bits | mask); break;
                        case OP_BIT_SET: layer_and(mask); layer_or(bits); break;
                    }
                }
            }
            break;
    #ifndef NO_ACTION_TAPPING
        case ACT_LAYER_TAP:
        case ACT_LAYER_TAP_EXT:
            switch (action.layer_tap.code) {
                case 0xe0 ... 0xef:
                    /* layer On/Off with modifiers(left only) */
                    if (event.pressed) {
                        layer_on(action.layer_tap.val);
                        register_mods(action.layer_tap.code & 0x0f);
                    } else {
                        layer_off(action.layer_tap.val);
                        unregister_mods(action.layer_tap.code & 0x0f);
                    }
                    break;
                case OP_TAP_TOGGLE:
                    /* tap toggle */
                    if (event.pressed) {
                        if (tap_count < TAPPING_TOGGLE) {
                            layer_invert(action.layer_tap.val);
                        }
                    } else {
                        if (tap_count <= TAPPING_TOGGLE) {
                            layer_invert(action.layer_tap.val);
                        }
                    }
                    break;
                case OP_ON_OFF:
                    event.pressed ? layer_on(action.layer_tap.val) :
                                    layer_off(action.layer_tap.val);
                    break;
                case OP_OFF_ON:
                    event.pressed ? layer_off(action.layer_tap.val) :
                                    layer_on(action.layer_tap.val);
                    break;
                case OP_SET_CLEAR:
                    event.pressed ? layer_move(action.layer_tap.val) :
                                    layer_clear();
                    break;
            #ifndef NO_ACTION_ONESHOT
                case OP_ONESHOT:
                    // Oneshot modifier
                #if defined(ONESHOT_TAP_TOGGLE) && ONESHOT_TAP_TOGGLE > 1
                    do_release_oneshot = false;
                    if (event.pressed) {
                        del_mods(get_oneshot_locked_mods());
                        if (get_oneshot_layer_state() == ONESHOT_TOGGLED) {
                            reset_oneshot_layer();
                            layer_off(action.layer_tap.val);
                            break;
                        } else if (tap_count < ONESHOT_TAP_TOGGLE) {
                            layer_on(action.layer_tap.val);
                            set_oneshot_layer(action.layer_tap.val, ONESHOT_START);
                        }
                    } else {
                        add_mods(get_oneshot_locked_mods());
                        if (tap_count >= ONESHOT_TAP_TOGGLE) {
                            reset_oneshot_layer();
                            clear_oneshot_locked_mods();
                            set_oneshot_layer(action.layer_tap.val, ONESHOT_TOGGLED);
                        } else {
                            clear_oneshot_layer_state(ONESHOT_PRESSED);
                        }
                    }
                #else
                    if (event.pressed) {
                        layer_on(action.layer_tap.val);
                        set_oneshot_layer(action.layer_tap.val, ONESHOT_START);
                    } else {
                        clear_oneshot_layer_state(ONESHOT_PRESSED);
                        if (tap_count > 1) {
                            clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED);
                        }
                    }
                #endif
                    break;
            #endif
                default:
                    /* tap key */
                    if (event.pressed) {
                        if (tap_count > 0) {
                            dprint("KEYMAP_TAP_KEY: Tap: register_code\n");
                            register_code(action.layer_tap.code);
                        } else {
                            dprint("KEYMAP_TAP_KEY: No tap: On on press\n");
                            layer_on(action.layer_tap.val);
                        }
                    } else {
                        if (tap_count > 0) {
                            dprint("KEYMAP_TAP_KEY: Tap: unregister_code\n");
                            unregister_code(action.layer_tap.code);
                        } else {
                            dprint("KEYMAP_TAP_KEY: No tap: Off on release\n");
                            layer_off(action.layer_tap.val);
                        }
                    }
                    break;
            }
            break;
    #endif
#endif
        /* Extentions */
#ifndef NO_ACTION_MACRO
        case ACT_MACRO:
            action_macro_play(action_get_macro(record, action.func.id, action.func.opt));
            break;
#endif
#ifdef BACKLIGHT_ENABLE
        case ACT_BACKLIGHT:
            if (!event.pressed) {
                switch (action.backlight.opt) {
                    case BACKLIGHT_INCREASE:
                        backlight_increase();
                        break;
                    case BACKLIGHT_DECREASE:
                        backlight_decrease();
                        break;
                    case BACKLIGHT_TOGGLE:
                        backlight_toggle();
                        break;
                    case BACKLIGHT_STEP:
                        backlight_step();
                        break;
                    case BACKLIGHT_LEVEL:
                        backlight_level(action.backlight.level);
                        break;
                }
            }
            break;
#endif
        case ACT_COMMAND:
            break;
#ifndef NO_ACTION_FUNCTION
        case ACT_FUNCTION:
            action_function(record, action.func.id, action.func.opt);
            break;
#endif
        default:
            break;
    }

#ifndef NO_ACTION_ONESHOT
    /* Because we switch layers after a oneshot event, we need to release the
     * key before we leave the layer or no key up event will be generated.
     */
    if (do_release_oneshot && !(get_oneshot_layer_state() & ONESHOT_PRESSED )   ) {
        record->event.pressed = false;
        layer_on(get_oneshot_layer());
        process_action(record);
        layer_off(get_oneshot_layer());
    }
#endif
}
Esempio n. 21
0
void process_action_nocache(keyrecord_t *record)
{
    disable_action_cache = true;
    process_action(record);
    disable_action_cache = false;
}
Esempio n. 22
0
void process_action_nocache(keyrecord_t *record)
{
    process_action(record);
}
Esempio n. 23
0
/* return true when key event is processed or consumed. */
bool process_tapping(keyrecord_t *keyp)
{
    keyevent_t event = keyp->event;

    // if tapping
    if (IS_TAPPING_PRESSED()) {
        if (WITHIN_TAPPING_TERM(event)) {
            if (tapping_key.tap.count == 0) {
                if (IS_TAPPING_KEY(event.key) && !event.pressed) {
                    // first tap!
                    debug("Tapping: First tap(0->1).\n");
                    tapping_key.tap.count = 1;
                    debug_tapping_key();
                    process_action(&tapping_key);

                    // copy tapping state
                    keyp->tap = tapping_key.tap;
                    // enqueue
                    return false;
                }
#if TAPPING_TERM >= 500
                /* Process a key typed within TAPPING_TERM
                 * This can register the key before settlement of tapping,
                 * useful for long TAPPING_TERM but may prevent fast typing.
                 */
                else if (IS_RELEASED(event) && waiting_buffer_typed(event)) {
                    debug("Tapping: End. No tap. Interfered by typing key\n");
                    process_action(&tapping_key);
                    tapping_key = (keyrecord_t){};
                    debug_tapping_key();
                    // enqueue
                    return false;
                }
#endif
                /* Process release event of a key pressed before tapping starts
                 * Without this unexpected repeating will occur with having fast repeating setting
                 * https://github.com/tmk/tmk_keyboard/issues/60
                 */
                else if (IS_RELEASED(event) && !waiting_buffer_typed(event)) {
                    // Modifier should be retained till end of this tapping.
                    action_t action = layer_switch_get_action(event.key);
                    switch (action.kind.id) {
                        case ACT_LMODS:
                        case ACT_RMODS:
                            if (action.key.mods && !action.key.code) return false;
                            if (IS_MOD(action.key.code)) return false;
                            break;
                        case ACT_LMODS_TAP:
                        case ACT_RMODS_TAP:
                            if (action.key.mods && keyp->tap.count == 0) return false;
                            if (IS_MOD(action.key.code)) return false;
                            break;
                    }
                    // Release of key should be process immediately.
                    debug("Tapping: release event of a key pressed before tapping\n");
                    process_action(keyp);
                    return true;
                }
                else {
                    // set interrupted flag when other key preesed during tapping
                    if (event.pressed) {
                        tapping_key.tap.interrupted = true;
                    }
                    // enqueue 
                    return false;
                }
            }
            // tap_count > 0
            else {
                if (IS_TAPPING_KEY(event.key) && !event.pressed) {
                    debug("Tapping: Tap release("); debug_dec(tapping_key.tap.count); debug(")\n");
                    keyp->tap = tapping_key.tap;
                    process_action(keyp);
                    tapping_key = *keyp;
                    debug_tapping_key();
                    return true;
                }
                else if (is_tap_key(event.key) && event.pressed) {
                    if (tapping_key.tap.count > 1) {
                        debug("Tapping: Start new tap with releasing last tap(>1).\n");
                        // unregister key
                        process_action(&(keyrecord_t){
                                .tap = tapping_key.tap,
                                .event.key = tapping_key.event.key,
                                .event.time = event.time,
                                .event.pressed = false
                        });
                    } else {
                        debug("Tapping: Start while last tap(1).\n");
                    }
                    tapping_key = *keyp;
                    waiting_buffer_scan_tap();
                    debug_tapping_key();
                    return true;
                }
                else {
                    if (!IS_NOEVENT(event)) {
Esempio n. 24
0
int main(int argc, char *argv[])
{
	char *conf_filename;
	int result;
	int wait_count;
	int sock;
	pthread_t schedule_tid;
	struct sigaction act;
	ScheduleEntry scheduleEntries[SCHEDULE_ENTRIES_COUNT];
	ScheduleArray scheduleArray;
	char pidFilename[MAX_PATH_SIZE];
	bool stop;

	if (argc < 2)
	{
		usage(argv[0]);
		return 1;
	}

	g_current_time = time(NULL);
	g_up_time = g_current_time;
	srand(g_up_time);

	log_init2();
	//通过指定的conf文件,获取base path
	conf_filename = argv[1];
	if ((result=get_base_path_from_conf_file(conf_filename,
		g_fdfs_base_path, sizeof(g_fdfs_base_path))) != 0)
	{
		log_destroy();
		return result;
	}
	//启动程序,或者通过文件中的pid来kill掉之前的进程
	snprintf(pidFilename, sizeof(pidFilename),
		"%s/data/fdfs_trackerd.pid", g_fdfs_base_path);
	if ((result=process_action(pidFilename, argv[2], &stop)) != 0)
	{
		if (result == EINVAL)
		{
			usage(argv[0]);
		}
		log_destroy();
		return result;
	}
	if (stop)
	{
		log_destroy();
		return 0;
	}

#if defined(DEBUG_FLAG) && defined(OS_LINUX)
	if (getExeAbsoluteFilename(argv[0], g_exe_name, \
		sizeof(g_exe_name)) == NULL)
	{
		logCrit("exit abnormally!\n");
		log_destroy();
		return errno != 0 ? errno : ENOENT;
	}
#endif

	memset(bind_addr, 0, sizeof(bind_addr));
	if ((result=tracker_load_from_conf_file(conf_filename, \
			bind_addr, sizeof(bind_addr))) != 0)
	{
		logCrit("exit abnormally!\n");
		log_destroy();
		return result;
	}
	//g_tracker_last_status只记录了uptime和last check time作用未知
	if ((result=tracker_load_status_from_file(&g_tracker_last_status)) != 0)
	{
		logCrit("exit abnormally!\n");
		log_destroy();
		return result;
	}

	base64_init_ex(&g_base64_context, 0, '-', '_', '.');
	if ((result=set_rand_seed()) != 0)
	{
		logCrit("file: "__FILE__", line: %d, " \
			"set_rand_seed fail, program exit!", __LINE__);
		return result;
	}
	//内存分配及历史group和storage载入
	if ((result=tracker_mem_init()) != 0)
	{
		logCrit("exit abnormally!\n");
		log_destroy();
		return result;
	}

	sock = socketServer(bind_addr, g_server_port, &result);
	if (sock < 0)
	{
		logCrit("exit abnormally!\n");
		log_destroy();
		return result;
	}

	if ((result=tcpsetserveropt(sock, g_fdfs_network_timeout)) != 0)
	{
		logCrit("exit abnormally!\n");
		log_destroy();
		return result;
	}
	//后台运行
	daemon_init(false);
	umask(0);
	//将pid记录到文件中
	if ((result=write_to_pid_file(pidFilename)) != 0)
	{
		log_destroy();
		return result;
	}
	//启动工作线程,这一块需要重点看
	if ((result=tracker_service_init()) != 0)
	{
		logCrit("exit abnormally!\n");
		log_destroy();
		return result;
	}
	//注册信号处理函数
	memset(&act, 0, sizeof(act));
	sigemptyset(&act.sa_mask);

	act.sa_handler = sigUsrHandler;
	if(sigaction(SIGUSR1, &act, NULL) < 0 || \
		sigaction(SIGUSR2, &act, NULL) < 0)
	{
		logCrit("file: "__FILE__", line: %d, " \
			"call sigaction fail, errno: %d, error info: %s", \
			__LINE__, errno, STRERROR(errno));
		logCrit("exit abnormally!\n");
		return errno;
	}

	act.sa_handler = sigHupHandler;
	if(sigaction(SIGHUP, &act, NULL) < 0)
	{
		logCrit("file: "__FILE__", line: %d, " \
			"call sigaction fail, errno: %d, error info: %s", \
			__LINE__, errno, STRERROR(errno));
		logCrit("exit abnormally!\n");
		return errno;
	}
	
	act.sa_handler = SIG_IGN;
	if(sigaction(SIGPIPE, &act, NULL) < 0)
	{
		logCrit("file: "__FILE__", line: %d, " \
			"call sigaction fail, errno: %d, error info: %s", \
			__LINE__, errno, STRERROR(errno));
		logCrit("exit abnormally!\n");
		return errno;
	}

	act.sa_handler = sigQuitHandler;
	if(sigaction(SIGINT, &act, NULL) < 0 || \
		sigaction(SIGTERM, &act, NULL) < 0 || \
		sigaction(SIGQUIT, &act, NULL) < 0)
	{
		logCrit("file: "__FILE__", line: %d, " \
			"call sigaction fail, errno: %d, error info: %s", \
			__LINE__, errno, STRERROR(errno));
		logCrit("exit abnormally!\n");
		return errno;
	}

#if defined(DEBUG_FLAG)
/*
#if defined(OS_LINUX)
	memset(&act, 0, sizeof(act));
	sigemptyset(&act.sa_mask);
        act.sa_sigaction = sigSegvHandler;
        act.sa_flags = SA_SIGINFO;
        if (sigaction(SIGSEGV, &act, NULL) < 0 || \
        	sigaction(SIGABRT, &act, NULL) < 0)
	{
		logCrit("file: "__FILE__", line: %d, " \
			"call sigaction fail, errno: %d, error info: %s", \
			__LINE__, errno, STRERROR(errno));
		logCrit("exit abnormally!\n");
		return errno;
	}
#endif
*/

	memset(&act, 0, sizeof(act));
	sigemptyset(&act.sa_mask);
	act.sa_handler = sigDumpHandler;
	if(sigaction(SIGUSR1, &act, NULL) < 0 || \
		sigaction(SIGUSR2, &act, NULL) < 0)
	{
		logCrit("file: "__FILE__", line: %d, " \
			"call sigaction fail, errno: %d, error info: %s", \
			__LINE__, errno, STRERROR(errno));
		logCrit("exit abnormally!\n");
		return errno;
	}
#endif

#ifdef WITH_HTTPD
	if (!g_http_params.disabled)
	{
		if ((result=tracker_httpd_start(bind_addr)) != 0)
		{
			logCrit("file: "__FILE__", line: %d, " \
				"tracker_httpd_start fail, program exit!", \
				__LINE__);
			return result;
		}

	}

	if ((result=tracker_http_check_start()) != 0)
	{
		logCrit("file: "__FILE__", line: %d, " \
			"tracker_http_check_start fail, " \
			"program exit!", __LINE__);
		return result;
	}
#endif

	if ((result=set_run_by(g_run_by_group, g_run_by_user)) != 0)
	{
		logCrit("exit abnormally!\n");
		log_destroy();
		return result;
	}
	//schedule 调度线程,主要作用待细看
	scheduleArray.entries = scheduleEntries;
	scheduleArray.count = 0;
	memset(scheduleEntries, 0, sizeof(scheduleEntries));
	//日志处理,日志是先存在cache中的,需要定时存储
	INIT_SCHEDULE_ENTRY(scheduleEntries[scheduleArray.count],
		scheduleArray.count + 1, TIME_NONE, TIME_NONE, TIME_NONE,
		g_sync_log_buff_interval, log_sync_func, &g_log_context);
	scheduleArray.count++;
	//用户检测trunk server服务器是否可用(trunk server是选定的一个storage)
	INIT_SCHEDULE_ENTRY(scheduleEntries[scheduleArray.count],
		scheduleArray.count + 1, TIME_NONE, TIME_NONE, TIME_NONE,
		g_check_active_interval, tracker_mem_check_alive, NULL);
	scheduleArray.count++;
	//每5分钟刷新一下status
	INIT_SCHEDULE_ENTRY(scheduleEntries[scheduleArray.count],
		scheduleArray.count + 1, 0, 0, 0,
		TRACKER_SYNC_STATUS_FILE_INTERVAL,
		tracker_write_status_to_file, NULL);
	scheduleArray.count++;

	if (g_rotate_error_log)
	{
		INIT_SCHEDULE_ENTRY_EX(scheduleEntries[scheduleArray.count],
			scheduleArray.count + 1, g_error_log_rotate_time,
			24 * 3600, log_notify_rotate, &g_log_context);
		scheduleArray.count++;

		if (g_log_file_keep_days > 0)
		{
			log_set_keep_days(&g_log_context, g_log_file_keep_days);

			INIT_SCHEDULE_ENTRY(scheduleEntries[scheduleArray.count],
				scheduleArray.count + 1, 1, 0, 0, 24 * 3600,
				log_delete_old_files, &g_log_context);
			scheduleArray.count++;
		}
	}

	if ((result=sched_start(&scheduleArray, &schedule_tid, \
		g_thread_stack_size, (bool * volatile)&g_continue_flag)) != 0)
	{
		logCrit("exit abnormally!\n");
		log_destroy();
		return result;
	}
	//选主机制,tracker默认不会把自己加入队列
	if ((result=tracker_relationship_init()) != 0)
	{
		logCrit("exit abnormally!\n");
		log_destroy();
		return result;
	}

	log_set_cache(true);

	bTerminateFlag = false;
	bAcceptEndFlag = false;
	//accept线程,工作线程和消息接收线程是分开的
	tracker_accept_loop(sock);
	bAcceptEndFlag = true;
	if (g_schedule_flag)
	{
		pthread_kill(schedule_tid, SIGINT);
	}
	tracker_terminate_threads();

#ifdef WITH_HTTPD
	if (g_http_check_flag)
	{
		tracker_http_check_stop();
	}

	while (g_http_check_flag)
	{
		usleep(50000);
	}
#endif

	wait_count = 0;
	//线程数和调度flag还在,则继续运行程序
	while ((g_tracker_thread_count != 0) || g_schedule_flag)
	{

/*
#if defined(DEBUG_FLAG) && defined(OS_LINUX)
		if (bSegmentFault)
		{
			sleep(5);
			break;
		}
#endif
*/

		usleep(10000);
		if (++wait_count > 3000)
		{
			logWarning("waiting timeout, exit!");
			break;
		}
	}
	
	tracker_mem_destroy();
	tracker_service_destroy();
	tracker_relationship_destroy();
	
	logInfo("exit normally.\n");
	log_destroy();
	
	delete_pid_file(pidFilename);
	return 0;
}