tcod-haskell-0.1.0.0: libtcod/samples/worldgen/main.cpp
/*
* Copyright (c) 2010 Jice
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * The name of Jice may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY JICE ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JICE BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "main.hpp"
#define WIDTH 80
#define HEIGHT 50
TCODNoise noise1d(1);
TCODNoise noise2d(2);
WorldGenerator worldGen;
// world map panning
float wx=0,wy=0, curwx=0,curwy=0;
// mouse coordinates in world map
float mx=0,my=0;
void update(float elapsed, TCOD_key_t k, TCOD_mouse_t mouse) {
// destination wanted
wx = (worldGen.getWidth()-2*WIDTH) * mouse.cx / WIDTH;
wy = (worldGen.getHeight()-2*HEIGHT) * mouse.cy / HEIGHT;
curwx += (wx-curwx)*elapsed;
curwy += (wy-curwy)*elapsed;
mx = curwx + mouse.cx*2;
my = curwy + mouse.cy*2;
worldGen.updateClouds(elapsed);
}
TCODColor getMapShadedColor(float worldX,float worldY,bool clouds) {
// sun color
static TCODColor sunCol(255,255,200);
float wx = CLAMP(0.0f, worldGen.getWidth()-1,worldX);
float wy = CLAMP(0.0f, worldGen.getHeight()-1,worldY);
// apply cloud shadow
float cloudAmount = clouds ? worldGen.getCloudThickness(wx,wy) : 0.0f;
TCODColor col = worldGen.getInterpolatedColor(worldX,worldY);
// apply sun light
float intensity = worldGen.getInterpolatedIntensity(wx,wy);
intensity = MIN(intensity, 1.5f-cloudAmount);
int cr = (int)(intensity*(int)(col.r)*sunCol.r/255 );
int cg = (int)(intensity*(int)(col.g)*sunCol.g/255 );
int cb = (int)(intensity*(int)(col.b)*sunCol.b/255 );
TCODColor col2;
col2.r = CLAMP(0,255,cr);
col2.g = CLAMP(0,255,cg);
col2.b = CLAMP(0,255,cb);
col2.r=MAX(col2.r,col.r/2);
col2.g=MAX(col2.g,col.g/2);
col2.b=MAX(col2.b,col.b/2);
return col2;
}
void render() {
// subcell resolution image
static TCODImage map(WIDTH*2,HEIGHT*2);
// compute the map image
for (int px=0; px <2*WIDTH; px++) {
for (int py=0; py <2*HEIGHT; py++) {
// world texel coordinate (with fisheye distorsion)
float wx = px+curwx;
float wy = py+curwy;
map.putPixel(px,py,getMapShadedColor(wx,wy,true));
}
}
map.blit2x(TCODConsole::root,0,0);
TCODConsole::root->setDefaultForeground(TCODColor::white);
static const char *biomeNames[] = {
"Tundra","Cold desert","Grassland", "Boreal forest",
"Temperate forest", "Tropical/Montane forest",
"Hot desert", "Savanna", "Tropical dry forest", "Tropical evergreen forest",
"Thorn forest"
};
if ( worldGen.isOnSea(mx,my) ) {
// some information are irrelevant on sea
TCODConsole::root->print(5,47,"Alt %5dm\n\nMove the mouse to scroll the map",
(int)worldGen.getRealAltitude(mx,my)
);
} else {
TCODConsole::root->print(5,47,"Alt %5dm Prec %3dcm/sq. m/y Temp %d deg C\nBiome : %s\nMove the mouse to scroll the map",
(int)worldGen.getRealAltitude(mx,my),
(int)worldGen.getPrecipitations(mx,my),
(int)worldGen.getTemperature(mx,my),
biomeNames[worldGen.getBiome(mx,my)]
);
}
}
int main (int argc, char *argv[]) {
// initialize the game window
TCODConsole::initRoot(WIDTH,HEIGHT,VERSION, false,TCOD_RENDERER_SDL);
TCODSystem::setFps(25);
TCODMouse::showCursor(true);
TCOD_key_t k = {TCODK_NONE,0};
TCOD_mouse_t mouse;
bool endCredits=false;
// generate the world with all data (rain, temperature and so on...)
worldGen.generate(NULL);
// compute light intensity on ground (depends on light direction and ground slope)
static float lightDir[3] = {
1.0f,1.0f,0.0f
};
worldGen.computeSunLight(lightDir);
while (! TCODConsole::isWindowClosed()) {
// read keyboard
// TCOD_key_t k=TCODConsole::checkForKeypress(TCOD_KEY_PRESSED|TCOD_KEY_RELEASED);
// TCOD_mouse_t mouse=TCODMouse::getStatus();
TCODSystem::checkForEvent((TCOD_event_t)(TCOD_EVENT_KEY_PRESS|TCOD_EVENT_MOUSE),&k,&mouse);
if ( k.vk == TCODK_PRINTSCREEN ) {
// screenshot
if (! k.pressed ) TCODSystem::saveScreenshot(NULL);
k.vk=TCODK_NONE;
} else if ( k.lalt && (k.vk == TCODK_ENTER || k.vk == TCODK_KPENTER) ) {
// switch fullscreen
if (! k.pressed ) TCODConsole::setFullscreen(!TCODConsole::isFullscreen());
k.vk=TCODK_NONE;
}
// update the game
update(TCODSystem::getLastFrameLength(),k,mouse);
// render the game screen
render();
// render libtcod credits
if (! endCredits ) endCredits = TCODConsole::renderCredits(4,4,true);
// flush updates to screen
TCODConsole::root->flush();
}
return 0;
}