기어2S의 Watchface 제작

(본문 내용은 추후에 넣을 예정)

Tizen 2.3.1 SDK의 wearable profile에는 Watchface App이라는 app 타입을 만들 수 있다.

<<Watchface app으로 등록>>
사용자 삽입 이미지


























<<일반 상태의 시간 출력>>
사용자 삽입 이미지


























<<Ambient 모드의 시간 출력>>
사용자 삽입 이미지


























만드는 방법은 다음의 소스를 참고하면 된다.
smwatch_151005a.7z

다운로드 (451K)



Posted by 안영기

2015/10/05 23:36 2015/10/05 23:36
Response
0 Trackbacks , 0 Comments
RSS :
http://smgal.ismine.net/tc_191/blog1/rss/response/48

Trackback URL : 이 글에는 트랙백을 보낼 수 없습니다

C++11의 UTF-8, UTF-16, UTF-32 표기법

회사 일을 하면서, 사람들에게 설명을 해 줘도 또 다시 물어 보고 또 물어 보고 하는 것 중에 하나가 '문자 인코딩'이다. 지금은 예전과는 달리 거의 유니 코드로 통일이 되었기 때문에 그나마 많은 비교 설명을 할 필요까지는 없다. 하지만, 그대신에 유니 코드를 표기하는 방법 자체에 대해서는 질문이 많은 편이다.
 
UCS-2, UCS-4, UTF-8, UTF-16, UTF-32 등에 대한 자료가 인터넷에는 널려서 이해를 한다 하더라도, IDE에서 소스를 만드기 위해 사용되는 문자 인코딩, 그 안에서 글자를 출력하기 위한 문자 인코딩, 그리고 실제 그것이 C 코드에 버퍼로 적용되었을 때의 인코딩이 각각 다를 수 있다는 것을 이해 시키기는 아주 힘들다.
 
const char* str = "가나다"
-> VC++에서, 소스는 KSC-5601의 코드로 표현될 수 있고 실제 실행 버퍼에서도 KSC-5601일 수 있다.
-> VC++에서, 소스는 UCS-2의 코드로 표현될 수 있고 실제 실행 버퍼에서는 KSC-5601일 수 있다.
-> Ubuntu vi에서, 소스는 UTF-8의 코드로 표현될 수 있고 실제 실행 버퍼에서는 UTF-8일 수 있다.
 
const wchar_t* str = L"가나다"
-> VC++에서, 소스는 KSC-5601의 코드로 표현될 수 있고 실제 실행 버퍼에서도 UCS-2일 수 있다.
-> VC++에서, 소스는 UCS-2의 코드로 표현될 수 있고 실제 실행 버퍼에서는 UCS-2일 수 있다.
-> Ubuntu vi에서, 소스는 UTF-8의 코드로 표현될 수 있고 실제 실행 버퍼에서는 UTF-32일 수 있다.
 
위의 예를 실제 하나식 돌려 보고 디버거로 버퍼 상태를 본 것은 아니지만, 하여간 위와 같은 상황이 될 수 있다는 것에 대해서 설명하는 것은 아주 힘들다. 특히 OS를 건너 뛰며 코드를 복사를 해 와서 생긴 문제를 가지고 왔을 때는, 그 상황을 설명하려면 더 힘들다.
 
그런데 C++11 표준에서는 ""와 L""로 구분하던 버퍼 문자열의 문자 인코딩 표기법이 좀 더 세분화 되었다.
 
const char* str = u8"가나다";
const char16_t* str = u"가나다";
const char32_t* str = U"가나다";
 
와 같이, 각각 UTF-8, UTF-16, UTF-32 에 대한 표기법이 구체적으로 생겨났다. 이제는 컴파일러별로 그 크기나 문자 인코딩이 다를 수 있었던 wchar_t 에서 벗어나, 좀 더 명확하게 버퍼 문자열의 문자 인코딩을 지정할 수 있는 방법이 생긴 것이다.
 

Posted by 안영기

2015/03/22 21:34 2015/03/22 21:34
Response
0 Trackbacks , 0 Comments
RSS :
http://smgal.ismine.net/tc_191/blog1/rss/response/47

Trackback URL : 이 글에는 트랙백을 보낼 수 없습니다

동급생2 맵출력 샘플 (Tizen 2.3 ver.)

이전에 Android NDK로 만든 것을 동일한 소스를 이용해 Tizen에서 구동하게 만들었다.
Tizen 2.3 에서 테스트 되었으며 일반적인 방법으로 import 를 하면 된다.

- 게임은 1995~6년도의 원작의 resource를 그대로 사용
  (ELF사에 저작권이 있는 부분입임)
- Cairo를 사용하여 scalability 구현
- 터치 입력을 추가, 스크린의 4 방향의 가장자리를 누르면 유이가 움직임

사용자 삽입 이미지

Tizen 2.3용 동급생 2 맵 출력 샘플 (88.7K)

Posted by 안영기

2014/11/23 01:59 2014/11/23 01:59
Response
0 Trackbacks , 0 Comments
RSS :
http://smgal.ismine.net/tc_191/blog1/rss/response/46

Trackback URL : 이 글에는 트랙백을 보낼 수 없습니다

대변 파이터 (Tizen 이식作)

이번에는 DOS -> Windows -> WIZ -> CANNOO -> bada 를 거쳐 Tizen 플랫폼에도 대변 파이터를 이식해 보았다.


Tizen용 대변 파이터 (522K)

Posted by 안영기

2013/06/02 22:33 2013/06/02 22:33
Response
0 Trackbacks , 2 Comments
RSS :
http://smgal.ismine.net/tc_191/blog1/rss/response/45

Trackback URL : 이 글에는 트랙백을 보낼 수 없습니다

동급생2 맵출력 샘플 (android ver.)

이전에 bada로 만든 것을 동일한 소스를 이용해 Android에서 구동하게 만들었다.

android-ndk-r8b 에서 테스트 되었으며 일반적인 NDK 샘플인 것처럼 import 를 하면 된다.


- 게임은 1995~6년도의 원작의 resource를 그대로 사용
  (ELF사에 저작권이 있는 부분입임)
- 당시 4-bit용 게임이었으므로 GetCanvasN()의 포맷인 ARGB8888로 리소스를 변경
- 터치 입력을 추가, 스크린의 4 방향의 가장자리를 누르면 유이가 움직임

Android용 동급생 2 맵 출력 샘플 (182K)

Posted by 안영기

2012/11/18 06:56 2012/11/18 06:56
Response
0 Trackbacks , 2 Comments
RSS :
http://smgal.ismine.net/tc_191/blog1/rss/response/44

Trackback URL : 이 글에는 트랙백을 보낼 수 없습니다

API의 deprecate 방법

어제 API 관련된 스펙 논의를 하다가 다음과 같은 조건의 해결 방법에 대한 논의가 있었다.
(내용을 핵심만 간략하게 정리한 것)


class IObject
{
};

void RegisterObject(const IObject& obj)
{
}

위와 같은 형태의 API가 기존에 있었을 때, 이 API의 파라미터를 IObject* 로 받도록 바꾸고 싶지만 기존에 이미 만들어진 코드도 제대로 빌드되고 정상 동작하게 하려면 어떻게 해야 하는가?

물론 C 적으로는 다음과 같은 방법이 있을 수 있다.

void RegisterObject(const IObject& obj) __attribute__((deprecated)); // __declspec(deprecated)

void RegisterObject(const IObject& obj)
{
}

void RegisterObject(IObject* obj)
{
}


그리고  나의 경우는 다음과 같은 의견을 내었다.

template <typename T>
struct ParamAdaptor
{
inline ParamAdaptor(const T& obj)
: param(const_cast<T*>(&obj))
{
}

inline ParamAdaptor(T* obj)
: param(obj)
{
}

T* param;
};
class IObject
{
}

void RegisterObject(ParamAdaptor<IObject> objAdaptor)
{
}


이렇게 만들게 되면 다음의 코드가 모두 정상적으로 동작한다.

IObject obj1;
RegisterObject(obj1);
RegisterObject(&obj1);

IObject* obj2 = new IObject;
RegisterObject(*obj2);
RegisterObject(obj2);


물론 이것은 아이디어일뿐, API 사용자가 이 API를 사용할 때 헤더의 선언과의 괴리를 느끼게 되므로 이 방법이 채택되지는 않았다.

Posted by 안영기

2012/08/25 11:10 2012/08/25 11:10
Response
0 Trackbacks , 1 Comments
RSS :
http://smgal.ismine.net/tc_191/blog1/rss/response/43

Trackback URL : 이 글에는 트랙백을 보낼 수 없습니다

가독성(readability)에 대한 결정

지금 진행하는 프로젝트의 coding idiom에는 가독성(readability)에 대한 부분이 정의되어 있다.


많은 사람들이 관리해야 할 코드에는 가독성이 필요하다는 것에는 의문이 없다. 하지만 무엇이 더 가독성이 좋은가에 대한 의견에는 의문이 많다.


 


1. if 문 뒤에 딱 한 라인이 올 때의 처리


(1) if (cond) 

       return false;


(2) if (cond) 

    {

        return false;

    }


위의 둘 중에 무엇을 택해야 하는 가에는 항상 논란이 많았다. (1)안을 택하게 되면 2개의 라인으로 내용을 모두 볼 수 있다는 장점이 있고 (2)안의 경우에는 indentation에 대한 예외를 두지 않는 규칙이라는 장점이 있다. (코딩에 실수를 할 우려가 있다 등등은 하수를 위한 것이므로 논외) 


현재 내가 진행하는 과제에서는 (2)안이 채택되어 있지만 나는 (1)안을 주장했다. 가독성의 가장 큰 장점이 빨리 코드를 파악해야 한다는 것인데 (1)안처럼 쓰면 한 눈에 코드 2-(2)안을 쓰면 화면 아래에 있을-을 더 볼 수 있다는 장점이 있기 때문이다 

 

 


2. 가로로 긴 줄을 잘라서 개행하기


(1) 가로로 라인이 길어도 개행 하지 않기. 


(2) 128자 등의 기준을 두고 기준 라인이 넘을 경우 개행 권고 


이것도 논란이 많은 이슈 중에 하나다. Linux 쪽의 유명한 사람은 아예 길게 코드를 짤 수 없게 하라는 말도 하였으나 현실과는 좀 맞지 않고, 최근에는 변수 이름을 길게 쓰거나 template을 파라미터로 쓰고 있기 때문에 가로줄이 계속 길어지고 있다.


현재는 가로로 스크롤을 하지 않고도 모든 코드를 다 볼 수 있는 (2)안이 채택되어 있으나 나는 (1)안을 주장하였다. (2)안을 쓰면 코드가 바뀔 때마다 개행 해야 하는 위치를 바꿔야 하는 것이 불편한데다가, 가로로 긴 코드를 실제로 끝까지 봐야 할 일은 거의 없다는 이유에서다.


가로로 줄이 길게 나오려면 주로 파라미터가 많거나 파라미터를 표시하는 방법이 길다는 것인데, 보통 코드를 분석할 때는 앞의 함수 이름을 보고 내가 관심이 있을 때만 뒤의 파라미터까지 보는 것이 대부분이라 나는 (1)안이어도 문제가 없다는 생각이다. 


 


3. 매크로에 대한 것


(1) 매크로가 유리할 때는 써야 한다.


(2) 매크로는 최대한 쓰지 말자. 


이 주제는 goto를 써야 하나 말아야 하냐의 오랜 주제처럼 의견이 많은 내용이다. 하지만 회사의 프로젝트에는 나름대로의 규칙이 존재해야 하기 때문에 이것에 대한 결론도 내어야 하였다. 결론은(2)안이 채택되었으나 나는 아주 예전부터 이것에 관해서는 (1)안을 주장해 왔다. C++ 책에 보면 매크로를 잘 못 썼을 때의 폐혜를 나열하면서 inline template으로 만들라고 한다. 하지만 그것은 매크로를 잘 못 짜거나 잘 못 사용한 경우에 대한 것이므로 제대로 만들었을 때는 문제가 없다는 것이다. 사실 규칙이 (2)안으로 정해졌기 때문에 나도 매크로를 inline template으로 바꾸는 작업을 하였는데, 주로 한 일이 1줄 짜리 매크로를 동일한 기능을 하는 7줄 짜리로 만드는 일이었다. 


그리고 각 method 마다 객체의 validity를 체크 하는 것이 method 제일 앞에 매크로로 들어가 있었다. 매크로만 신뢰한다면 항상 해당 method는 매크로 이후에는 객체 상태가 valid 하다는 것을 보장하는 코드이다. 게다가 수시로 바뀌는 validity 조건을 딱 한군데에서 제어할 수 있기 때문에 큰 장점이 있는 구조였다. 하지만 매크로를 없애야 하는 일이 생기면서 이 부분도 수정을 해야 하게 되었는데 이 매크로 안에는 return과 같은 제어문이 들어 가기 때문에 inline template으로도 만들 수가 없다. 그래서 결국은 매크로를 모두 풀어서 각 method 제일 앞에 넣는 수 밖에 없는 것이다. (물론 이건 안 하고 있다) 


그래서 나는 (1)안을 주장한다. 


Posted by 안영기

2012/05/28 23:17 2012/05/28 23:17
Response
0 Trackbacks , 5 Comments
RSS :
http://smgal.ismine.net/tc_191/blog1/rss/response/42

Trackback URL : 이 글에는 트랙백을 보낼 수 없습니다

copy constructor 문제?!

정적 분석 툴에서 다음과 같은 코드의 copy constructor에서 잠재적인 문제점이 있다는 보고를 받았다. (코드는 핵심적인 부분만 남긴 것이다)

 

하지만, 이쪽 코드는 우리가 최근 수정한 적이 없기 때문에 다른 모듈에서 최근 새로운 용법이 생기면서 발생한 문제라고 판단하면서 문제 분석을 하였다.

 

 

class A

{

public:

    A(void);

    A(const A& ref);

 

    int m_val;

};

 

A::A(void)

    : m_val(0)

{

}

 

A::A(const A& ref)

{

    m_val = ref.m_val;

}

 

 

확인 결과, 보통은 문제가 없었지만 다음과 같은 형태의 코드가 추가되면서 잠재적인 문제점이 발생한 것이다. (역시 핵심만 추린 것이라 코드 자체의 로직에는 큰 의미가 없다)

 

enum AType

{

    TYPE_DEFAULT

};

 

A GetA(AType type)

{

    switch (type)

    {

    case TYPE_DEFAULT:

        return A();

    }

    // A를 사용하는 쪽에서 return 구문이 없다.

    // enum의 모든 case에 대해서 switch 문에서 처리하므로

    // 정적 분석툴에서는 문제 없는 것으로 인식 한다.

}

 

int main(void)

{

    A a = GetA(TYPE_DEFAULT);

    A b = a;

 

물론 위의 코드만으로는 아무런 문제가 없다. 하지만 누군가가 악의적으로 다음과 같이 사용했을 때가 문제가 된다.

 

    A a = GetA(AType(TYPE_DEFAULT+1));

 

이와 같이 강제로 enum에 정의되지 않은 것을 강제로 넣게 되면 GetA() A를 리턴하긴 하지만 생성자가 불리지 않은 A의 임시 객체를 리턴한다. 그렇게 되면 멤버 변수는 초기화 되지 않은 상태이고 A b = a; 에 의해 copy constructor를 통한 b를 생성한다. 이 때 m_val = ref.m_val; 부분을 지나가게 되는데 a는 초기화된 적이 없으므로 알 수 없는 값인 ref.m_valm_val를 초기화 하기 때문에 최종적으로는 A class copy constructor 문제라고 보고가 된다.


Posted by 안영기

2012/05/28 20:16 2012/05/28 20:16
Response
0 Trackbacks , 0 Comments
RSS :
http://smgal.ismine.net/tc_191/blog1/rss/response/41

Trackback URL : 이 글에는 트랙백을 보낼 수 없습니다

new A 와 new A()에 대해

이번에는 new에 대한 이야기 이다.

몇 달 전에, Coding idiom을 정하는 쪽에서 코드의 통일성을 위해 파라미터가 없는 생성자의 생성법을 idiom으로 정리를 하자는 의견을 내었다. 간단하게 이야기 하면 new를 할 때의 코드 표기법을 new A 또는 new A() 중에 하나를 권장하는 쪽으로 가자는 것이다.

나의 경우, 처음에는 stack에서 생성할 때는 A a(); 가 아닌 A a; 를 사용해야 하므로 new 할 때도 new A()가 아닌 new A; 를 해야 한다는 주장을 하였다. 그런데 또 다른 쪽에서는 현재의 C++ 규약에서는 new A()와 new A의 동작을 각각 다르게 정의를 하고 있으므로 그 정의에 따라 결정을 하자고 했다.

그래서 문제의 방향은 new A()와 new A의 차이점을 보고 결정하기로 하였는데, C++1998과 C++2003에서 각각 정의하고 있는 new A()와 new A 의 차이점은 다음 링크에 잘 정리되어 있다.


원래 문제는 좀 더 복잡한 상태에서의 결정이지만, 이 문제를 간단하게 줄이면

- new A 는 메모리만 할당을 하며 사용자가 명세하지 않은 임의의 일을 더 하지 않는다.
- new A() 는 메모리 할당뿐 아니라 멤버의 값을 0으로 초기화 시켜 준다.

이렇게 정리가 된다.

여러 사람들이 각각의 의견을 내었고, 나는 C++1998이냐 C++2003이냐와 상관없이 (1)컴파일러가 임의의 일을 더 하지 않는 new A 방식을 택하여야만 개발자가 항상 명확한 코드를 짤 수 있다는 주장이었고, 반대 쪽의 의견은 (2)항상 0으로 초기화 시켜주어서 개발자가 실수하더라도 문제가 적어지도록 적절히 초기화가 되어야 한다라는 주장이었다.

최종적으로는 나의 의견은 채택되지 않았지만, 나는 여전이 (1)번을 주장하고 싶다. -std 옵션이 무엇이 되든 간에 코드의 consistency을 보장할 수 있다는 것, 즉 예외가 없는 규칙이 가장 좋은 규칙이라는 생각에는 변함이 없다.

사실 이래나 저래나 큰 영향은 없는 규칙이고 개인의 철학과 다양성의 문제이다 보니, 괜히 이런 결정에 브레이크를 걸어 여러 사람의 뒷다리를 잡는 일은 없어야 하기에 그냥 다수의 결정에 따랐다.

Posted by 안영기

2012/04/15 04:46 2012/04/15 04:46
Response
0 Trackbacks , 0 Comments
RSS :
http://smgal.ismine.net/tc_191/blog1/rss/response/39

Trackback URL : 이 글에는 트랙백을 보낼 수 없습니다

POD를 상속한 후손의 assignment operator

최근 정적 분석 툴에 의해 다음의 코드에 문제가 있다는 통보를 받았다.
(실제 코드에서 문제점만 최대한 압축하였다)

struct A
{
int a;
};

class B: public A
{
public:
B& operator=(const B& ref);
};

B& B::operator=(const B& ref)
{
if (this == &ref)
return *this;

this->a = ref.a;

return *this;
}

대부분의 경우는 정적 분석 툴의 설명만으로 문제를 수정할 수 있었지만 이 경우는 도저히 어떤 문제가 있는 것인지 알 수가 없었다. 이 자체로는 문제 있는 것이 아니었기에 컴파일러의 warning level을 높여도 문제가 검출 되지 않았다.

그래서, 결국은 SE팀에게 분석을 요청했고 이 문제에 대한 명료한 대답이 돌아 왔다.




아래처럼 변수를 직접 대입하면 (현재는 문제가 없지만) 잠재적인 문제가 있기 때문에

this->a = ref.a;

다음과 같이 자동으로 만들어질 A의 default assignment operator를 불러야 한다고 한다.

A::operator=(ref);

반론을 찾기 위해 이래 저래 의심 나는 부분에 대해서 어셈블리어로 만들어서 분석해 보았는데, 위 같이 하면, 나중에 A가 어떻게 변하더라도 A만 제대로 구현하였다면 B의 assignment operator는 문제가 없는 것으로 확인되었다. 컴파일러가 알아서 저 부분의 코드를 그때 그때에 맞게 잘 변경 해 주었던 것이다.

Posted by 안영기

2012/03/01 08:35 2012/03/01 08:35
Response
0 Trackbacks , 2 Comments
RSS :
http://smgal.ismine.net/tc_191/blog1/rss/response/38

Trackback URL : 이 글에는 트랙백을 보낼 수 없습니다

« Previous : 1 : 2 : 3 : 4 : 5 : Next »

블로그 이미지

Tizen과 GP2X WIZ와 CAANNO와 bada용 게임 개발을 하자

- 안영기

Notices

Archives

Authors

  1. 안영기

Recent Trackbacks

Calendar

«   2017/11   »
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30    

Site Stats

Total hits:
159576
Today:
6
Yesterday:
4