2010년 1월 30일 토요일

mercurial, 로컬에서만 ignore 하기

필요없는 파일은 맞는데 .hgignore 에 넣기는 후달릴때 쓰는 방법
참고 에 소개되어있다. hg st 때렸을때 깔끔하게 프롬프트만 떨어지게 하고 쓰자. 무시하고 살다보면 add 를 까먹기도 한다.


워킹카피내의 .hg/hgrc 에 아래내용 추가하고 hgignore 작성하면 끝.

[ui]
ignore = /path/to/repo/.hg/hgignore



2010년 1월 27일 수요일

어라 코드하이라이트 지원하네

환경설정 보다 알았네
그런데 지원언어가 많지 않다.

음.. 그냥 지금처럼 emacs 에서 html 뽑아서 붙이는쪽이 끌리는데..
어쨌건 기억해 두자.

여태껏 집에서 돌리던 리파지토리 서버를 내리고 드랍박스에서 리파지토리를 돌리고 있어서 전처럼 필요할때 집에 로그인해서 코드를 꺼내가기 힘들어졌으니 앞으로 코드조각들을 블로그에 올려둬야 할 판인데 자주 써먹게되겠군.


오우거 시작코드를 스크래치부터 짜보고 있는데 그 코드 올려본다.

[code cpp]
/*
  흠. 외부데이타를 읽을게 많아서 초기기동이 상당히 성가시다.
  setupResourceLocations() 함수를 참고해보자.
*/
#include <iostream>
#include <string>
#include "Ogre.h"

using namespace std;
using namespace Ogre;


class MyFrameListener : public FrameListener
{
public:
    virtual bool frameStarted(const FrameEvent& e)
    {
        return true;
    }
    virtual bool frameEnded(const FrameEvent& e)
    {
        return true;
    }
};


class OgreApp
{
public:
    OgreApp()
    {
        setupLog();
        setupRoot();
        setupRenderWindow();
        setupSceneManager();
        setupCamera();
        setupViewport();
        setupResourceLocations();
        createScene();
    }
   
    virtual ~OgreApp()
    {
        delete root_;
        delete logMgr_;
    }

    void run()
    {
        while(true)
        {
            if(!root_->renderOneFrame())
                break;
            messageLoop();
        }
    }

    void addFrameListener(FrameListener* fl)
    {
        root_->addFrameListener(fl);
    }

private:
    LogManager*   logMgr_;
    Root*         root_;
    RenderWindow* window_;
    SceneManager* sceneMgr_;
    Camera*       cam_;
    Viewport*     vp_;


    void setupLog()
    {
        logMgr_ = new LogManager;
        LogManager::getSingleton().createLog("ogre.log", true, true, false);
        logMgr_->setLogDetail(LL_BOREME);
    }

    void setupRoot()
    {
        root_ = new Root("", "");
        loadPlugin("RenderSystem_Direct3D9");
        loadPlugin("Plugin_OctreeSceneManager");           
        root_->setRenderSystem(*root_->getAvailableRenderers()->begin());
        root_->initialise(false);
    }
    void loadPlugin(const char* name)
    {
        string n = name;
#if _DEBUG
        n += "_d";
#endif
        root_->loadPlugin(n);
    }
    void setupRenderWindow()
    {
        root_->getRenderSystem()->setConfigOption("Full Screen", "No");
        root_->getRenderSystem()->setConfigOption("Video Mode", "1024 x 768 @ 32-bit colour");
        window_ = root_->createRenderWindow("Manual Ogre Window", 1024, 768, false, 0);
    }
    void setupSceneManager()
    {
        sceneMgr_ = root_->createSceneManager(ST_GENERIC, "MySceneManager");
    }

    void setupCamera()
    {
        cam_ = sceneMgr_->createCamera("MainCam");
        // Z 방향으로 500 거리에 카메라 위치
        cam_->setPosition(Vector3(0,0,500));
        // Z 쪽으로 향하게
        cam_->lookAt(Vector3(0,0,-300));
        cam_->setAspectRatio(1.33333f);
        cam_->setNearClipDistance(5);
        cam_->setFarClipDistance(1000);
    }
    void setupViewport()
    {
        vp_ = window_->addViewport(cam_);
        vp_->setBackgroundColour(ColourValue(0,0,0));
    }
    void setupResourceLocations()
    {
        //addResourceLocation("/packs/OgreCore.zip", "Zip", "Boostrap");
        addResourceLocation("/materials/programs", "FileSystem", "General");
        addResourceLocation("/materials/scripts", "FileSystem", "General");
        addResourceLocation("/materials/textures", "FileSystem", "General");
        addResourceLocation("/models", "FileSystem", "General");
        ResourceGroupManager::getSingleton().initialiseAllResourceGroups(); // 그룹별로 초기화도 가능하다 기억해두자.
    }
    void addResourceLocation(const char* name, const char* type, const char* group)
    {
        const char* ogrehome = getenv("OGRE_HOME");
        if(!ogrehome) throw runtime_error("need OGRE_HOME env");

        ResourceGroupManager::getSingleton().addResourceLocation(string(ogrehome) + "/media" + name,
                                                                 type,
                                                                 group);       
    }
    void createScene()
    {
        sceneMgr_->setAmbientLight(ColourValue(0.5,0.5,0.5));
        Light* l = sceneMgr_->createLight("MainLight");
        l->setPosition(20,80,50);
        Entity* ent = sceneMgr_->createEntity("head", "ogrehead.mesh");
        //ent->setMaterialName("Examples/EnvMappedRustySteel");
        sceneMgr_->getRootSceneNode()->createChildSceneNode()->attachObject(ent);
    }

    void messageLoop()
    {
        MSG msg;
        while(PeekMessage(&msg, NULL, 0, 0,  PM_REMOVE))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
};




int main()
{
    MyFrameListener fl;
   
    OgreApp app;
    app.addFrameListener(&fl);
    app.run();
}
[/code]

2010년 1월 26일 화요일

s7, 간단한 scheme 구현

https://ccrma.stanford.edu/software/snd/snd/s7.html
https://ccrma.stanford.edu/software/snd/

http://www.reddit.com/r/programming/comments/arvdl/choosing_a_game_scripting_language/

중 s7 언급을 보고 알았다.
다음에 스크립트 올릴일 있으면 tinyscheme 말고 이놈 한번 써보자.

후에 이게 기억나길..

2010년 1월 25일 월요일

무료 웹하드류 서비스에 mercurial 리파지토리 올리는 시도중

흠. 집에 항상 켜두는 PC 가 있어서 거기 colinux 를 깔고 hg 서버로 활용했는데 이제 그렇게 쓰기 힘들게 됐다. 그래서 전부터 생각해오던 몇가지 대안을 테스트중.

1. 유료 웹호스팅 활용.
몇몇 호스팅의 경우 계정에 hg 설치가 가능해서.. 충분히 써먹을수 있지만 난 돈이 없다.

2. svn, hg 무료 호스팅 서비스
용량 작거나 라이센스 제한.

3. N 드라이브
네이버 서비스인데, 드라이브가 N 으로 잡혀서 콘솔에서 쓰기 쉬운게 매력적.. 이라고 생각했었지만 hg clone 부터 실패하더라. 흠. 제길슨.

4. 드랍박스
헐 이미 다른용도로 용량을 거의 다 쓰고 있어서.. 그리고 무료계정은 2기가를 주는데 그다지 넉넉치 못하다. 그래도 가장 나아보인다.

5. 라이브메쉬
현재 라이브메쉬로 hg 리파지토리 폴더를 동기화중.. 느리고 동기화가 얼마나 진행됐는지 알기 어려운데.. 흠 달리 대안이 없으니 일단 이걸 써볼 예정. 하지만 리눅스 미지원때문에
오래 쓰진 못할것같다.



으음.. 전에 S3 에 리파지토리 올리는거 찾아보다가 말았는데 다시 뒤져보자.
유료라 쓰진 않겠지만..

아.. skydrive 도 한번 고려해보자.. 이쪽은 서드파티 클라이언트들을 좀 뒤져봐야 겠다.



2010/01/26
흠 mesh 는 좀 요상하네. 분명 수정을 했는데 싱크가 되지 않고 있더라.. 음.. 5G 는 매력적인데 어차피 리눅 미지원이니 별 고민없이 드랍박스로 세팅했다. 현재 드랍박스에 동기화중.
존내 느린건 마찬가지...
언제 짬내서 보너스용량 받아 챙겨야겠다.
https://www.dropbox.com/referrals/NTEyOTUzMjE5
적어둬야지..


2010/02/02
push 중 lock 됐다는 에러가 뜨던데 이글을 참고하여 .hg/store/lock 을 지워버렸다.
흠. 집에서 PC 를 끌때 동기화가 잘 안된건가???



2010년 1월 21일 목요일

boost asio 를 이용 serialport 로 테스트용 바이트시퀀스를 줄줄이 싸봤다.

보드쪽에서 시리얼 읽는게 좀 이상하길래 만들어본 테스트 코드.

처음엔 haskell 로 짰는데( serialport 라고, haskell 에서 win32 시리얼 포트를 지원하는 라이브러리가 나온게 본기억이 나서 ) ㅋㅋㅋ 잘 안되더라. send 가 묘하게 느리던데.. 업무상 필요한 작업이라 삽질 그만두고 바로 C++ 로 짜버렸다.

테스트한 시나리오가.. C++ 로 0x00 부터 0xFF 를 줄기차게 날리고 보드쪽에서 매번 한바이트읽을때마다 기존 값하고 1 차이나는지 비교한.. 단순히 한방향 통신만 하는 코드라서 시리얼포트에서 읽거나 하는 코드는 들어있지 않다.

뭐 사실 그냥 asio 사용하고 다를거하나 없고 set_option 의 사용법 정도나 봐두면 되겠다.



#include <boost/asio.hpp>
#include <exception>
#include <iostream>

using namespace std;


int main()
{
try
{
boost::asio::io_service io_service;

// 시리얼포트 열고
boost::asio::serial_port s(io_service, "COM4");
boost::asio::serial_port::baud_rate baud_rate(9600);
s.set_option(baud_rate);

boost::asio::deadline_timer t(io_service);
unsigned char buf[1] = {0};

while(true)
{
// 한바이트씩 보내자
s.write_some(boost::asio::buffer(buf, sizeof(buf)));
cout << static_cast<unsigned int>(buf[0]) << endl;

// 0x00 부터 0xFF 까지 보내면 되겠지.
buf[0]++;

// 잠시 쉬자.
t.expires_from_now(boost::posix_time::milliseconds(5));
t.wait();
}


io_service.run();
}
catch(exception& e)
{
cerr << e.what() << endl;
}
}

2010년 1월 18일 월요일

cmake, 실행하는데 여러 파일이 필요한놈한테 파일 모아주기

퇴원후 첫글이네 흠.

ogre 1.6 을 구경하고있는데 이게 빌드후 실행시 여려가지 dll 하고 리소스 들이 필요하더라.
리소스는 복사하긴 좀 덩치가 커서 코드내에서 $OGRE_HOME 을 기준으로 찾게했고 ( 보통 cfg 를 쓰도록 구성되어있는데 이건 내취향이 아니다. 적어도 샘플수준 코드라면 이런저런 파일을 들고다니는건 귀찮기만 할 뿐. 코드에 박는게 속편하다.) 그외 dll 들은 적당히 복사를 해서 쓰도록 했다.

어쨌건 정리해두면 먼저 exe, dll 들이 모이는 디렉토리를 만들고 cmake 가 만드는 출력을 이쪽으로 돌렸다. 아.. ogre 쪽 dll 도 복사하도록 추가했다.

file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/out)
set_output_dir(${CMAKE_BINARY_DIR}/out)
copy_ogre_dlls(${CMAKE_BINARY_DIR}/out)

위에서 아래두줄은 내가만든 매크로.. 소스는 요렇다.

# 컴파일 결과를 한곳으로.
# cmake 로 dll 들을 서브프로젝트로 만들경우 exe 와 다른 디렉토리에 떨어져 불편하니 이걸 써먹자.
# 예)
# set_output_dir(${CMAKE_BINARY_DIR}/out)
macro(set_output_dir dir)
  set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${dir} CACHE PATH "Single Directory for all Libraries")
  set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${dir} CACHE PATH "Single Directory for all Executables")
  set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${dir} CACHE PATH "Single Directory for all static libraries")
endmacro(set_output_dir dir)

macro(filecopy src dst)
  configure_file("${src}" "${dst}" COPYONLY)
endmacro(filecopy src dst)

macro(copy_ogre_dlls dir)
  if(CMAKE_BUILD_TYPE MATCHES Debug)
    filecopy("${OGRE_HOME}/bin/debug/OgreMain_d.dll" "${dir}")
    filecopy("${OGRE_HOME}/bin/debug/RenderSystem_Direct3D9_d.dll" "${dir}")
    filecopy("${OGRE_HOME}/bin/debug/Plugin_OctreeSceneManager_d.dll" "${dir}")
    filecopy("${OGRE_HOME}/bin/debug/OIS_d.dll" "${dir}")   
  else()
    filecopy("${OGRE_HOME}/bin/release/OgreMain.dll" "${dir}")
    filecopy("${OGRE_HOME}/bin/release/RenderSystem_Direct3D9.dll" "${dir}")  
    filecopy("${OGRE_HOME}/bin/release/Plugin_OctreeSceneManager.dll" "${dir}")
    filecopy("${OGRE_HOME}/bin/release/OIS.dll" "${dir}")
  endif()
endmacro(copy_ogre_dlls dir)

흠, 참고로 ogre 샘플제작을 편하게 하려고 만든 매크로도 걍 적어둔다..

macro(link_ogre3d target)
  if(CMAKE_BUILD_TYPE MATCHES Debug)
    target_link_libraries("${target}" OgreMain_d OIS_d)
  else()
    target_link_libraries("${target}" OgreMain OIS)
  endif() 
endmacro(link_ogre3d target)

macro(link_ogre3d_all)
  if(CMAKE_BUILD_TYPE MATCHES Debug)
    link_libraries("${target}" OgreMain_d OIS_d)
  else()
    link_libraries("${target}" OgreMain OIS)
  endif() 
endmacro(link_ogre3d_all)



흠 추가로, 원래 configure_file 을 쓰지 않고 cmake -E 를 써보려고 했는데 그쪽은 좀 성가셔서 하다 말았다. configure_file 은 cmake 가 실행되는 시점에 복사를 하는거라 흠.. 정확히 내가 원하는 동작은 아닌데.. 뭐 별수없지.


아.. ogre 에 대해서도 좀 적어둔다.
흠 3D 는 전혀 모르지만 접근하는데 큰 무리는 없더라. 물론 3D 를 모르니 의미없는 접근이지만. 어쨌건 예제들이 간단한 프레임웍들을 끼고있어서 scratch 에서부터 시작하는게 좀 짜증났다. cfg 등을 남발하는 구조도 초기접근시 좀 더러웠고.