DevIL 윈도우에서 빌드하기

Posted at 2009/05/18 11:27// Posted in msvc
게임에서 잡다구리 이미지 포멧을 읽을때 DevIL 을 사용하고 있습니다.
몇년간 대규모 업데이트가 없어서 잊고 살다가...
쓰레드 모델 문제 때문에 소스를 다시 받아보려고 찾아가보니~
http://openil.sourceforge.net/

엄청 활발하게 활동하고 있는 것 같내요 -ㅁ-)/
윈도우 사용자를 위한 LibCompiled.zip 도 다시 지원하고 말이죠 햐햐 -ㅂ-

하지만 다운로드 소스는 윈도우 프로젝트 파일이 빠져있더군요 -_-;
요즘은 다들 SVN 저장소로 직접 다운로드 받기 때문인지 잘 관리가 안되는걸까요..

그래서 저도 SVN 저장소로 다운 받았습니다.
https://openil.svn.sourceforge.net/svnroot/openil/trunk/DevIL

윈도우는 의존성을 알아서 찾아야 하는데-_-;
매우 귀찮은 작업이므로 그냥 컴파일된 것도 받아서
http://downloads.sourceforge.net/openil/LibCompiled-vc8.zip

압축을 푼다음 src-IL/include 와 src-IL/lib 폴더에 복사해둡니다.

vc2005 솔류션은 projects/msvc8/ImageLib.sln 입니다.
src-IL 프로젝트 라이브러리 설정에 src-IL/lib 연결이 없으므로 연결해주시고요~

컴파일전에 include/config.h.win 을 include/config.h 로 이름을 변경하고 설정작업을
해줘야 합니다. 그냥 빌드하면 각종 라이브러리가 없다고 에러를 냅니다-_-


#define IL_NO_BLP
// #define IL_NO_BMP
#define IL_NO_CUT
#define IL_NO_CHEAD
#define IL_NO_DCX
// #define IL_NO_DDS
#define IL_NO_DICOM
#define IL_NO_DOOM
#define IL_NO_EXR
#define IL_NO_FITS
#define IL_NO_FTX
// #define IL_NO_GIF
// #define IL_NO_HDR
// #define IL_NO_ICO
#define IL_NO_ICNS
#define IL_NO_IWI
#define IL_NO_JP2
// #define IL_NO_JPG
#define IL_NO_LCMS
#define IL_NO_LIF
#define IL_NO_MDL
#define IL_NO_MNG
#define IL_NO_PCD
// #define IL_NO_PCX
#define IL_NO_PIC
#define IL_NO_PIX
// #define IL_NO_PNG
#define IL_NO_PNM
// #define IL_NO_PSD
// #define IL_NO_PSP
#define IL_NO_PXR
// #define IL_NO_RAW
#define IL_NO_ROT
#define IL_NO_SGI
#define IL_NO_SUN
// #define IL_NO_TGA
// #define IL_NO_TIF
#define IL_NO_TPL
#define IL_NO_WAL
#define IL_NO_WDP
#define IL_NO_XPM

// 중간 생략

//#undef ILUT_USE_DIRECTX8
#define ILUT_USE_DIRECTX9
//#define ILUT_USE_DIRECTX10
#define ILUT_USE_OPENGL
//#define ILUT_USE_SDL
#define ILUT_USE_WIN32


그냥 유명한 확장자 빼고는 전부 IL_NO_* 주석을 풀어주세요~
ILUT 플랫폼도 사용하고자하는 플랫폼만 남기고 주석처리합니다

컴파일하다보면 ilu_error.c 에서 다국어 에러 메시지 처리 때문에 에러를 내는데

#include "ilu_internal.h"
+#include "ilu_error/ilu_err-english.h"
+/*
#include "ilu_error/ilu_err-arabic.h"
#include "ilu_error/ilu_err-dutch.h"
-#include "ilu_error/ilu_err-english.h"
#include "ilu_error/ilu_err-french.h"
#include "ilu_error/ilu_err-german.h"
#include "ilu_error/ilu_err-italian.h"
#include "ilu_error/ilu_err-japanese.h"
#include "ilu_error/ilu_err-spanish.h"
+*/

-
ILconst_string *iluErrors;
ILconst_string *iluLibErrors;
ILconst_string *iluMiscErrors;
-#define ILU_NUM_LANGUAGES 8
+#define ILU_NUM_LANGUAGES 1

ILconst_string *iluErrorStrings[ILU_NUM_LANGUAGES] = {
iluErrorStringsEnglish,
+ /*
iluErrorStringsArabic,
iluErrorStringsDutch,
iluErrorStringsFrench,
@@ -36,10 +38,12 @@
iluErrorStringsSpanish,
iluErrorStringsGerman,
iluErrorStringsItalian
+ */
};

ILconst_string *iluLibErrorStrings[ILU_NUM_LANGUAGES] = {
iluLibErrorStringsEnglish,
+ /*
iluLibErrorStringsArabic,
iluLibErrorStringsDutch,
iluLibErrorStringsFrench,
@@ -47,10 +51,12 @@
iluLibErrorStringsSpanish,
iluLibErrorStringsGerman,
iluLibErrorStringsItalian
+ */
};

ILconst_string *iluMiscErrorStrings[ILU_NUM_LANGUAGES] = {
iluMiscErrorStringsEnglish,
+ /*
iluMiscErrorStringsArabic,
iluMiscErrorStringsDutch,
iluMiscErrorStringsFrench,
@@ -58,6 +64,7 @@
iluMiscErrorStringsSpanish,
iluMiscErrorStringsGerman,
iluMiscErrorStringsItalian
+ */

한글도 없고 귀찮으니 영어만 남기고 제거합니다.

~(-_-)~ 이제 사용하기만 하면 됩니다~ 짜잔~
이올린에 북마크하기(0) 이올린에 추천하기(0)
2009/05/18 11:27 2009/05/18 11:27
vc2005 로 빌드하다보면 DXSDK 나 BOOST 에서 잘못된 문자에 대한 아래와 같은 컴파일 경고가 발생한다.

../../../../boost/ref.hpp : warning C4819: 현재 코드 페이지(949)에서 표시할 수 없는 문자가 파일에 들어 있습니다. 데이터가 손실되지 않게 하려면 해당 파일을 유니코드 형식으로 저장하십시오.
../../../../boost/utility/enable_if.hpp : warning C4819: 현재 코드 페이지(949)에서 표시할 수 없는 문자가 파일에 들어 있습니다. 데이터가 손실되지 않게 하려면 해당 파일을 유니코드 형식으로 저장하십시오.
../../../../boost/python/ptr.hpp : warning C4819: 현재 코드 페이지(949)에서 표시할 수 없는 문자가 파일에 들어 있습니다. 데이터가 손실되지 않게 하려면 해당 파일을 유니코드 형식으로 저장하십시오.
../../../../boost/utility/enable_if.hpp : warning C4819: 현재 코드 페이지(949)에서 표시할 수 없는 문자가 파일에 들어 있습니다. 데이터가 손실되지 않게 하려면 해당 파일을 유니코드 형식으로 저장하십시오.

헤더파일안에 latin1 로 인코딩된 문자가 있을때 발생하며 이런 경우 아래와 같은 파이썬 스크립트를 이용해 utf8 로 변환해주면 경고 메시지를 안 볼 수 있다.

import
os
import stat

def FindFilesByExt(ext, path):
    if path[-1] != os.sep:
        path += os.sep

    ext = ext.lower()

    retList = []
    for name in os.listdir(path):
        if stat.S_ISDIR(os.stat(path + name).st_mode):
            retList += FindFilesByExt(ext, path + name)
        else:
            if name[-len(ext):].lower() == ext:
                retList.append(path + name)

    return retList

for name in FindFilesByExt(".hpp", "."):
    print name
    src = open(name).read()
    open(name, "w").write(src.decode("latin1").encode("utf8"))
이올린에 북마크하기(0) 이올린에 추천하기(0)
2007/07/11 20:50 2007/07/11 20:50
아래 링크에러가 발생하면 stdafx.cpp 에 해당하는 라이브러리를 연결시킨다.


more..


#pragma comment(lib, "DxErr9.lib")

---------------------------------

more..



#pragma comment(lib, "dxguid.lib")

---------------------------------

more..


#pragma comment(lib, "shell32.lib")

---------------------------------

more..


#pragma comment(lib, "comctl32.lib")

---------------------------------

more..


#pragma comment(lib, "gdi32.lib")

---------------------------------

more..



#pragma comment(lib, "user32.lib")
이올린에 북마크하기(0) 이올린에 추천하기(0)
2007/05/15 13:42 2007/05/15 13:42
독일에서 3일전에 편지가 왔다-_-

This happens sometimes during normal gaming.

This happens ALWAYS in the following situations:

- when starting the client for the first time after logging-in

- when starting the client immediately again (the second time): after selecting empire

- next time after creating the character

(= so at the beginning, the client finishes himself off 3 times, and only with the 4th attempt, the player can really access the game)

This also happens ALWAYS in the following situations:

          - when keying in wrong login-data in login-window

          - when trying to go to login-window from in-game

         -  when trying to go to character selection window from in-game


ALWAYS 의 압박 orz;;

독일버전은 잘 실행되는데 이탈리어 버전에서만
로그인후 캐릭터 선택화면에서 게임 실행될때, 혹은 로그아웃 후 캐릭터 선택할때만
클라이언트가 죽는다는 것이었다.

하지만 한국어 윈도우에서는 문제가 없었다 (-_-); 그렇게 하루가 흘러가고...

영문 윈도우를 설치해 실행해보았지만 이상무;
이탈리어어로 설정해도 마찬가지였다.

결국 영문 윈도우에서 AppLocale 을 설치하고, 현재 지역 위치도 이탈리아로 설정하자
겨우 에러 상황을 재현해낼 수 있었다. 한번 에러가 발생하니 AppLocale 이 없어도
에러가 항상 발생하는 행운까지 GET! -_-)!

하지만 회사 개발 컴파일러인 vc 6.0 디버그 버전에서는 에러가 나지 않는 절망의 상황 T_T);
( 게임 컴파일은 꽁짜 컴파일러 visual c++ .net 2003 toolkit 를 사용중이라 IDE 디버깅 불가 )

결국 원점으로 돌아와 -_-
릴리즈 버전 에러 리포팅 정보를 분석하기 시작했다.

Exception Type: 0xc0000005

eax: 0x0012caa8 ebx: 0x0012caa4
ecx: 0x00181a9b edx: 0x00617475
esi: 0x1c6e3000 edi: 0x34ef0a28
ebp: 0x0012c3bc esp: 0x0012c3b0

0x00403fc4  game - std::string.assign
0x0044c277  game - LoadSkillDesc
0x0046c60b  game - LoadLocaleData
0x0046f741  game
0x1e04cf4c  python22.dll
0x8d0c4d8b

흠 (-_-); std::string assign 이 에러날리는 없으므로 스킬 데이터를 로딩하다가
메모리가 깨진 현상인건 틀림없다. 지난번에 수정한 lower 함수 부분일까도 의심해봤지만
해당 코드에서는 사용되고 있지 않았다.

에러나는 라인이나 로그로 찍어보자

라고 코딩해보니 -_-); 에러 위치는 마지막 라인...
게다가 알수없는 스킬 번호라는 문구까지 보이는게 아닌가

코드를 다시 살펴보니 흑흑

for (int linePos = 0; linePos != lineCount; ++linePos)
{
     if (!SplitLines(lines[linePos], &tokenVector))
        continue;
 
     vnum = atoi(tokenVector[SKILLDESC_VNUM]);

     ... 어쩌구 ...

     tokenVector[SKILLDESC_VAL] 저쩌구 ..
    
}

이런식으로 되어있는걸 발견 (-_-);

vector 각 요소에 접근하는데, 최대 길이 체크도 안하고 과감하게 직접 접근하는 코드들이
대범하게 나열되어있는것이 아닌가 T_T);

일단은 각 요소가 일정개수 이하일때는 공백라인으로 에러 로그 남기고 건너뛰도록
응급조치 종료 _ -_)~

-----------------------------------------

텍스트 파일을 파싱할때는 아래 체크 과정을 거치는 것이 좋다

for line in lines:
    line = line.strip()
    if not line: # 공백 라인 체크
        continue
    tokens = line.split("\t")
    if len(tokens) < TOKEN_COUNT: # 토큰 개수 체크
        continue

    tokens[pos] # 접근




이올린에 북마크하기(0) 이올린에 추천하기(0)
2007/05/09 17:46 2007/05/09 17:46

visual c++ 리모트 디버깅

Posted at 2007/05/09 16:28// Posted in msvc
www.kgda.or.kr/cgi/technote/ read.cgi?board=program02&y_number=297

대상 컴퓨터 작업
0. 첨부 파일 다운로드

리모트 디버깅


1. 첨부된 파일 실행 파일을 실행한다.
2. Setting을 눌러 소스 컴퓨터의 주소를 적는다
3. Connect 버튼을 누르고 대기한다

소스 컴퓨터 작업
1. Build->Debugger Remote Connection 실행
2. Network(TCP/IP)를 선택하고 Settings 를 눌러 대상 컴퓨터 주소를 적는다.
3. Project Setting 에서
Working Directory에는 대상 컴퓨터에서 실행될 폴더 주소를
Remote excutable path and filename: 에 대상 컴퓨터에서 실행될 파일의
전체경로(디스크이름을 포함한..)를 적는다
4. 컴파일
5. 파일을 대상 컴퓨터에 복사한다
6. 실행

http://www.myevan.net/phpBB/viewtopic.php?t=1929&highlight=remote


안녕하세요. 매크로 없는 메비~랍니다.

리모트 디버깅 팁 몇가지를 적어봅니다.

일단 파일을 다운로드 할 필요없이 VC++이 깔린 PC에서 다음 파일들을 복사해서 한 폴더에 넣고 사용하비면 됩니다. Help 문서에서도 찾을 수 있지만 간혹 버젼이 틀리거나 하면 낭패이므로 참고하기 바랍니다.

DM.DLL
MSDIS110.DLL
MSVCMON.EXE
MSVCP60.DLL
MSVCRT.DLL
PSAPI.DLL
TLN0T.DLL

디버깅을 할때 실행 폴더와 실행파일 경로등이 항상 문제가 됩니다. 빌드한 실행파일의 timestamp 등을 체크하기 때문에 버젼이 틀리면 경고를 해주면 여로모로 귀찮습니다. 특히 리모트 파일의 실행 폴더가 로컬 파일과 같은 주소로 사용되기 때문에 로컬에서 쓰다가 리모트에서 쓰고 왔다갔다 하려면 프로젝트 셋팅을 매번 바꿔줘야 하는 경우가 있습니다.

이럴때는 두가지 방법이 있는데 다음과 같습니다.

1) 리모트 머신도 로컬과 동일한 폴더/드라이브명을 갖게 한다.

동일한 폴더 셋팅은 프로젝트의 Post-Process 에 간단한 copy 명령등을 추가해서 리모트 머신의 특정 폴더에 빌드가 끝난 exe 파일과 pdb 파일들을 자동적으로 복사하게 해주는 것입니다. 이는 매번 컴파일이 끝날때마다 자동적으로 이뤄지고 리모트 컴퓨터에 공유폴더만 정상적으로 작동하면 언제나 사용할 수 있십니다.

2) 동일한 공유 폴더를 이용한다.

먼저 작업할 폴더를 공유폴더로 설정합니다. 그리고 해당 공유 폴더를 특정 드라이브에 맵핑합니다. 가령 \\kwonil\TestCode 란 폴더가 공유되어 있으면 x: 드라이브에 \\kwonil\TestCode를 공유시킵니다. 그리고 VC++에서 작업을 할때는 모든 작업이 x: 드라이브에서 작업할 수 있게 해둡니다. 보통 프로젝트 폴더를 공유하지 않고 워킹 폴더(게임 폴더)를 공유해놓고 빌드되는 실행파일의 타겟 경로를 게임 폴더로 해놓는 것도 좋은 방법이죠. 그리고 다음 작업은 리모트 머신에서 같은 드라이브 즉 x: 드라이브에 \\kwonil\TestCode를 공유해주는 것이죠. 그러면 리모트 머신도 로컬 머신도 동일한 경로(x:)에서 모든 것이 돌아가기 때문에 모든 작업이 깔끔하게 끝납니다.

개인적으로 1)을 선호했는데 뭣보다 안정적이고 공유폴더보다 속도가 좋기 때문이죠. 이것저것 자료가 자주 바뀌거나 로컬과 리모트에서 공유를 열어줘야할 필요가 꼭 있을때는 2)도 좋지만 저는 1)을 써서 계속 작업을 했었습니다. 매번 손으로 복사해주는거 매우 불편하니까 Post-Process에 한줄만 추가해주면 되죠. copy~~ 명령으로 말이죠. ^_^ 리모트 디버깅은 풀스크린 모드로 작업할때, 특정 환경을 구축해서 테스트할때 매우매우매우 우용하다고 생각합니다. 저는 로컬라이즈 작업을 처음부터 저렇게 해왔고 리모트 머신에 OS를 여러개 Ghost 이미지로 만들어서 매번 바꿔가면서 리모트 디버깅으로 작업을 하곤 했었죠. 그래서 하루에 OS 10개를 사용한(언어, 버젼별) 테스트도 가능했습니다. ^_^
이올린에 북마크하기(0) 이올린에 추천하기(0)
2007/05/09 16:28 2007/05/09 16:28