대변 파이터 (CAANOO 이식作)

일전에 GP2X WIZ로 만들었던 대변 파이터 embedded 판을 CAANOO로 포팅을 하였다. CAANOO에 맞는 키 설정으로 바뀌었으며, 사용 버튼은 다음과 같다.

<1인용>
방향키: 캐릭터를 8 방향으로 움직임
B키: 일반 공격
A키: 특수 공격
Home키:종료

<2인용>
<player 1>
왼쪽방향키: 캐릭터를 8 방향으로 움직임
<자동> 일반 공격
L키: 특수 공격
Home키: 종료

<player 2>
오른쪽방향키:캐릭터를 8 방향으로 움직임
<자동> 일반 공격
R키: 특수 공격
Home키: 종료

사용자 삽입 이미지
CAANOO용 대변 파이터 (198K)

Posted by 안영기

2011/05/29 20:20 2011/05/29 20:20
Response
0 Trackbacks , 0 Comments
RSS :
http://smgal.ismine.net/tc_191/blog1/rss/response/32

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

또 다른 지식의 성전 (CAANOO 이식作)

일전에 GP2X WIZ로 만들었던 또 다른 지식의 성전 embedded 판을 CAANOO로 포팅을 하였다. 역시 Lore 성만 플레이 가능하며 사용 버튼은 다음과 같다.

방향키: 캐릭터를 4 방향으로 움직임
B키: 확인
A키: 취소
II 키: 메뉴
Home키:종료

사용자 삽입 이미지
CAANOO용 또 다른 지식의 성전 (309K)

(CAANOO 버전은 CAANOO의 LCD 특성상 윗 부분 몇 픽셀이 베젤에 가려집니다)

Posted by 안영기

2011/05/29 19:55 2011/05/29 19:55
Response
0 Trackbacks , 0 Comments
RSS :
http://smgal.ismine.net/tc_191/blog1/rss/response/31

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

최근에 WIZ의 후속 기기인 CAANOO가 생긴 덕에, CAANOO의 툴체인에 익숙해져 보자는 미명으로 WIZ로 만들었던 게임을 포팅하고 있다.

처음부터 SDL 등으로 했으면 좋았을 텐데, 개인적인 만족을 위해 굳이 GPIO를 쓰고자 했던 지라 지금 CAANOO로 포팅하는 데 많은 애를 먹고 있다.

CAANOO 의 포팅 이야기는 다음에 하고 이번에 40분 이상을 고생하게 만든 코드를 소개하고자 한다. (printf()라도 되면 금방 잡았겠지만, 실행하면 그냥 기기가 다운되는 디버깅 환경이었다)

문제의 발단은

int num_chunk = read(fd, &data, sizeof(data));
if (num_chunk < 0)
return;
num_chunk /= sizeof(data[0]);

라고 처음에 만들었던 코드를 다음과 같이 최적화를 한답시고 한 줄 줄인 것이 원인이었다.

int num_chunk = read(fd, &data, sizeof(data))
                / sizeof(data[0]);
if (num_chunk < 0)
return;

man page에 의하면 read()가 size_t를 리턴하니, 같은 리턴 타입인 sizeof()로 나누어도 문제가 없을 것이란 예상이었다. 그와는 또 다르게 read()가 실패하면 -1을 돌리는 함수라는 것을 알고 있었고, (음수 / 양수)가 되면 결과는 음수가 되리라는 기본 산수적인 생각도 했기에 위의 코드는 문제가 없다고 생각하고 넘어 갔던 것이다.

나눗셈을 하는 순서가 조금 다를 뿐이었지만 이 부분이 잘 못되었다고 생각하기가 어려웠기에 이 주위에서 printf()를 찍으면서 좀 많이 헤매었다.


결론적으로, 내가 man page에서 read()가 size_t를 넘긴다고 보았던 것이 나의 착각이었다. 실제 함수의 프로토타입은 다음과 같다.

ssize_t read(int fd, void *buf, size_t count);

size_t가 아니라 signed인 ssize_t였다. 결국은 signed int / unsigned int 이고, 이 경우는 강제로 앞 쪽의 signed int가 강제로 unsigned 로 캐스팅되어서 결코 음의 결과 값이 나올 수가 없게 된다. 6~7년 전에도 회사 코드에서 비슷한 문제가 있어서 실수한 적이 있는데 또 그 상황이 재현되었다.

이것과 완전히 같은 내용은 아니지만 signed 와 unsigned의 비교 방법도 참 특이(?)한데, 다음과 같이 비교가 진행된다는 것을 꼭 알아야 한다.

- 양쪽 타입 크기가 같으면 signed 쪽를 unsigned로 변환
- 양쪽 타입의 크기가 다르면 작은 쪽을 큰 타입으로 바꾼 뒤
  unsigned 쪽을 signed 로 변환하여 계산


그리고 여기서 재미 있는 것 한 가지...

#include <stdio.h>

int main()
{
{
int          a = -10;
unsigned int b = 10;

printf("-10 / 10 = %d\n", a / b);
}

{
short          a = -10;
unsigned short b = 10;

printf("-10 / 10 = %d\n", a / b);
}

return 0;
}

이것을 실행 시키면 어떻게 될까. 결과는 다음과 같다.

-10 / 10 = 429496728 /* int / unsigned int의 결과 */
-10 / 10 = -1 /* short / unsigned short의 결과. */

방금 말한대로라면 계산이 이상해져야 정상인데, 왜 short 일 때는 잘 되는 것일까? 왜 이런지 이유를 알고 싶으면 assembly로 결과를 보내어서 보면 알 수 있다.

Posted by 안영기

2011/05/29 17:06 2011/05/29 17:06
Response
0 Trackbacks , 0 Comments
RSS :
http://smgal.ismine.net/tc_191/blog1/rss/response/29

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

this에 대한 NULL 체크

나는 플랫폼의 API는 C++이 아닌 C가 되어야 한다고 주장한다. 하지만 어떠한 이유에서든 현재는 Open API가 C++인 플랫폼을 개발하고 있다.
 
Open API가 C++ 이다 보니 여러 가지 문제가 많긴 한데(장점도 있겠지만) 그 중에 하나는 NULL instance가 그 객체의 method를 부르려고 할 때 방어 하는 방법이다.

최종적으로 Open API의 제공자는 모든 경우의 사용자의 오남용을 막을 의무가 있기에 관련 method마다 제일 앞에 다음과 같은 코드를 넣고 있다.
 
void MyClass::SetValue(int value)
{
        if (this) // (1)
        {
               this->m_value = value;
        }
}
 
이렇게 했을 때, 다음과 같은 실수를 막을 수 있을 것이란 기대이다.
 
MyClass* pMyClass = CreateMyClass(…);
// NULL 체크를 하지 않았음
pMyClass->SetValue(100);
 
물론 생각대로 잘 동작하고 있었고 국내 모 전자 회사의 TV에는 이런 코드로 실제 애플리케이션의 실수를 막고 있다. –MIPS와 ARM을 사용-
 
하지만 문제는 휴대폰에서였는데, 여기에서는 이 경우 (1)이라고 표시한 부분에서 항상 프로그램이 죽는다 (죽는 이유는 좀 복잡하지만 그건 생략). 여기서 사용한 컴파일러는 ARM core용이긴 하지만 armcc와는 조금 다른 다른 부류이다. 일단 나는 표준 C++의 동작을 따르지 않는다는 이유로 컴파일러 버그로 통보해야 한다는 주장을 했지만, 담당자가 알아 보더니 C++ 스펙에서는 this가 NULL일 경우에 대한 참조는 보장할 수 없다는 것이 답이라고 한다.
 
C++을 사용할 때, virtual table의 구조라든지 method call과 관련된 구조를 숙지하게 되고 그 내용에서는 보통 this는 stack이나 register를 통해 전달 되기 때문에 위의 코드는 표준에서도 문제가 없다고 생각하기 마련인데 사실은 그렇지 않나 보다.


Posted by 안영기

2010/12/29 23:18 2010/12/29 23:18
Response
0 Trackbacks , 9 Comments
RSS :
http://smgal.ismine.net/tc_191/blog1/rss/response/28

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

GP2X WIZ의 libcastor 이용 프로젝트

항상 일과는 별개로 집에 와서는 개인 프로젝트를 하면서 여러 가지의 실험적인 일을 하곤 했다. 하지만 전부터는 그마저도 쉽지 않았고 실제 성공한 개인 프로젝트는 거의 없다시피 하였다. 대부분이 기술적인 난제라서가 아니라 개인적인 시간이 부족하여 흐지부지 것이 대부분이다. 

올해도 게임에서 sight of line 어떻게 빠르게 처리할 있을까 하는 주제로 연구(?)하였고 엄청난 처리 속도의 알고리즘이 만들어진 것인 알았지만 결국 초기의 아이디어에 헛점이 발견되어해결할 없는 경우 생기고 말았다. 그래서 폐기. 

다음에는 대변 파이터 1.0 버전을 만들기 위해 renewal 작업을 했었다. 효과음 부분을 집어 넣고, 소스 공개를 목적으로 했기에 구조를 최적화 하고, 프레임을 2 빠르게 만들었다. 프레임이 2배가 늘어 나게 되면서 디테일과 관련된 일부 버그가 발견되어 현재는 방치된 상태다. (언젠간 다시 것이라 생각한다) 

그리고 작년에 것이 바로 지금 공개하는 것이다. 원래 libcastor라는 것은 GP2X Wiz native 입출력 기능을 가진 라이브러리인데, 이것을 통해서 Wiz 고질 문제인 tearing 근본적으로 없애자는 아이디어로 시작한 것이다. 최초에는 Wiz 숨겨진 기능인 32-bit frame buffer mode double buffer flipping 기능을 사용하여 보았으나 실제로는 H/W 처리되지 않는 속도 저하가 있었다. 하여간 tearing 없애기 위해 Wiz 세로 모드로 놓고 가로 모드 좌표계로 모두 바꾸어서 출력하는 시뮬레이션 레이어를 만들었는데 그것이 flat experience 불리는 라이브러리다. (이것도 여러 플랫폼에 이식이 되어 있다) 

압축을 풀면 나오는 구조는 다음과 같고, 파일에 대한 설명으로 마무리 지으려 한다. (개인적인 성취감 또는 의무로서 올리는 것이라 다른 사람의 편의성은 생각하지 않았다) 

사용자 삽입 이미지

(233k)

dejadun
|  
|   Makefile
|
+---avej_util
|       avej_util_font12x12.cpp
|       avej_util_font12x12.h
|       avej_util_pascal_set.cpp
|       avej_util_pascal_set.h
|       avej_util_tile_map.cpp
|       avej_util_tile_map.h
|      
+---bin
|       deja512_1.png
|       deja512_2.png
|       font1bit_1024_512.png
|       Roperr.maf
|      
+---deja_dun
|       Makefile
|       pdm_chara.cpp
|       pdm_chara.h
|       pdm_config.h
|       pdm_item.h
|       pdm_main.cpp
|       pdm_res.cpp
|       pdm_res.h
|       pdm_type.h
|       pdm_window.cpp
|       pdm_window.h
|       pdm_window_map.cpp
|       pdm_window_map.h
|      
\---flat_experience
    |   Makefile.lib
    |  
    +---include
    |       flat_experience.h
    |       pixel_format.h
    |       sm_util.h
    |      
    +---lib
    \---src
        |   flat_board.h
        |   flat_experience_display.cpp
        |   flat_experience_input.cpp
        |   image_decoder_png.cpp
        |   image_decoder_png.h
        |   sm_util.cpp
        |  
        +---target_bada
        +---target_common
        |       file_io.cpp
        |       system.cpp
        |      
        +---target_win32
        \---target_wiz
                castor.c
                castor.h
                polluxregs.h 

Makefile

이 프로젝트를 빌드하기 위한 Makefile. 실제로 cygwin에서 사용하였다.

GPH에서 제공한 툴체인이 root에 설치되어 있다고 가정하고 만든 것이기에 실제 빌드할 때는 몇몇 디바이스 헤더를 못 찾는다는 메시지가 나올 수 있다. 그때는 자신의 툴체인이 설치된 위치를 CPPFLAGS 에 추가해 주면 된다. 

avej_util

일종의 utility 들을 모아 놓은 디렉토리다. 

avej_util/avej_util_font12x12

12x12 한글 폰트를 출력하기 위한 것이다. bin/font1bit_1024_512.png 폰트를 사용한다. 

avej_util/avej_util_pascal_set

pascal의 내장 set과 같은 기능을 c로 구현한 것이다. 그다지 중요하지 않으니 자세한 설명은 생략한다. 

avej_util/avej_util_tile_map

맵의 구조를 표현하기 위한 부분이다. DejaVu map 파일인 *.maf을 읽는 부분이 들어 가 있다. 

bin

최종 결과물이 들어가게 되는 디렉토리. 타일 이미지, 스프라이트 이미지, 폰트 이미지, 맵 파일, 그리고 실행 파일이 들어 간다. 

deja_dun/pdm_chara

DejaVu 캐릭터를 나타내기 위한 class들을 담고 있다. 

deja_dun/pdm_config.h

게임을 위한 configuration 들어 있다. 

deja_dun/pdm_item.h

Item 위한 기본 구조를 담고 있다. 

deja_dun/pdm_main.cpp

게임의 구조를 가지기 위한 초기화와 종료 코드를 가지고 있으며 실제 데모의 실행 루프를 가지고 있다. 

deja_dun/pdm_res

데모에 사용되는 리소스를 모아 놓은 구조체를 담고 있다. 

deja_dun/pdm_type.h

데모에 공통으로 사용하는 기본 자료형을 정의하였다. 

deja_dun/pdm_window

데모에서 사용되는 window 기본 구조를 정의하였다. 데모 자체는 따로 진행하는 다른 프로젝트에서 가져 왔으므로 필요 없는 정의가 많다. 정확하게 이야기 하면 Wiz같은 embedded device 스크린에서 window 구조는 그다지 필요 없긴 하다. 

deja_dun/pdm_window_map

게임의 형태를 띄기 위해 map 출력하는 목적의 window 재정의하였다. 실제 모든 출력은 window에서 일어나게 된다. 

flat_experience

libcastor 사용함과 동시에 WIZ tearing 현상을 없애기 위해 세로 모드에서 가로 모드를 시뮬레이션 해주는 플랫폼이다. 

flat_experience/Makefile.lib

데모에는 전체가 빌드되는 형식이지만 원래는 Makefile 이용해서 독리적인 라이브러리로 배포 가능하다. 

flat_experience/include

flat experience 라이브러리를 사용할 필요한 헤더가 정의 되어 있다. 

flat_experience/lib

독립적인 라이브러리로 빌드 때는 디렉토리에 *.a 생성된다. 

flat_experience/src

flat experience 라이브러리의 소스가 담겨 있다. 

flat_experience/src/flat_board.h

2D 버퍼를 표현하기 위한 기본 구조를 정의를 하고 있다. 

flat_experience/src/flat_experience_display.cpp

세로 모드에 대한 2D 버퍼를, 가로 모드처럼 보이게 하기 위한 시뮬레이션이 들어 있다. 실제로 libcastor 사용해서 출력을 하는 곳이다. HW Flip, 32-bit color, 다중 layer 같이 WIZ 숨겨진(?) 기능을 쓰는 코드가 들어 있긴 하나 실제로 적용 했을 문제점이 많아서 그냥 버퍼를 copy하는 코드로 최종 반영되어 있다. 

flat_experience/src/flat_experience_input.cpp

Wiz 입력을 일반화 시키기 위한 내용이 들어 있다. 역시 libcastor 사용하고 있으며 WIZ touch screen 입력 관련된 것도 포함되어 있다. 

flat_experience/src/image_decoder_png

libpng 사용하여 PNG 파일을 읽는 부분이 들어 있다. 데모의 리소스를 읽는데 사용한다. 

flat_experience/src/sm_util.cpp

Utility 함수의 집합이 되어야 하지만 지금은 PNG 읽어 오는 여러 방법에 대한 것이 정의 되어 있다. 

flat_experience/src/target_bada

삼성의 스마트폰 플랫폼인 bada 포팅 레이어이다. 배포에는 내용이 빠져 있다. 

flat_experience/src/target_common

타게팅과 관련되어 기능적으로 일반화 가능한 것이 정의된 디렉토리이다. 

flat_experience/src/target_common/file_io.cpp

파일 접근에 대한 기본 기능이 정의되어 있다. bada 같이 std 파일에 접근이 불가능 경우를 위해 포팅 레이어로 빠져 있다. 

flat_experience/src/target_common/system.cpp

플랫폼의 시스템 특성과 관련된 기능이 정의되어 있다. 지금은 클럭 관련 기능만 들어 있다. 

flat_experience/src/target_win32

MS Windows 포팅 레이어이다. 배포에는 내용이 빠져 있다. 

flat_experience/src/target_wiz

GP2X Wiz 포팅 레이어이다. 

flat_experience/src/target_wiz/castor

libcastor 원본이다. 라이선스에 의하면 자유롭게 수정 배포 가능하다고 한다. 

flat_experience/src/target_wiz/polluxregs.h

libcastor 포함된 내용으로, Wiz 사용하는 pollux 대한 레지스터가 정의되어 있다.

Posted by 안영기

2010/11/20 07:23 2010/11/20 07:23
Response
0 Trackbacks , 0 Comments
RSS :
http://smgal.ismine.net/tc_191/blog1/rss/response/27

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

C와 C++의 const 처리 방식

며칠 전 팀 사람들과 모여서 SDK 샘플에 사용할 코드를 리뷰 하다가 한가지 의문이 들었다. 헤더에서 const int로 선언한 상수의 instance는 어디에 생기느냐는 것이었다.

헤더라고 해도 결국 *.c / *.cpp 파일이 include하는 목적으로 사용되는 것이기 때문에 결국은 *.c / *.cpp에 직접 선언 한 것과 같아진다. , a.c b.c에서 동시에 const 선언된 상수가 있는 헤더 파일을 include 하게 되면 실제로는 같은 이름의 상수가 a.c b.c 에 동시에 선언이 된 것이다. 그리고 이것이 static이 아닌 이상은 같은 이름으로 선언된 것이 2개가 되므로 컴파일 에러를 내어야 한다.

일단 실험을 해보았다.


a.h

const int AAAA = 0;

a.c

#include "a.h"
int main()
{
    return AAAA;
}


b.c

#include "a.h"
int foo()
{
    return AAAA;
}

bash-3.00$ gcc a.c b.c
/cygdrive/c/ykahn/ccQerCRS.o:(.rodata+0x0): multiple definition of `AAAA'
/cygdrive/c/ykahn/cc3HVd2e.o:(.rodata+0x0): first defined here
collect2: ld returned 1 exit status



역시 예상대로 다중 선언에 의한 컴파일 에러가 발생했다.

그럼 여기서 드는 의문은, c++을 배울 때 꽤 앞 쪽에 나오는 이야기 중에는, ‘헤더에 쓰인 #define const로 대체하라라고 되어 있는데 그렇게 해도 문제가 없는 가였다. 기억으로는 c++에서는 헤더에 const를 넣고도 아무리 많은 cpp 파일에서 include를 해도 위와 같은 문제는 없었다는 것이 경험상의 결과였다.

그래서 이 번에는 cpp 파일로 테스트를 해보았다.


a.h

const int AAAA = 0;

a.cpp

#include "a.h"
int main()
{
    return AAAA;
}


b.cpp

#include "a.h"
int foo()
{
    return AAAA;
}


bash-3.00$ gcc a.cpp b.cpp
bash-3.00$ _

.. 그 동안 경험한 결과와 같이 이 경우에는 문제없이 컴파일 된다. 이걸 보고 가장 먼저 드는 생각은 일관성의 문제였다. 좋은 스펙은 예외 사항이 최소여야 한다고 생각되었기에 구글링을 통해 이 부분을 검색을 해보았다.

검색 결과 이 경우 c c++ const를 다르게 해석하며 ISO C++ 표준 Sec. 5.2.11.7, Sec. 7.1.5.1  그것이 정의되어 있다고 한다. , 스펙이 그렇다고 하니 더 이상 의문을 가질 필요는 없어졌고 각각의 상수에 대한 주소를 찍어 보면 include 한 개수만의 서로 다른 instance를 가지고 있는 것으로 나타난다.

Posted by 안영기

2010/10/22 21:01 2010/10/22 21:01
Response
0 Trackbacks , 0 Comments
RSS :
http://smgal.ismine.net/tc_191/blog1/rss/response/26

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

이상한 파라미터

조금 예전의 코드를 보다가 나중에 검토를 해 보자는 주석이 달린 코드를 보았다.
그리고 그 때 제시된 문제를 간략하게 만들어 보았다
.

#include <stdio.h>

class CRenderMode
{
public:
        explicit CRenderMode(int mode)
        {
               printf("mode = %d\n", mode);
        }
};

int main()
{
        int mode = 0;

        // 아래 것은 출력 안 됨.
        CRenderMode state0( int(mode) );

        // 나머지 3개는 출력 됨
        CRenderMode state_( int((int)mode) );
        CRenderMode state1( int(mode+0) );
        CRenderMode state2( (int)mode );

        return 0;
}

생성자에 파라미터를 넣을 때 int(mode) 라고 하니 원했던 생성자가 안 불렸다는 것인데, 마치 파라미터 없는 생성자를 부를 때 실수로 CRenderMode state0(); 라고 했을 때와 상황이 같다. 이것도 뭔가 스펙이 있는 듯 하지만, 정확한 이유는 모르겠다.

 

 

Posted by 안영기

2010/04/25 12:45 2010/04/25 12:45
Response
0 Trackbacks , 5 Comments
RSS :
http://smgal.ismine.net/tc_191/blog1/rss/response/24

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

notation

프로그래밍이란 것을 계속 하다 보면, 어느 순간 여러 가지 방법론이 머리 속에 고정관념처럼 박혀 있는 것이 많다.

그런데 여전히 갈피를 못 잡고 있는 것은 code notation을 정하는 것이다. 가장 처음에는 변수를 2자 밖에 못쓰던 언어를 사용였는데 모두 대문자 약자로 변수를 구성하였다. 그러다가 C를 하면서는 under_score notation을 썼고 다음에 Pascal을 하면서부터는 자연스레 PascalCase를 사용하게 되었다. 그러면서 한동안은 함수명은 PascalCase, 변수명은 camelCase로 고정되고 있다가 약 2년 전부터는 다시 변수에 under_score를 쓰기 시작했다.

가독성이라는 기준이 해가 가면서 변하는지라, 지금은 camelCase보다는 under_score가 눈에 더 잘 들어오고 있기 때문이다. Notation은 해가 갈 때마다 변하지만 그래도 변하지 않는 것은 그것을 적용하는 목표이다. 그 목표란 최대한 코드를 빨리 읽으면서 실수를 줄이자는데 있다. 파라미터 변수와 멤버 변수를 가려 내고, 클래스와 네임스페이스를 가려 내고 함수와 매크로는 표기법만으로 구분하면서 최대 효율로 작업을 할 수 있게 하기 위함이다. (code를 만들 때의 타이핑은 많아져도 상관없다고 생각한다)

덕분에 그 동안 만든 라이브러리 코드들을 보면 대충 만들어진 시대를 짐작할 수 있게 되었다.

Posted by 안영기

2010/03/31 23:29 2010/03/31 23:29
Response
0 Trackbacks , 2 Comments
RSS :
http://smgal.ismine.net/tc_191/blog1/rss/response/23

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

플랫폼의 지원 범위

플랫폼 개발을 하다 보면 사람들 간의 개념 간의 충돌이 많다. 그런 것들은 답이 정해져 있는 것도 아니라 개인이 추구하는 성향에 따라 의견들이 갈리는 것이 대부분이다. 그 중에 하나가, 이 플랫폼으로 개발할 개발자들에게 모든 가능성을 간직한 기본만을 제공할 것인가아니면 최대한 많은 기능을 넣어서 편의성을 도모할 것인가에 대한 의견 충돌이 제일 처음 생기게 된다.

 

결론부터 말하자면 나는 전자이다. 플랫폼은 기본만 제공하는 간단한 것이었으면 한다.

 

이 의견에 반대 사람들이 내는 주장은 대부분 플랫폼 사용을 쉽게 하여 많은 개발자가 사용할 수 있게 하자라는 것인데 나는 이 부분 때문에 반대를 하는 것이다. 나는 플랫폼을 기반으로 한 애플리케이션 사용에는, 어느 정도 문턱이 있어서 일정 레벨 이상의 개발자들만 뛰어 들어야 전체 결과물의 수준이 높아진다고 생각을 하고 있다.

 

회사 내에서도 논란이 되는 부분이 SDKOpenGL ES만 지원하면 되는지 아니면 자체 렌더링 엔진을 넣어야 하는지의 선택이 있는데, 이 역시도 위의 선택에 따라 OpenGL ES만 지원하면 된다고 주장하고 있다. Apple 앱스토어의 통계 같은 것은 잘 모르겠지만 내가 예상하는 것은, 잘 만든 소수의 애플리케이션이 대다수의 돈을 벌어 들인다는 생각이다.

 

개발의 문턱이 낮을 때, 100개의 애플리케이션이 상급 10개 중급 30개 하급 60개로 구성되어 있다면, - (1)

개발의 문턱이 높을 때는 40개의 애플리케이션이 상급 10개 중급 30개만 있게 된다. – (2)

(상급의 애플리케이션이 판매 개수가 훨씬 많고 하급은 판매 개수는 적다는 논리를 적용 한다)

 

이렇게 되면 겉보기의 전체적인 수익은 (1)이 높아 보일지는 모르겠지만, 유저의 입장에서는 (2)의 경우가 더 신뢰성 있는 애플리케이션을 구할 확률이 높으므로 유저의 수가 더 많이 몰리게 되어 실제 매출이 더 높아진다는 논리이다.

 

게임 플랫폼이라면, ‘기본 OS의 추상화 + 디바이스 추상화에다가 2D 그래픽은 frame buffer 접근법만 열어 주면 되고, 3D 그래픽은 OpenGL 같은 것만 열어 주면 된다는 것이다. 하지만 대부분의 사람들은 플랫폼을 종합 선물 세트로 만들려고 하기에 시간과 돈이 많이 투자된다. (라는 생각을 가지고 있다. 하지만 역시 정답은 없다)

 

Posted by 안영기

2010/02/27 21:43 2010/02/27 21:43
Response
0 Trackbacks , 4 Comments
RSS :
http://smgal.ismine.net/tc_191/blog1/rss/response/22

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

LG폰 SMS의 2010년 표시 버그

이번 2010년이 들어서 S/W 업계에서 가장 큰 화두는 LGSMS2010년 표시 버그일 것으로 생각한다.

SMS의 스펙을 확인 해 보니, 연도는 1byte"Swapped Nibble을 적용한다고 되어 있으며 Swapped Nibble의 정의는 BCD code where nibbles within octet is swapped. E.g.: 0x31 Represents value of 13 라고 되어 있다. 여기서 문제가 되는 것은 BCD인데, Swapped Nibble 이라는 말을 단어 자체로만 들으면 4비트가 서로 바뀌어 있다라는 의미만 내포된 것으로 보이기 때문에 그것이 BCD로 표현될 것이란 예상을 하기가 어렵다. (물론 스펙을 제대로 안 본 사람이 무조건 잘 못이지만…)

그래서 원래는 (year >> 4) + (year & 0x0F) * 10 이어야 하는 공식을 (year >> 4) + (year & 0x0F) * 0x10 로 쓴 것으로 예상한다.

여기에서 특별히 기술적인 내용을 이야기 하려는 것은 아니고, 이런 사소한 실수 하나 때문에 회사의 이미지가 떨어지고 관련된 담당자와 그의 상사들과 QA팀은 큰 화를 입을 것이란 것이라는 것이다. 실수의 경중으로 보면 굉장히 가벼운 실수이긴 하나 파급 효과는 굉장히 크다. 버그 있는 코드는 누구나 만들고 있지만 운도 많이 작용하고 있다는 일례일 것이다.

LG의 개발 상황을 예상해보면, 문제의 코드를 만든 본인은 이미 퇴사 또는 다른 부서로 발령이 났고, 몇 명의 담당자를 거쳐 지금은 사원급 개발자가 인수 받았으며 그 한 명이 국내판 백 종 이상의 양산 코드를 담당하고 있었을...

Posted by 안영기

2010/01/05 10:59 2010/01/05 10:59
Response
0 Trackbacks , 0 Comments
RSS :
http://smgal.ismine.net/tc_191/blog1/rss/response/21

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

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

블로그 이미지

게임 개발을 기반으로 한, 잡다한 개발 기록 저장소

- 안영기

Notices

Archives

Authors

  1. 안영기

Recent Comments

Recent Trackbacks

Calendar

«   2024/12   »
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 31        

Site Stats

Total hits:
252014
Today:
1
Yesterday:
165