Exemple #1
0
void minmax(game & cur)
{
	if (cur.finished())
	{
		cout << "game is done" << endl;
		return;
	}
	forward_list<game> moves = cur.getMoves();
	int best = -10000;
	game best_move;
	int count = 0;
	while(!moves.empty())
	{
		debug(++count);
		game top = moves.front();
		moves.pop_front();
		int score = calcvalue(top, true);
		if (score > best)
		{
			best_move = top;
			best = score;
		}
	}
	cout << "best move is \n" << best_move;
}
void classMap::move_npcs() /// @TODO - check out of screen
{
	int i = 0;
	std::list<classnpc*>::iterator npc_it;
	//std::cout << "*************** classMap::showMap - npc_list.size: " << npc_list.size() << std::endl;
	for (npc_it = npc_list.begin(); npc_it != npc_list.end(); npc_it++) {
		//std::cout << ">>>>>>>>>>>>>>>>>> classMap::showMap - executing npc[" << i << "] '" << (*npc_it)->getName() << "'" << std::endl;
		bool temp_is_boss = (*npc_it)->is_boss();

		if (freeze_weapon_effect == false) {
			(*npc_it)->execute(); // TODO: must pass scroll map to npcs somwhow...
		}
		//(*npc_it)->show();
		if ((*npc_it)->is_dead() == true) {
			std::string temp_name = (*npc_it)->getName();
			if (!temp_is_boss) {
				add_animation(ANIMATION_STATIC, std::string("explosion_32.png"), st_position((*npc_it)->getPosition().x, (*npc_it)->getPosition().y), st_position(-8, -8), 80, 2, (*npc_it)->get_direction(), st_size(32, 32));
			}
			//std::cout << "Stage[" << stage_number << "].map[" << number << "] - Killed npc[" << i << "] '" << (*npc_it)->getName() << "'" << ", is_boss: " << temp_is_boss << std::endl;
			st_position npc_pos = (*npc_it)->get_real_position();
			delete (*npc_it);
			npc_list.erase(npc_it);
			if (temp_is_boss) {
				//std::cout << "classMap::showMap - killed boss" << std::endl;
				gameControl.draw_explosion(npc_pos.x, npc_pos.y, true);
				gameControl.got_weapon(temp_name);
			}
			return;
		}
		i++;
	}
}
Exemple #3
0
void menu::go_to_winscreen(game& g)
{
	//postup do dalsich levelu kampane
	for (int i = 0;i < campaign.size();++i)
		if (maplist_get_name(g.get_mapchosen()).compare(campaign[i]) 
			== 0) 
			if (i != campaign.size() - 1) 
				g.change_campaign_status(i + 1);
	set_menu(12);
}
Exemple #4
0
int corner_info(int corner, int tilenum)
{
	int retval = 0;
	if(usrin == 1)
		retval = (10 * catan.check_corner_owner(corner, tilenum) + catan.check_corner_building_type(corner, tilenum));
	else if (usrin == 2)
		retval = (10 * clientcatan.check_corner_owner(corner, tilenum) + clientcatan.check_corner_building_type(corner, tilenum));
	else
		cout << "invalid input dickhead!" << endl;
	return(retval);
}
Exemple #5
0
/* 
 * Main function
 */
int main(int argc, char* args[]) {
	try{
		// Initialize game
		gam.init_game();

		// Go to main loop
		gam.main();
	}
	catch (exception &e) {err_hndl_obj.inform_about_error("main()", e);};

	// Quit application
	return 0;
}
Exemple #6
0
void GameInit() {
	g_game_rand = random(GetTickCount());

	g_game._player = spawn_entity(&g_game, new player(), vec2(10.0f, 9.5f));

	for(int j = 0; j < MAP_HEIGHT; j++) {
		for(int i = 0; i < MAP_WIDTH; i++) {
			if (tile* t = g_game.get(i, j)) {
				if (j < 10) {
					t->type =  ((i == 0) || (i == MAP_WIDTH - 1)) ? TT_VOID : TT_EMPTY;
				}
				else if (j < (MAP_HEIGHT - 2)) {
					t->type = ((i == 0) || (i == MAP_WIDTH - 1)) ? TT_WALL : TT_SOLID;

					if ((i > 0) && (i < MAP_WIDTH - 1)) {
						int wall_c = max(20 - ((j - 10) / 2), 5);

						if (g_game_rand.rand(0, 150) == 0) {
							if (j > 20)
								t->ore = -1;
						}
						else if (g_game_rand.rand(0, wall_c) == 0) {
							t->type = TT_WALL;
						}
					}
				}
				else
					t->type = TT_WALL;
			}
		}

		int ores = clamp(j / 15, 1, 10) + g_game_rand.rand(0, 2);
		
		for(int z = 0; z < ores; z++) {
			int i = g_game_rand.rand(1, MAP_WIDTH - 2);

			if (tile* t = g_game.get(i, j)) {
				if (t->type == TT_SOLID) {
					if (t->ore == 0) {
						t->ore = 1;

						for(int z = j / 15; z > 0; z--)
							t->ore += g_game_rand.rand(0, 4) == 0;
					}
				}
			}
		}
	}
}
int main(int argc, char *argv[])
{
	quick_load = false;
	UNUSED(argc);
	gameControl.currentStage = TECHNOBOT;
	game_config.selected_player = 1;

	//strncpy (FILEPATH, argv[0], strlen(argv[0])-11);

	string argvString = string(argv[0]);

	FILEPATH = argvString.substr(0, argvString.size()-EXEC_NAME.size());
	//std::cout << "main - FILEPATH: " << FILEPATH << std::endl;

	format_v_2_0_1::file_io fio;
	fio.read_game(game_data);

	// INIT GRAPHICS
	if (graphLib.initGraphics() != true) {
		exit(-1);
	}

	// INIT GAME
	if (quick_load == false) {
		if (gameControl.showIntro() == false) {
			return 0;
		}
	} else {
		gameControl.quick_load_game();
		//ending game_ending;
		//game_ending.start();
	}

	input.clean();
	input.p1_input[BTN_START] = 0;
	input.waitTime(200);
	input.clean();
	while (true) {
		input.readInput();
		if (input.p1_input[BTN_QUIT] == 1) {
			exit(-1);
		}
		gameControl.showGame();
		graphLib.updateScreen();
	}
	/// @TODO: sdl quit sub-systems
	SDL_Quit();
	return 1;
}
void sub_uzo_display::post_display(game& gm) const
{
	if (gm.get_player()->get_target()) {
		projection_data pd = get_projection_data(gm);
		ui.show_target(pd.x, pd.y, pd.w, pd.h, get_viewpos(gm));
	}

	sys().prepare_2d_drawing();
	
	int tex_w = compass->get_width();
	int tex_h = compass->get_height();

	int bearing = int(tex_w*ui.get_relative_bearing().value()/360);

	if( bearing>dx && bearing<tex_w-dx){
		compass->draw_subimage(xi, yi, comp_size, tex_h, bearing-dx, 0, comp_size, tex_h);
	} else {
		int dx1=0,dx2=0;
		if( bearing<dx ){ dx1=dx-bearing; dx2=dx+bearing; } else if( bearing>tex_w-dx ){ dx1=dx+(tex_w-bearing); dx2=comp_size-dx; }
		compass->draw_subimage(xi, yi, dx1, tex_h, tex_w-(dx1), 0, dx1, tex_h);
		compass->draw_subimage(xi+dx1, yi, dx2, tex_h, 0, 0, dx2, tex_h );
	}
	
	uzotex->draw(0, 0, 1024, 768);
	ui.draw_infopanel(true);

	sys().unprepare_2d_drawing();
}
void sub_uzo_display::set_modelview_matrix(game& gm, const vector3& viewpos) const
{
	glLoadIdentity();

	// set up rotation (player's view direction)
	// limit elevation to -20...20 degrees.
	float elev = -ui.get_elevation().value();
	const float LIMIT = 20.0f;
	if (elev < -LIMIT - 90.0f) elev = -LIMIT - 90.0f;
	if (elev > +LIMIT - 90.0f) elev = +LIMIT - 90.0f;
	glRotated(elev,1,0,0);

	// if we're aboard the player's vessel move the world instead of the ship
	if (aboard) {
		// This should be a negative angle, but nautical view dir is clockwise,
		// OpenGL uses ccw values, so this is a double negation
		glRotated(ui.get_relative_bearing().value(),0,0,1);
		gm.get_player()->get_orientation().conj().rotmat4().multiply_gl();
	} else {
		// This should be a negative angle, but nautical view dir is clockwise,
		// OpenGL uses ccw values, so this is a double negation
		glRotated(ui.get_absolute_bearing().value(),0,0,1);
	}

	// set up modelview matrix as if player is at position (0, 0, 0), so do NOT set a translational part.
	// This is done to avoid rounding errors caused by large x/y values (modelview matrix seems to store floats,
	// but coordinates are in real meters, so float is not precise enough).
}
Exemple #10
0
void display() {
    glClear(GL_COLOR_BUFFER_BIT);
    painter p;
    game_.draw(p);

    glutSwapBuffers();
}
// update
void update(MASTERSCREEN screen)
{
	mxhwnd.SetTimeFlag();
	
	switch(screen)
	{
	case ID_KLOSED:
		klosed.update();
		break;
	case ID_INTRO:
		intro.intro_update();
		break;
	
	case ID_OPTIONS:
		//options_update();
		break;
	case ID_GAME:
		
		game.update();
	
		break;
	case ID_GAMEOVER:
		//gameover_update();
		break;
	}
	
}
// ********************************************************************************************** //
//                                                                                                //
// ********************************************************************************************** //
int inputLib::waitScapeTime(int wait_period) {
	int now_time = 0;

	waitTime(50);
	now_time = timer.getTimer();
	wait_period = now_time + wait_period;

	while (now_time < wait_period) {
		readInput();
		if (p1_input[BTN_START] == 1 || p2_input[BTN_START] == 1) {
			return 1;
        } else if (p1_input[BTN_QUIT] == 1 || p2_input[BTN_QUIT] == 1) {
#if !defined(PLAYSTATION2) && !defined(PSP) && !defined(WII) && !defined(DREAMCAST)
            std::cout << "LEAVE #2" << std::endl;
            std::fflush(stdout);
            gameControl.leave_game();
#endif
		}
		now_time = timer.getTimer();
		#ifdef PLAYSTATION
			RotateThreadReadyQueue(_MIXER_THREAD_PRIORITY);
		#endif
        SDL_Delay(5);
	}
	return 0;
}
Exemple #13
0
/**
* Checks the game winning conditions to see if it has been won.
*/
bool isGameOver()
{
	//checks to see if the game is over after each turn if all player hands and deck are empty
	int gameOverCounter=0;
	int totalPlayerCount=currentGame.getPlayerCount();
	for(int i = 0; i < totalPlayerCount; i++)
	{
		if(currentGame.getPlayer(i).getHand().size()==0)
			gameOverCounter++;
	}
	if(gameOverCounter==totalPlayerCount && currentGame.getDeck().isEmpty()==true)
	{
		return true;
	}
	else 
		return false;
}
Exemple #14
0
void keyEvent(int key, int, int)
{
    switch (key)
    {
    case GLUT_KEY_LEFT:
        game_.keyEvent(snake::LEFT);
        break;
    case GLUT_KEY_UP:
        game_.keyEvent(snake::UP);
        break;
    case GLUT_KEY_RIGHT:
        game_.keyEvent(snake::RIGHT);
        break;
    case GLUT_KEY_DOWN:
        game_.keyEvent(snake::DOWN);
        break;
    }
}
Exemple #15
0
void renderScene(void) {
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	disp.setOrthographicProjection();
	glLoadIdentity();
	
	//Functions to draw objects
	interface.drawBoarder(boarderTexture);
	
	
	glutSwapBuffers();
	
}
bool networking::gameOverCheck(gameData gd, game Game){
	bool gameOver = Game.gameOver();
	if(write(gd.player1, &gameOver, sizeof(bool)) == -1)
	{
		perror("[server]Eroare la scriere in socket");
	}
	if(write(gd.player2, &gameOver, sizeof(bool)) == -1)
	{
		perror("[server]Eroare la scriere in socket");
	}
	return gameOver;
}
bool networking::winConditionCheck(gameData gd, game Game){
	bool winCondition = Game.winCondition();
	if(write(gd.player1, &winCondition, sizeof(bool)) == -1)
	{
		perror("[server]Eroare la scriere in socket");
	}
	if(write(gd.player2, &winCondition, sizeof(bool)) == -1)
	{
		perror("[server]Eroare la scriere in socket");
	}
	return winCondition;
}
user_interface* user_interface::create(game& gm)
{
	sea_object* p = gm.get_player();
	user_interface* ui = 0;
	// check for interfaces
	if (dynamic_cast<submarine*>(p)) ui = new submarine_interface(gm);
#if 0
	else if (dynamic_cast<ship*>(p)) ui = new ship_interface(gm);
	else if (dynamic_cast<airplane*>(p)) ui = new airplane_interface(gm);
#endif
	if (ui) ui->finish_construction();
	return ui;
}
Exemple #19
0
/**
* Displays the scores of each player next to them.
*/
void updateScore(int comps)
{
	const char* cstr3;
	const char* cstr2;
	const char* cstr1;
	const char* cstr;
	switch(comps)
	{
	case 3: 
		cstr3 = currentGame.getPlayer(3).getScore().c_str();
		mvprintw(7,5,cstr3); //Falls through to the next player
	case 2: 
		cstr2 = currentGame.getPlayer(2).getScore().c_str();
		mvprintw(7,58,cstr2);
	case 1: 
		cstr1 = currentGame.getPlayer(1).getScore().c_str();
		mvprintw(3,32,cstr1);
	default: 
		cstr = currentGame.getPlayer(0).getScore().c_str();
		mvprintw(12,40,cstr);
	}
}
Exemple #20
0
int calcvalue(game& cur, bool isMax)
{
	if (cur.finished())
	{
		if (isMax) return cur.getValue();
		return -cur.getValue();
	}
	forward_list<game> moves = cur.getMoves();
	int best = isMax? -10000 : 10000;
	while(!moves.empty())
	{
		game top = moves.front();
		moves.pop_front();
		int score = calcvalue(top, !isMax);
		if (isMax)
		{
			best = max(best, score);
		}
		else
			best = min(best, score);
	}
	return best;
}
void classPlayer::death()
{
    std::cout << "PLAYER::death" << std::endl;
    map->print_objects_number();
    reset_charging_shot();
	map->clear_animations();
    map->print_objects_number();
    map->reset_objects();
    map->print_objects_number();
	dead = true;
	state.jump_state = NO_JUMP;
    freeze_weapon_effect = FREEZE_EFFECT_NONE;
    clear_move_commands();
	input.clean();
	state.direction = ANIM_DIRECTION_RIGHT;
	gameControl.draw_explosion(realPosition.x, realPosition.y, false);
    if (game_save.items.lifes == 0) {
        game_save.items.lifes = 3;
        std::cout << "GAME OVER" << std::endl;
        gameControl.game_over();
        return;
    }
    game_save.items.lifes--;
}
void classboss::boss_move() {
	if (state.move_timer > timer.getTimer()) {
		return;
	}

	if (_initialized == 0) { /// @TODO: move this logic to map (player should not move while boss is presenting)
		_initialized++;
		gameControl.boss_intro();
		return;
	} else if (_initialized == 1) {
		if (position.x > RES_H/2 && gravity(true) == false) {
			_initialized++;
		}
		state.move_timer = timer.getTimer()+100;
		return;
	}


	//std::cout << "classboss::move [" << name << "]" << std::endl;
	/*
	int mapScrollX = map->getMapScrolling().x;
	int lock_point = map->getMapPointLock(st_position(position.x/16, position.y/16));
	struct struct_player_dist dist_players = dist_npc_players();
	*/

	if (first_run == 0) {
		// show boss dialogs here
		first_run = 1;
		//boss_energy = temp_npc;
		//play_boss_music();
		//show_dialog(STAGE_N, 1);
	}
	if (name == "Daisie Bot") {
		exec_daisiebot();
		//npc_gravity(temp_npc);
		return;
	} else if (name == "Ape Bot") {
		//exec_IA_Apebot(temp_npc);
        //exec_daisiebot();
		return;
	} else {
		gravity(false);
		return;
	}
}
void draw::preload()
{
    std::string filename = FILEPATH + "data/images/tilesets/ready.png";
    graphLib.surfaceFromFile(filename, &ready_message);

    filename = FILEPATH + "data/images/sprites/teleport_small.png";
    graphLib.surfaceFromFile(filename, &_teleport_small_gfx);

    // DROPABLE OBJECT GRAPHICS
    for (int i=0; i<GAME_MAX_OBJS; i++) {
        for (int j=0; j<DROP_ITEM_COUNT; j++) {
            short obj_type_n = gameControl.get_drop_item_id(j);
            if (obj_type_n != -1) {
                get_object_graphic(obj_type_n);
            }
        }
    }
}
void networking::getMove(gameData gd, game &Game){
	int position;
	bool response;
	if(Game.getCurrentPlayer() == 1)
	{
		if(read(gd.player1, &position, sizeof(int)) == -1)
		{
			perror("[server]Eroare la citire din socket");
		}
		while(!(response = Game.insertDisc(position, Game.getCurrentPlayer())))
		{
			if(write(gd.player1, &response, sizeof(bool)) == -1)
			{
				perror("[server]Eroare la scriere in socket");
			}
			if(read(gd.player1, &position, sizeof(int)) == -1)
			{
				perror("[server]Eroare la citire din socket");

			}
		}
		if(write(gd.player1, &response, sizeof(bool)) == -1)
		{
			perror("[server]Eroare la scriere in socket");
		}
	}
	else if(Game.getCurrentPlayer() == 2)
	{
		if(read(gd.player2, &position, sizeof(int)) == -1)
		{
			perror("[server]Eroare la citire din socket");
		}
		while(!(response = Game.insertDisc(position, Game.getCurrentPlayer())))
		{
			if(write(gd.player2, &response, sizeof(bool)) == -1)
			{
				perror("[server]Eroare la scriere in socket");
			}
			if(read(gd.player2, &position, sizeof(int)) == -1)
			{
				perror("[server]Eroare la citire din socket");
			}
		}
		if(write(gd.player2, &response, sizeof(bool)) == -1)
		{
			perror("[server]Eroare la scriere in socket");
		}
	}
}
int main()
{
    // Begin
    std::cout << "\n/*---------------------BEGIN GAME---------------------*/\n";
    std::cout << std::endl;

    // Initialise game engine
    auto engine = GameEngine(GRID_WIDTH, GRID_HEIGHT, MAX_SHAPES);

    // Initialise round count
    int rounds = 1;

    // Continue until one shape remains
    while (engine.shapes_remaining() > 1) {
        // Elimination round
        std::cout << "Round:\t" << rounds << std::endl;
        engine.resolve_overlaps();
        rounds++;

        // Print the total remaining
        std::cout << "\n\tShapes remaining:\t";
        std::cout << engine.shapes_remaining() << std::endl << std::endl;

        // Advance shape positions for next round if we aren't done already
        if (engine.shapes_remaining() > 1)
            engine.advance_positions();
    }

    std::cout << "\n/*---------------------GAME ENDED---------------------*/\n";
    std::cout << std::endl;

    // Print the final shape
    std::cout << "Final shape:\n\t" << engine.first() << std::endl;

    std::cout << "\n/*----------------------------------------------------*/\n";
    std::cout << std::endl;

    // End
    return 0;
}
Exemple #26
0
int main(int argc, char *argv[])
{
	  /* perform initialization NOT OpenGL/GLUT dependent,
		 as we haven't created a GLUT window yet */
	init();

	/* initialize GLUT, let it extract command-line
	GLUT options that you may provide
	- NOTE THE '&' BEFORE argc */
	glutInit(&argc, argv);

	createWindow(WIDTH, HEIGHT, TITLE);

	  /* register function to handle window resizes */
	glutReshapeFunc(reshape);
	
	  /* register keyboard event processing function */
	glutKeyboardFunc(kbd);
	glutKeyboardUpFunc(kbu);
	glutTimerFunc(TIME, update, 0);

	  /* register function that draws in the window */
	glutDisplayFunc(display);

	  /* init GL */
	glClearColor(0.2f, 0.2f, 0.3f, 1.0f);
	glColor3f(0.0, 0.0, 0.0);
	glLineWidth(3.0);

	instance.contextCreated();

	//////printf("%s\n", gluErrorString(glGetError()));
	  /* start the GLUT main loop */
	glutMainLoop();


	exit(0);
}
// mastermain
int XSTD MasterMain(HINSTANCE hInst,LPSTR line)
{
	srand(time(NULL));

	// init masterX
	if(mxhwnd.CreateMasterX("Deslock",800,600,COLOR_DEFAULT,MasterProc,hInst,LoadIcon(hInst,MAKEINTRESOURCE(IDI_ICON1)),NULL),LoadCursor(NULL,IDC_ARROW))//LoadIcon(hInst,MAKEINTRESOURCE(IDI_ICON1)),NULL))
	{
		
		mxhwnd.InitTimer(1,1);
		
		klosed.load();
		intro.load();
		game.load();
	

		mxhwnd.SetScreen(ID_KLOSED);
		mxhwnd.HideCursor();
		
		//playgamesound(0);
		return mxhwnd.InitLoop(update);
	}
	
	return 0;
}
Exemple #28
0
// keyboard down
void kbd(unsigned char key, int x, int y)
{
  switch((char)key) {
  case 'q':
  case 27:
    glutDestroyWindow(wd);
    exit(0);
  default:
    break;
  }

  glutGetModifiers();
  enum modifier { off, shift, ctrl, alt };
  int mod = 0;
  if (glutGetModifiers() & GLUT_ACTIVE_SHIFT) mod = modifier::shift;
  else if (glutGetModifiers() & GLUT_ACTIVE_CTRL) mod = modifier::ctrl;
  else if (glutGetModifiers() & GLUT_ACTIVE_ALT) mod = modifier::alt;
  else mod = modifier::off;
  if (mod == modifier::ctrl) key += 96;

  instance.recieveInput(key, x, y, mod);

  return;
}
Exemple #29
0
bool menu::update(float timediff, bool esc_down, bool left_mouse_down, 
	bool right_mouse_down, int mouse_x, int mouse_y, game& g)
{
	//aktualni hodnoty pro prichod do podmenu
	mapname = maplist_get_name(g.get_mapchosen());
	username = userlist_get_name(g.get_userchosen());
	sens = sensitivities[g.get_sensitivity()];
	dayt = daytime[g.get_daytime()];
	weat = weather[g.get_weather()];
	diff = difficulty[g.get_difficulty()];

	//urceni pozice kurzoru
	cursor_pos += mouse_y;
	if (cursor_pos >= (int)(items.size() *100)) 
		cursor_pos = (int)(items.size() * 100 - 1);
	if (cursor_pos < 0) cursor_pos = 0;

	int left_just_pressed = 0, esc_just_pressed = 0;
	//proti sekvencim stisknutych tlacitek
	if (left_mouse_down) {
		if (!left_mouse_hit)
			left_just_pressed = left_mouse_hit = 1;
	} else left_mouse_hit = 0;
	if (esc_down) {
		if (!esc_hit)
			esc_just_pressed = esc_hit = 1;
	} else esc_hit = 0;
	
	//pro vytvoreni prvniho uzivatelskeho uctu pri prvnim spusteni hry
	if ((username == "") && (menustatus != 10)) {
		new_one = true;
		set_menu(10);
	}
	
	//vyber submenu
	if (left_just_pressed || esc_just_pressed)
		if (!handle_menu_click(cursor_pos / 100, g, esc_just_pressed))
			return false;

	return true;
}
user_interface::user_interface(game& gm) :
	mygame(&gm),
	pause(false),
	time_scale(1),
	panel_visible(true),
	screen_selector_visible(false),
	playlist_visible(false),
	main_menu_visible(false),
	bearing(0),
	elevation(90),
	bearing_is_relative(true),
	current_display(0),
	current_popup(0),
	mycoastmap(get_map_dir() + "default.xml"),
	daymode(gm.is_day_mode())
{
	add_loading_screen("coast map initialized");
	mysky.reset(new sky());
	panel.reset(new widget(0, 768-32, 1024, 32, "", 0));
	panel->set_background(0);
	// ca. 1024-2*8 for 6 texts => 168 pix. for each text
	int paneltextnrs[6] = { 1, 4, 5, 2, 98, 61 };
	const char* paneltexts[6] = { "000", "000", "000", "000", "000", "00:00:00" };
	for (int i = 0; i < 6; ++i) {
		int off = 8 + i*(1024-2*8)/6;
		string tx = texts::get(paneltextnrs[i]);
		vector2i sz = widget::get_theme()->myfont->get_size(tx);
		panel->add_child(new widget_text(off, 4, 0, 0, tx));
		panel_valuetexts[i] = new widget_text(off + 8 + sz.x, 4, 0, 0, paneltexts[i]);
		panel->add_child(panel_valuetexts[i]);
	}

	// create screen selector widget
	screen_selector.reset(new widget(0, 0, 256, 32, "", 0));
	screen_selector->set_background(0);

	// create playlist widget
	music_playlist.reset(new widget(0, 0, 384, 512, texts::get(262), 0));
	music_playlist->set_background(0);
	struct musiclist : public widget_list
	{
		bool active;
		void on_sel_change() {
			if (!active) return;
			int s = get_selected();
			if (s >= 0)
				music::instance().play_track(unsigned(s), 500);
		}
		musiclist(int x, int y, int w, int h) : widget_list(x, y, w, h), active(false) {}
	};
	musiclist* playlist = new musiclist(0, 0, 384, 512);
	music_playlist->add_child_near_last_child(playlist);
	music& m = music::instance();
	vector<string> mpl = m.get_playlist();
	for (vector<string>::const_iterator it = mpl.begin();
	     it != mpl.end(); ++it) {
		playlist->append_entry(*it);
	}
	typedef widget_caller_checkbox<user_interface, void (user_interface::*)()> wccui;
	// fixme: use checkbox here...
	playlist_repeat_checkbox = new wccui(this, &user_interface::playlist_mode_changed, 0, 0, 192, 32, false, texts::get(263));
	music_playlist->add_child_near_last_child(playlist_repeat_checkbox);
	playlist_shuffle_checkbox = new wccui(this, &user_interface::playlist_mode_changed, 0, 0, 192, 32, false, texts::get(264));
	music_playlist->add_child_near_last_child(playlist_shuffle_checkbox, 0, 1);
	playlist_mute_checkbox = new wccui(this, &user_interface::playlist_mute, 0, 0, 384, 32, false, texts::get(265));
	music_playlist->add_child_near_last_child(playlist_mute_checkbox, 0);
	playlist_mute_checkbox->move_pos(vector2i(-192, 0));
	music_playlist->add_child_near_last_child(new widget_set_button<bool>(playlist_visible, false, 0, 0, 384, 32, texts::get(260)), 0);
	music_playlist->clip_to_children_area();
	music_playlist->set_pos(vector2i(0, 0));
	// enable music switching finally, to avoid on_sel_change changing the music track,
	// because on_sel_change is called above, when adding entries.
	playlist->active = true;

	// create main menu widget
	main_menu.reset(new widget(0, 0, 256, 128, texts::get(104), 0));
	main_menu->set_background(0);
	typedef widget_caller_button<user_interface, void (user_interface::*)()> wcbui;
	main_menu->add_child_near_last_child(new wcbui(this, &user_interface::show_screen_selector, 0, 0, 256, 32, texts::get(266)));
	main_menu->add_child_near_last_child(new wcbui(this, &user_interface::toggle_popup, 0, 0, 256, 32, texts::get(267)), 0);
	main_menu->add_child_near_last_child(new wcbui(this, &user_interface::show_playlist, 0, 0, 256, 32, texts::get(261)), 0);
	main_menu->add_child_near_last_child(new wcbui(this, &user_interface::toggle_pause, 0, 0, 256, 32, texts::get(268)), 0);
	main_menu->add_child_near_last_child(new widget_caller_arg_button<user_interface, void (user_interface::*)(bool), bool>(this, &user_interface::request_abort, true, 0, 0, 256, 32, texts::get(177)), 0);
	main_menu->add_child_near_last_child(new widget_set_button<bool>(main_menu_visible, false, 0, 0, 256, 32, texts::get(260)), 0);
	main_menu->clip_to_children_area();
	vector2i mmp = sys().get_res_2d() - main_menu->get_size();
	main_menu->set_pos(vector2i(mmp.x/2, mmp.y/2));

	// create weather effects textures

	// rain
#ifdef RAIN
#define NR_OF_RAIN_FRAMES 16
#define NR_OF_RAIN_DROPS 800
#define RAIN_TEX_W 256
#define RAIN_TEX_H 256
	raintex.resize(NR_OF_RAIN_FRAMES);
	vector<Uint8> raintmptex(RAIN_TEX_W * RAIN_TEX_H * 2);

	for (unsigned j = 0; j < NR_OF_RAIN_FRAMES; ++j) {
		for (unsigned k = 0; k < RAIN_TEX_W * RAIN_TEX_H * 2; k += 2) {
			raintmptex[k + 0] = 128;
			raintmptex[k + 1] = 0;
		}
		for (unsigned i = 0; i < NR_OF_RAIN_DROPS; ++i) {
			vector2i pos(rnd(RAIN_TEX_W-2)+2, rnd(RAIN_TEX_H-2));
			Uint8 c = rnd(64)+128;
			raintmptex[(RAIN_TEX_W*pos.y + pos.x) * 2 + 0] = c;
			raintmptex[(RAIN_TEX_W*pos.y + pos.x) * 2 + 1] = 128;
			pos.x -= 1; pos.y += 1;
			raintmptex[(RAIN_TEX_W*pos.y + pos.x) * 2 + 0] = c;
			raintmptex[(RAIN_TEX_W*pos.y + pos.x) * 2 + 1] = 192;
			pos.x -= 1; pos.y += 1;
			raintmptex[(RAIN_TEX_W*pos.y + pos.x) * 2 + 0] = c;
			raintmptex[(RAIN_TEX_W*pos.y + pos.x) * 2 + 1] = 255;
		}
		raintex.reset(j, new texture(raintmptex, RAIN_TEX_W, RAIN_TEX_H, GL_LUMINANCE_ALPHA, texture::LINEAR_MIPMAP_LINEAR, texture::REPEAT));
	}
#endif
	// snow
#ifdef SNOW
#define NR_OF_SNOW_FRAMES 23
#define NR_OF_SNOW_FLAKES 2000
#define SNOW_TEX_W 256
#define SNOW_TEX_H 256
	snowtex.resize(NR_OF_SNOW_FRAMES);
	vector<Uint8> snowtmptex(SNOW_TEX_W * SNOW_TEX_H * 2, 255);
	vector<vector2i> snowflakepos(NR_OF_SNOW_FLAKES);
	vector<int> snowxrand(NR_OF_SNOW_FRAMES);

	// create random x coordinate sequence (perturbation)
	vector<unsigned> snowxtrans(SNOW_TEX_W);
	for (unsigned k = 0; k < SNOW_TEX_W; ++k) {
		snowxtrans[k] = k;
	}
	for (unsigned k = 0; k < SNOW_TEX_W * 20; ++k) {
		unsigned a = rnd(SNOW_TEX_W), b = rnd(SNOW_TEX_W);
		unsigned c = snowxtrans[a];
		snowxtrans[a] = snowxtrans[b];
		snowxtrans[b] = c;
	}

	for (unsigned j = 0; j < NR_OF_SNOW_FRAMES; ++j) {
		snowxrand[j] = rnd(3)-1;
	}
	snowflakepos[0] = vector2i(snowxtrans[0], 0);
	for (unsigned i = 1; i < NR_OF_SNOW_FLAKES; ++i) {
		vector2i oldpos = snowflakepos[i-1];
		for (unsigned j = 0; j < NR_OF_SNOW_FRAMES; ++j) {
			oldpos.x += snowxrand[(j+3*i)%NR_OF_SNOW_FRAMES];
			if (oldpos.x < 0) oldpos.x += SNOW_TEX_W;
			if (oldpos.x >= SNOW_TEX_W) oldpos.x -= SNOW_TEX_W;
			oldpos.y += 1;	// fixme add more complex "fall down" function
			if (oldpos.y >= SNOW_TEX_H) {
				oldpos.x = snowxtrans[oldpos.x];
				oldpos.y = 0;
			}
		}
		snowflakepos[i] = oldpos;
	}
	for (unsigned i = 0; i < NR_OF_SNOW_FRAMES; ++i) {
		for (unsigned k = 0; k < SNOW_TEX_W * SNOW_TEX_H * 2; k += 2)
			snowtmptex[k + 1] = 0;
		for (unsigned j = 0; j < NR_OF_SNOW_FLAKES; ++j) {
			snowtmptex[(SNOW_TEX_H*snowflakepos[j].y + snowflakepos[j].x) * 2 + 1] = 255;
			vector2i& oldpos = snowflakepos[j];
			oldpos.x += snowxrand[(j+3*i)%NR_OF_SNOW_FRAMES];
			if (oldpos.x < 0) oldpos.x += SNOW_TEX_W;
			if (oldpos.x >= SNOW_TEX_W) oldpos.x -= SNOW_TEX_W;
			oldpos.y += 1;	// fixme add more complex "fall down" function
			if (oldpos.y >= SNOW_TEX_H) {
				oldpos.x = snowxtrans[oldpos.x];
				oldpos.y = 0;
			}
		}
/*
		ostringstream oss;
		oss << "snowframe"<<i<<".pgm";
		ofstream osg(oss.str().c_str());
		osg << "P5\n"<<SNOW_TEX_W<<" "<<SNOW_TEX_H<<"\n255\n";
		osg.write((const char*)(&snowtmptex[0]), SNOW_TEX_W * SNOW_TEX_H);
*/
		snowtex.reset(i, new texture(snowtmptex, SNOW_TEX_W, SNOW_TEX_H, GL_LUMINANCE_ALPHA, texture::LINEAR_MIPMAP_LINEAR, texture::REPEAT));
	}
#endif

	particle::init();

	// level size is N * sample_spacing * 2^j, here we give n = log2(N)
	// where j is level number from 0 on.
	// so we compute number of levels:
	// 2^n * sample_spacing * 2^j_max <= z_far
	// j_max <= log2(z_far / (2^n * sample_spacing))
	// and #levels = j_max+1
	// so #levels = floor(log2(z_far / (2^n * sample_spacing))) + 1
	//const double z_far = 20000.0;

  add_loading_screen("user interface initialized");

	mygeoclipmap.reset(new geoclipmap(TERRAIN_NR_LEVELS, TERRAIN_RESOLUTION_N, mygame->get_height_gen()));
  mygeoclipmap->set_viewerpos(gm.get_player()->get_pos());

	add_loading_screen("terrain loaded");
}