오늘 테스트하는데 스캔 코드(Scan Code)가 필요해서 찾다보니 아주 깔끔하게 정리된 내용을 발견했습니다. 원문은 http://blog.naver.com/jesuskth?Redirect=Log&logNo=20005262457에서 보실 수 있습니다.

Const SCANKEY_ESC = 1

Const SCANKEY_1 = 2             ' 1
Const SCANKEY_2 = 3             ' 2
Const SCANKEY_3 = 4             ' 3
Const SCANKEY_4 = 5             ' 4
Const SCANKEY_5 = 6             ' 5
Const SCANKEY_6 = 7             ' 6
Const SCANKEY_7 = 8             ' 7
Const SCANKEY_8 = 9             ' 8
Const SCANKEY_9 = 10            ' 9
Const SCANKEY_0 = 11            ' 0
Const SCANKEY_MINUS = 12        ' -
Const SCANKEY_EQUAL = 13        ' =
Const SCANKEY_BS = 14           ' ←

Const SCANKEY_TAB = 15          'TAB
Const SCANKEY_Q = 16            ' Q
Const SCANKEY_W = 17            ' W
Const SCANKEY_E = 18            ' E
Const SCANKEY_R = 19            ' R
Const SCANKEY_T = 20            ' T
Const SCANKEY_Y = 21            ' Y
Const SCANKEY_U = 22            ' U
Const SCANKEY_I = 23            ' I
Const SCANKEY_O = 24            ' O
Const SCANKEY_P = 25            ' P
Const SCANKEY_SQUARE_OPEN = 26  ' [
Const SCANKEY_SQUARE_CLOSE = 27 ' ]
Const SCANKEY_ENTER = 28        ' ENTER

Const SCANKEY_CTRL = 29         ' CTRL
Const SCANKEY_A = 30            ' A
Const SCANKEY_S = 31            ' S
Const SCANKEY_D = 32            ' D
Const SCANKEY_F = 33            ' F
Const SCANKEY_G = 34            ' G
Const SCANKEY_H = 35            ' H
Const SCANKEY_J = 36            ' J
Const SCANKEY_K = 37            ' K
Const SCANKEY_L = 38            ' L
Const SCANKEY_SEMICOLON = 39    ' ;
Const SCANKEY_QUOTATION = 40    ' '

Const SCANKEY_QUOTATION2 = 41   ' `
Const SCANKEY_LSHIFT = 42       ' LEFT SHIFT
Const SCANKEY_WON = 43          ' \

Const SCANKEY_Z = 44            ' Z
Const SCANKEY_X = 45            ' X
Const SCANKEY_C = 46            ' C
Const SCANKEY_V = 47            ' V
Const SCANKEY_B = 48            ' B
Const SCANKEY_N = 49            ' N
Const SCANKEY_M = 50            ' M
Const SCANKEY_COMMA = 51        ' ,
Const SCANKEY_PERIOD = 52       ' .
Const SCANKEY_SLASH = 53        ' /
Const SCANKEY_RSHIFT = 54       ' RIGHT SHIFT

Const SCANKEY_PRTSC = 55        ' PRINT SCREEN SYS RQ
Const SCANKEY_ALT = 56          ' ALT
Const SCANKEY_SPACE = 57        ' SPACE
Const SCANKEY_CAPS = 58         ' CAPS
Const SCANKEY_F1 = 59           ' F1
Const SCANKEY_F2 = 60           ' F2
Const SCANKEY_F3 = 61           ' F3
Const SCANKEY_F4 = 62           ' F4
Const SCANKEY_F5 = 63           ' F5
Const SCANKEY_F6 = 64           ' F6
Const SCANKEY_F7 = 65           ' F7
Const SCANKEY_F8 = 66           ' F8
Const SCANKEY_F9 = 67           ' F9
Const SCANKEY_F10 = 68          ' F10
Const SCANKEY_NUM = 69          ' NUM ROCK
Const SCANKEY_SCROLL = 70       ' SCROLL ROCK

Const SCANKEY_GRAY_HOME = 71    ' 키패드
Const SCANKEY_GRAY_UP = 72
Const SCANKEY_GRAY_PGUP = 73
Const SCANKEY_GRAY_MINUS = 74
Const SCANKEY_GRAY_LEFT = 75
Const SCANKEY_GRAY_CENTER = 76
Const SCANKEY_GRAY_RIGHT = 77
Const SCANKEY_GRAY_PLUS = 78
Const SCANKEY_GRAY_END = 79
Const SCANKEY_GRAY_DOWN = 80
Const SCANKEY_GRAY_PGDN = 81
Const SCANKEY_GRAY_INS = 82
Const SCANKEY_GRAY_DEL = 83

Const SCANKEY_F11 = 87          ' F11
Const SCANKEY_F12 = 88          ' F12


 에혀~ 일찍 자야하는데 작업을 좀 하다보니 이제야 끝났군요. 급히 좀 쓸일이 있어서 뚝딱뚝딱 드라이버와 DLL을 손봤습니다.

 가끔 생각하는건데... 제가 뭐하는 사람인지 잘 모르겠군요. ^^;;;; 소속도 애매한 것이 이것 저것 안하는게 없는 것 같습니다. ㅜ_ㅜ

 뭐 하나를 진득하게 파긴 파야할텐데 호기심이 많아서 가만히 있지를 못하겠군요. ㅎㅎ 그래도 뭐 아웃풋이 나오니 그나마 다행이지요. ^^;;;

 에혀~ 이제 자야겠군요. 다들 좋은 밤 되시길 ;)


 요즘 회사에서 하루종일 소스 코드를 분석을 하고 있습니다. 앞으로 제가 수정해야할지도 모르는 코드라서 상당히 조심스러운데... 수많은 테스트를 거치면서 다양한 케이스를 커버하기위해 도배된 if-else를 보면 한숨만 나옵니다. ㅡ_ㅡa...

 또 하는 일이 좀 그런지라 Function Pointer로 도배된 코드는 따라가기가 상당히 귀찮습니다. ㅜ_ㅜ)-b 좋은 분석툴을 쓰고 있기는 한데... 그래도 뭔가 부족한 느낌이 들더군요. 복잡한 콜 관계를 그래프로 그려주는 게 없을까하고 한참을 고민했습니다.

 그러다 문득 Doxygen이 떠올랐습니다. 복잡한 소스 코드도 척척 다이얼로그를 그려주던 모습이 상당히 인상적이더군요. 그래서 Doxygen과 Graphvis를 급하게 설치해서 바로 돌렸습니다. 그런데 얼래... 콜 그래프가 없는 겁니다. ㅡ_ㅡa...

 왜그럴까 한참을 고민하면서 옵션을 만지다 결국 퇴근... 계속 고민 고민하다 문득 Function Pointer로 도배된 코드는 분석 못하는게 아닌가 하는 생각이 들더군요. ㅡ_ㅡa... 원래 이런 류의 코드는 잘 안되는건가....

 혹시 Function Pointer로 도배된 코드를 Doxygen으로 돌려서 Call Graph를 생성하신 분 계시면 요령 좀 가르쳐주세요. ^^;;; kkamagui 한번 살려주시는 셈 치시고 덧글로 부탁드립니다. ^^)/~ 혹시 좋은 소스 분석 툴 있으면 추천도 감사히 받겠습니다. ;)

 오늘은 뭘 할려고해도 시간이 부족하군요. ;) 글이나 좀 읽다가 자야겠습니다.
 다들 좋은 밤 되세요 ^^)/~
 
 
 와우~ 이번에 모 드라이버들이 업데이트가 좀 되서 애를 좀 먹었습니다. ^^;;; 리버싱을 해서 분석하는게 아니라 윈도우 커널이 어떻게 변경되는가를 보고 추측(?)해서 작업하기 때문에 테스트 케이스를 상당히 많이 만들어두는 편입니다.

 어떤 케이스가 무사히 통과할지는 모르는거니까, 상당한 노가다가 필요한 작업이지요. ㅜ_ㅜ)/~ 이거 테스트할려고 오늘 퇴근도 일찍했는데, 나름 보람있군요. ㅎㅎ 잘 돌아가는 걸 확인하고 나니 뿌듯합니다.

 이제 슬슬 정리하고 쉬어야겠습니다. 간만에 머리를 굴렸더니 다리(??)가 아프네요(저도 이유를 모르겠습니다. 이게 무슨... ㅡ_ㅡa...).

ps) 이럴줄 알았으면 툴을 좀 많이 만들어 두는 건데... 이번 주말에 신경 좀 써서 노가다를 피하는 방향으로 좀 가야겠군요. ;)
 분석할 드라이버가 생겨서 당분간 NDS or PSP 홈브루를 개발하기 힘들 것 같습니다. 일단 아웃풋이 나와야해서.. ^^;;;;

 뭐 그리 거창한 것은 아니고, 게임 보안에 관련된 드라이버인데... 원체 실력이 허접한지라 그냥 훓어보는 정도입니다. 예전에 많이 분석하고 배우고 그랬었는데... 그때와는 또 많이 달라졌네요. ㅎㅎ

 예전에 제가 분석할 때는 SDT쪽을 누가 티안나게 잘 훔치는가가 대세였는데... 지금은 한쪽은 SDT를 완전히 포기하고 ntoskrnl쪽을 패치하는 쪽으로 방향을 바꿨고, 다른 한쪽은 아직 SDT쪽에 손을 대고 있더군요. ㅎㅎ

 뭐 어떻게 하고 있는지를 알았으니 이제 파 보는 일만 남았습니다. ㅎㅎ 언능 완료하고 오겠습니다. ;)

 그럼 좋은 밤 되시길~ ^^)/~

ps) 그러고보니 이때까지 분석 드라이버 하나 안가지고 있었군요. 매번 템플릿에 손을 좀 대서 하다보니 귀찮아져서... 이 기회에 만들어둬야겠습니다. ;)


 DDK를 설치하면서 너무 오래 걸리길래 영화 한편을 봤습니다. 포비든 킹덤(Forbidden Kingdom)을 봤는데, 뭐랄까요... 그냥 성룡표 액션 정도가 되겠더군요. ㅡ_ㅡa 헐리우드판 홍콩영화랄까요... ㅋㅋㅋ

 생각보다 좀 별로였습니다. 성룡표 액션도 좀 부족했고, 이연걸의 포스가 좀 많이 떨어져서... 눈물이...(예전의 포스는 다 어디가고... ㅜ_ㅜ)

 그나저나 DDK 는 아직도 설치 중이라는... ㅜ_ㅜ
 이거 나원.... ㅎㅎ

ps) 아이언맨 2가 빨리 나왔으면 좋겠어요 ㅎㅎ >ㅁ<)/~~

참고. NDS 홈브루에 DLDI 패치하는 방법

원문 :http://kkamagui.springnote.com/pages/1189016

 

들어가기 전에...

0.시작하면서...

 이 문서는 파일에 접근하는 NDS 홈브루를 정상적으로 실행하기위해 DLDI 패치를 적용하는 방법을 설명한 문서이다.

 

1.DLDI란?

 DLDI는 Dynamically Linked Device Interface의 약자로써, NDS 홈브루 개발에 사용되는 libfat 라이브러리에서 사용한다. libfat는 기기에 포함된 MicroSD 또는 SD와 같은 메모리 카드 영역에 접근하여 파일을 읽고 쓰는 기능을 하는 라이브러리이다. 메모리 카드에 데이터를 읽고 쓰는 NDS 홈브루라면 반드시 사용하고 있는 라이브러리이다.

 하지만 각 기기마다 메모리 카드에 접근하는 방식에 차이가 있기 때문에, 자신의 기기에서 정상적으로 실행하기 위해서는 DLDI에 패치를 가해야 한다.

 

2.DLDI 패치 프로그램 다운로드

 DLDI 프로그램은 http://chishm.drunkencoders.com/DLDI/에서 다운로드 받을 수 있다.

 웹 페이지의 중간쯤 보면 아래와 같은 화면이 보일 것이다. 붉은 사각형으로 표시된 "Win32 GUI Download" 를 클릭하여 파일을 저장하자.

DLDI.PNG

<DLDI 패치 프로그램>

 다운로드 받은 파일의 압축을 해제하면 여러 파일이 나오는데, 그 중 "dlditool32.exe" 파일만 있으면 되므로, 해당 파일만 남기고 나머지는 모두 삭제하자.

 

3.DLDI 패치 파일 다운로드

 패치 프로그램을 다운로드 받았으니 이제 패치 파일을 다운로드 받아야 한다. 패치파일은 http://chishm.drunkencoders.com/DLDI/ 의 상단(아래 화면 참조)에서 받을 수 있다. 

 자신의 기기에 맞는 파일을 다운로드하여 위에서 다운 받은 "dlditool32.exe" 파일이 있는 폴더에 넣자. 만약 파일이 정상적으로 다운로드 되지 않는다면 dlditool-win32-gui.zip에서 다운로드 하자. DLDI 패치 파일과 패치 프로그램이 포함된 압축 파일이다.

DLDI_Patch_File.PNG

<DLDI 패치 파일>

 

4.홈브루 패치 실행

4.1 초기 화면 및 기기 선택

 이제 "dlditool32.exe"을 실행하면 아래와 같은 화면이 표시될 것이다.

실행1.PNG

<초기 화면>

 최상단의 붉은색 콤보박스는 홈브루를 동작시킬 기기를 선택한다. 만약 자신의 기기가 나타나지 않는다면 위로 돌아가서 다시 DLDI 패치 파일을 다운로드해서 "dlditool32.exe파일과 같은 폴더에 넣어두자.

 

4.2 NDS 홈브루 파일 선택

 이제 실제 패치할 홈브루를 선택해야 한다. 홈브루 선택은 우측 중앙 쯤에 있는 "..." 버튼으로 선택하면 된다. "..." 버튼을 누르면 아래와 같은 파일 선택 창이 나타날 것이다. NDS 파일을 찾아서 넣어두자.

파일선택.PNG

<NDS 홈브루 파일 선택>

4.3 패치 적용

 파일을 선택했으면 제일 아래 쪽에 "Patch" 버튼을 누르면 된다.

패치실행.PNG

<패치 적용>

 

 패치가 성공하면 아래와 같은 메시지가 표시될 것이다. 이제 홈브루를 기기에 복사해서 실행하면 정상적으로 실행되는 것을 확인할 수 있다.

 

패치성공.PNG

<패치 성공>

 

5.마치면서...

 이상으로 NDS 홈브루에 DLDI 패치를 적용하는 방법을 알아보았다. 이제 NDS의 기능을 확장해주는 홈브루의 세계로 빠져보자. ^^)/~

 

 

이 글은 스프링노트에서 작성되었습니다.

공지사항
많은 분들이 닌텐도 DS용 한글 입력 메모장을 쓰고 계시는데,
주의사항이 있어서 알려드립니다.

한글 입력 메모장은 기존 버전과 호환성을 위해 한 페이지에 쓸 수 있는 글 량이 제한되어 있습니다.
스크롤이 없는 이전 버전은 쓸 수 있는 최대 길이가 한 페이지를 꽉 채우는 정도 였습니다.

따라서 한글로 가득 채운다면 220자 정도, 영문으로 가득 채운다면 440자 정도가 최대이니

적당히 채우시고(?) 다음 페이지로 이동하시기 바랍니다. ㅠㅠ

나중에 시간이 나면 업데이트할 때 이를 표시해주는 기능을 넣을 예정이니
불편하시더라도 주의해서 쓰시기 바랍니다.


 드디어 닌텐도 DS(NDS)용 한글 입력 메모장 프로그램 v1.2가 나왔습니다. 많은 분들이 건의하셨던 커서 이동 기능과 메모 스크롤 기능이 추가되었습니다. 이제 메모를 수정하기위해 전체를 수정하지 않아도 됩니다. ^^)/~

 데이터 파일은 기존의 1.1 버전과 호환되므로 NDS 파일만 교체하시면 정상적으로 수행됩니다. ^^
사용자 삽입 이미지

 다만 에디트 박스 컨트롤이 완전하지가 않아서 커서 이동 시에 한글 처리가 미흡합니다. ^^;;; 그 때문에 한글을 삭제하실 때 주의하실 점이 있습니다.

 1. 한글을 지우실 때 커서를 한글 뒤쪽에 위치시킨다음 백스페이스를 2번 눌러주셔야합니다. 만약 한번만 누르시면 글자가 깨어집니다. 깨어졌을 경우 한번 더 백스페이스를 눌러주시면 정상적으로 표시됩니다.

 2. 커서가 한글의 가운데에 위치했을 때 백스페이스를 누르시면 역시 글자가 깨어집니다. 물론 이때 커서를 오른쪽으로 한칸 이동한 다음 다시 백스페이스를 누르면 깨끗하게 지워집니다.

 한글이 원래 2자리를 차지하기때문에 발생하는 문제인데, 다음 버전에 수정할 계획입니다. 급히 릴리즈하느라 소프트웨어 리셋 부분 또한 완전히 처리하지 못했는데, 다음 버전에 같이 수정하여 릴리즈하겠습니다. ^^;;;

 아래는 홈브루 파일입니다.
DLDI 패치는 필수입니다 ^^ http://kkamagui.tistory.com/469 를 참고하세요 ^^;;


================ Version History ================
Version 1.2 - http://kkamagui.tistory.com/468 참고
1. 커서 표시 및 이동 기능 : 내용을 수정하려면 백스페이스를 이용해서 데이터를 모두 지웠던 불편함 때문에 추가. 윈도우의 에디트박스와 같이 커서를 표시하고 커서 위치를 통해 추가/수정/삭제하도록 변경함. 커서 이동은 왼쪽 방향키로 가능
2. 메모장 스크롤 기능 : 메모를 최대 한 페이지까지 밖에 입력하지 못했던 불편함 때문에 추가. 커서를 이용해서 스크롤 가능하도록 변경함


Version 1.1 - http://kkamagui.tistory.com/410 참고
1. 소프트웨어 리셋 기능 : "START" 버튼을 클릭하여 펌웨어 시작화면으로 돌아가는 기능 추가. 파워를 껏다가 켜야했던 기존의 불편함을 줄임
2. TXT 추가 기능 : 메모 페이지에서 "A"버튼을 누르면 루트 디렉토리에 DATA + 페이지번호 +.txt 형식으로 txt 파일을 생성. PC에서 데이터 파일 공유 가능
사용자 삽입 이미지
3. 메모 페이지 확장 : 메모장의 페이지를 40 페이지를 확장. 기존의 20 페이지용 데이터 파일의 경우, 안전한 사용을 위해 모든 데이터를 백업해 놓고 루트 디렉토리에 있는 NOTEDATA.DAT 파일을 삭제하길 권장

Version 1.0 - http://kkamagui.tistory.com/238 참고
1. 완성형 한글/영문/숫자 입력 기능 : 완성형 한글 오토마타를 이용하여 한글 조합 및 출력 가능. 실제 키보드와 거의 동일하게 자판을 배열하고 구성함. Shift 키와 Delete 키를 지원하고 Space바 좌측의 모드 변환 키를 통해서 키보드의 타입 변경 가능.
2. 메모 입력 기능 : 1줄당 최대 영문 42자 or 한글 21자 입력 가능. 최대 10줄까지 입력가능.
3. 메모 페이지 이동 기능 : 메모 페이지를 최대 20장까지 지원. 키보드 상단의 "<<" or ">>" 버튼으로 메모 페이지 이동가능. 최상단에 현재 페이지 번호 표시.
4. 메모 내용 저장 기능 : 페이지 이동 시 or ""저장" 버튼 클릭 시 메모를 저장하는 기능. NDS 재시작 후에도 이전 메모 기록 확인 가능


 버그는 블로그의 덧글로 부탁드립니다. ^^)/~

 그럼 좋은 하루 되세요 ^^)/~


 ㅜ_ㅜ... 한시간 내내 여자친구랑 디자인했습니다. 어찌 될지는 모르겠지만 좀더 손 본 다음에 올리겠습니다. ㅜ_ㅜ)/~

 화면 구성만 한시간 내내 했네요. ㅜ_ㅜ... 천지 이런... 흑흑... ㅜ_ㅜ

 왠지 허무한듯한... ㅠ_ㅠ 아우...

사용자 삽입 이미지



 드디어 새로 만든 에디트 박스를 한글 입력 메모장 홈브루에 적용했습니다. 기본적인 기능은 1.1 버전과 거의 동일하니 기본 기능에 대한 내용은 http://kkamagui.tistory.com/410 을 참고하시면 됩니다.

 아래 화면에서 붉은 색으로 표시된 것이 커서이고, NDS의 왼쪽 방향키를 이용해서 움직일 수 있습니다. 물론 스크롤 또한 가능합니다. ^^)/~
사용자 삽입 이미지


 
주의해야 할 것은 삭제 단위가 한글 단위가 아닌 영어 단위라서 한글을 삭제할 때는 2번 Backspace를 눌러줘야 한다는 것입니다. 한번만 누르실 경우, 이상한 글자가 표시되는데 당황하지 마시고 한번 더 누르시면 깨끗하게 지워집니다.

 지울 부분의 데이터를 분석해서 한글이면 2자를 지우게 하는 것도 가능하지만 커서의 위치와 밀접한 관련이 있어서 손보기가 쉽지 않더군요. ㅜ_ㅜ 일단 어느 정도 안정화된 뒤에 처리할 생각입니다. ^^;;;

 현재 테스트 버전에서는 입력 한계가 없으나 저장할 때 잘려서 저장되니 너무 많이 입력하시면... 잘려서 나올지도... ㅜ_ㅜ;;;;

 혹시 버그가 있으면 덧글로 제보 부탁드립니다. ^^)/~
 그럼 좋은 하루 되세요 ;)



 미디어 다음에 재미있는 글이 있더군요. "속도 느린 `윈도 비스타` PC산업 성장 가로막는다" 라는 글이던데,
http://photo.media.daum.net/photogallery/economic/economy_others/view.html?photoid=3177&newsid=20080512082511506&cp=mk 에서 보실 수 있습니다.

 전체적으로 느린 비스타로 인해 비스타가 탑재되는 PC 수요가 크게 늘지 않고, 사도 XP로 다운그레이드해서 쓴답니다. ㅎㅎ 뭐랄까요... 어느정도 공감합니다. 아무래도 사양이 너무 높고 XP에 비해서 느린 건 사실이니까요.

 특히 커널이 업그레이드되어 드라이버쪽 작업하기도 힘들고... 아무래도 옮겨타기에는 무리가 있지요. ㅎㅎ 사용자도 사용자지만, 개발자에게도 타격이 큽니다. ㅎㅎ

 다음 버전의 운영체제는 어떻게 될지 모르겠지만... 개발자에게도 사용자에게도 편리한(?) 운영체제를 만들어 줬으면 좋겠습니다. ^^;;;;
 이사오면서 집에 놀고 있는 노트북이 하나 생겼는데, 어떻게 사용해야할지 고민입니다. ㅜ_ㅜ 리눅스를 깔아서 써볼까 생각하고 있지만, 뭔가 더 재미있는 것이 있을 것 같아서 미루고 있습니다.

 하라는 개발은 안하고 뭔 고민을 이렇게 하고 있는지 저도 모르겠습니다만, 촉(?)이 지금 바짝 서있어서 ㅎㅎㅎ 혹시 좋은 생각 있으신 분 있으시면 제보 부탁드립니다. ^^)/~

 그럼 다들 좋은 밤 되세요 ;)
 밤에 피곤한 상태로 코딩을 해서 그런지 버그 테스트가 확실히 안됬더군요. 요리조리 테스트 해보고 있는데 로직에 버그가 장난이 아닙니다. ㅜ_ㅜ)/~ 이거 NDS 메모장에 업데이트 할려면 시간이 좀 걸리겠습니다. ㅜ_ㅜ

 어제는 옥션에서 주문한 소파 침대가 와서 정리하느라고 컴퓨터할 시간도 없었습니다. 싼맛에 샀더니만 석유냄새도 심하고 천도 엉망이더군요. 하루 정도 밖에서 말리니 겨우 쓸 수 있을 정도는 됬습니다만... 뭐랄까... 살살 올라오는 석유냄새란... ㅜ_ㅜ

 주말에 시간 좀 내서 에디터에 버그도 수정하고 NDS에 적용도 해야겠습니다.
 (과연 할 수 있을지 의문이 드네요. ㅜ_ㅜ)

 그럼 좋은 밤 되세요 ^^)/~


 원래 계획은 오늘 NDS로 포팅을 시작하는 것이었는데, 시험을 치다보니 시간이 늦어서 결국 포기했습니다. ㅜ_ㅜ 요즘 잠도 잘 못자서 얼굴이 뒤집어졌는데, 포팅을 시작하게 되면 끝날 때까지 안잘 것 같아서... ^^;;;

 대신 어느 정도 완성된 에디트 박스(Edit Box)를 올립니다. Version은 아직 버그가 좀 있을 수 있기 때문에 0.9로 했습니다. ^^ 아래는 직접 키보드를 이용해서 메모를 변경하고 추가한 화면입니다.
사용자 삽입 이미지 사용자 삽입 이미지

 방향키로 커서 이동이 가능하고 키보드로 알파벳, 스페이스, 엔터 그리고 백스페이스를 사용할 수 있습니다.

 내일까지 테스트 해본 후에 큰 버그가 없으면 함수 좀 정리해서 NDS에 포팅해야겠습니다. ^^)/~ 별 문제 없이 끝났으면 좋겠네요. ㅎㅎ 이제 커서 이동까지 가능해지면 그동안 빗발쳤던(??) 요구사항을 어느정도 수렴한듯 하니까요. ^^;;;;

 엇~ 벌써 시간이 이렇게나... 이만 자야겠습니다. ^^)/~
 다들 좋은 밤 되세요 >ㅁ<)/~


 오늘 후배가 꽤나 괜찮은 링크를 보내주더군요. ^^)/~ 후배의 블로그( http://www.filewiki.net/tc/entry/PSP-%EA%B0%9C%EB%B0%9C%EC%97%90-%EB%8C%80%ED%95%9C-%EC%9E%90%EB%A3%8C ) 에서 찾았습니다. ㅎㅎ

 한글로 된 자료를 찾으시는 분들이 많으시던데, 희소식이 되겠군요. ^^)/~


 그럼 좋은 하루 되세요 ;)
 요 근래 작업을 좀 한다고 무리해서 그런지 얼굴이 완전 뒤집어졌습니다. 거의 3일만에 갑자기 조그만 여드름같은 것들이 올라오더니 얼굴을 뒤덮었네요. ㅜ_ㅜ... 오늘 부랴부랴 피부과에 갔는데 과로 아니면 음주/담배가 원인일 것 같다고 했습니다. ㅜ_ㅜ)/~

 제가 볼때는 아무래도 음주와 과로... 그 중에서도 과로가 가장 큰 원인이 아닌가 싶은데... 좀 자제를 해야겠군요. ㅎㅎ 일찍 자야겠습니다.

 그 와중에도 에디터를 손봐서 어느정도 테스트를 끝냈습니다. 조금만 더 하면 NDS 메모장에 올릴 수 있을 것 같네요. ㅎㅎ

 그럼 다들 건강 조심하시고 무리하지 마세요 ;)

 휴가를 틈타 NDS 메모장 홈브루를 손보려고 집에 PC 뒤졌는데, 옛날 소스 밖에는 없더군요. ㅜ_ㅜ 그래서 제 스프링노트(http://kkamagui.springnote.com)와 블로그(http://kkamagui.tistory.com)를 검색했더니 역시나... ㅜ_ㅜ

 다른 소스는 다 올려놨으면서 이 소스는 왜 안올려 놓은건지... 하는 수 없이 윈도우 환경에서 구현하기로 했습니다. NDS를 하다말고 갑자기 왠 윈도우냐 하시는 분이 계실지 모르겠습니다. ^^;;;
 
 NDS용 메모장 홈브루는 제가 틈틈이 만든 NDS 윈도우 라이브러리(http://kkamagui.tistory.com/37)를 기반으로 작성되었기 때문에, 윈도우 환경(MFC)과 매우 유사하기 때문에 가능한 것이지요. 개발을 편하게 진행하기 위해서 필요한 부분만 최대한 비슷하게 구현했습니다.

 현재 커서와 데이터 출력, 스크롤 부분까지 처리가 끝났고 이제 남은 것은 커서가 있는 부분을 위주로 추가/수정/삭제하는 부분만 추가하면 되는데... NDS의 한정된 메모리를 사용해야 하기 때문에, 어떻게 하는 것이 좋을지 상당히 고민스럽습니다. 일단은 좀 더 생각해봐야겠습니다. ^^;;;;

 아래는 실제 구현된 에디트 박스의 모습입니다. 글자 사이에 있는 빨간 선이 커서를 나타내고 제일 바깥쪽에 있는 붉은 색 선은 NDS의 LCD 영역을 나타냅니다.

사용자 삽입 이미지
사용자 삽입 이미지
사용자 삽입 이미지
사용자 삽입 이미지


 


























 아래에 첨부된 압축파일을 풀어서 실행하면 간단한 테스트 해볼 수 있으니, 심심하시면 한번... ^^)/~ 키보드의 화살표 키로 커서를 이동할 수 있으며, 그에 따른 커서 위치 처리와 스크롤에 관한 처리를 테스트 할 수 있습니다. ^^


 아아~ 생각보다 진도가 안나가는 군요. ㅜ_ㅜ)/~
 그럼 다들 좋은 밤 되시길~



 학교 후배에게 뽐뿌를 해서 PSP를 지르게 만들었습니다. 그런데 이녀석이 홈브루를 개발한답시고 VS.net 2008용 App Wizard를 만들더군요.

 AppWizard는 후배의 블로그(http://www.filewiki.net/tc/entry/PSP-%EA%B0%9C%EB%B0%9C-AppWizard)에서 다운받을 수 있습니다.
 
사용자 삽입 이미지

 VS.net 환경에 익숙한 분이시라면 더욱 편리하게 사용하실 수 있을 것 같습니다. ^^)/~


 아아~ 이거 힘드네요. ㅜ_ㅜ 일단 RSS를 통해 티스토리에서 댓글만 뽑아내려고 했는데, 잘 안되서 파이썬으로 파싱하는 걸로 방향을 바꿨습니다. 파이썬 라이브러리 중에 Beautiful Soup를 사용해서 간단히 파싱하여 댓글을 추출하는 것까지는 금방했습니다.

 그런데 문제는 UTF-8로 인코딩된 웹페이지를 파일로 저장하려니 ASCII로 저장하는 것이 기본인지 저장할 수 없다는 에러가.... 이렇게 황당한 일이... ㅡ_ㅡa... 파이썬을 쓰면서 한글 처리를 별로 안해서 크게 불편함을 몰랐는데, 이번에 제대로 걸렸네요. ㅜ_ㅜ

 이래 저래 해보다가 결국 포기 ㅜ_ㅜ)/~ 차라리 티스토리에 웹페이지를 하나 더 넣어서 댓글만 표시하게 하는게 더 편하겠습니다. ㅜ_ㅜ)/~

 댓글 추출하는 소스는 만든게 아까워서 올려놓습니다. 애휴... 밥이나 먹어야겠군요. ㅜ_ㅜ)/~




 ps) 아아... 이게 무슨 삽질인지... 쉽게 처리하는 방법을 아시면 댓글로 제보 부탁드립니다.


 점프 투 파이썬의 저자이신 박응용님께서 책의 내용을 공개해 놓으셨습니다. 책 내용은http://wikidocs.net/mybook/read/library?pageid=1 에서 보실 수 있습니다. 테스트 주도 개발(TDD)에 대한 내용도 있더군요. 관심 있으신 분은 한번쯤 들러보시면 좋을 것 같습니다.

사용자 삽입 이미지

 예전에 파이썬 공부할때 많이 봤던 책인데, 이렇게 웹에서 보게되니 반갑네요. ㅜ_ㅜ)/~ 박응용님 블로그(http://tdd.or.kr/tddlog/)에도 잠깐 들렀는데... 참 대단하신 분인것 같습니다. 직장생활 하시면서 저렇게 많은 웹서비스를 개발하다니... 역시 하기나름인 것 같습니다(저도 열심히 @0@)/`!!!).

 파이썬 만세~ >ㅁ<)/~!!~

 

 대박 연휴를 맞아 집에 내려오게됬습니다. 집에서 인터넷으로 열차시간을 확인한 뒤, 역으로 왔더니 고새 매진이더군요. ㅡ_ㅡa... 어쩔 수 없어 한시간 뒤 기차를 예매하고 서점으로 갔습니다. 역에 갈때마다 한번씩 들리는 버릇이 생겼거든요. ^^;;;;

 제일 먼저 마이크로소프트웨어 5월호를 들었습니다. 하는 일이 응용 프로그램과 거리가 멀다보니, 위쪽(?) 소식이 많이 궁금합니다(좋은 소식 덧글로 많이 전해주세요 ㅜ_ㅜ...). 마소 기사 목록을 죽 훓어보다보니 블로그 관리를 위한 툴에 대한 기사가 있던데, 갑자기 뭔가 번득하더군요. @0@)/~

 블로그에 수시로 들러서 글쓰고 답글을 달지만, "블로그"에서 그 일을 해야한다는 고정관념 같은게 있었습니다. ㅡ_ㅡa. 그런데 저 기사 제목을 보고 나니 당장 툴을 만들어야겠다는 생각이 들더군요. 일일이 덧글 목록을 살펴서 답글을 달다보면 보지 못하고 넘어가는 덧글이 종종있거든요. ^^;;;;(혹시 제가 덧글에 답글을 달지 않았다면, 이 자리를 빌어 죄송하다는 말씀을 드립니다. (__) 일부러 안단게 아니니 용서해주세요 ㅜ_ㅜ)

 연휴 기간에 덧글을 검색하는 테스트 프로그램부터 간단히 만들어볼까 생각중입니다. Python으로 만들면 간단히 할 수 있을 듯도 한데, 원체 오래되서 기억이 가물가물하네요. ^^;;; 이번에는 OpenAPI를 사용해서 덧글 리스트를 뽑아봐야겠습니다. ^^)/~

 그리고 이전에 만들었던 NDS용 한글 메모장(http://kkamagui.tistory.com/410)PSP에 포팅할까 생각중인데, 그 이전에 한글 메모장부터 손볼 생각입니다. 메모장의 가장 큰 문제였던 커서 이동이 안되는 부분을 방향키를 이용해서 이동할 수 있도록 할까 합니다. 물론 커서도 추가해야겠지요. ^^)/~

 연휴에 푹 쉬나 했더니 이번 연휴도 바쁘겠군요. ^^)/~ 역시 천성이 개발자인듯 합니다. ㅎㅎ
 그럼 다들 좋은밤 되시길~ ^^

 흑흑... 원래 계획은 좀 일찍와서 청소를 하고, PSP 관련 정보를 올릴 생각이었는데... 예기치 못한 야근으로 인해 그냥 포기했습니다. 집에오니까 11시가 다 됬더군요. ㅎㅎ ㅜ_ㅜ

 또 다시 내일을 기약해봅니다. 오늘 할일은 내일로 미루자 @0@)/~~
 (그럼 내일은? ㅜ_ㅜ)

 그럼 다들 좋은 밤 되세요... ㅜ_ㅜ...


 원래 계획대로라면 PSP 한글 출력관련 작업을 해야되지만, 음주를 좀 심하게한 관계로 쉬어야겠습니다. ㅜ_ㅜ)/~ 내일은 일찍와서 꼭 정리해서 올리겠습니다. ㅜ_ㅜ)/~

 그럼 전 이만 휘리릭~!!! 쿨럭..;;;;

 PSP의 비디오 모드를 뒤지다 보니, 4BYTE RGB를 사용하는 FrameBuffer모드가 기본인 것 같았습니다. DebugPrint류의 함수를 곰곰히 살펴본 결과 U32의 값으로 비디오 주소에 계속 출력하고 있더군요. 이걸로 바로 확신이 섰습니다. ^0^)/~

 그래서 NDS에 만들어뒀던 한글 출력 라이브러리를 포팅할려고, 뚝딱 소스를 갖다 부었더니 뭔가 잘 안되더군요. ㅜ_ㅜ)/~ 한글이 출력되는 게 아니라 뭔 점같은게 출력됬습니다. 한참 소스를 뒤진 결과, 간단한 연산 버그가 있어서 그랬습니다. 교육 때 들었던 unsigned char과 int의 연산 문제를 제 소스에서 딱 마주치니 웃음이 실실... ㅜ_ㅜ...

 결국 그 문제를 해결하고 나니 화면에 한글이 나왔습니다. ㅜ_ㅜ)-b 아아~ 이 감명깊은 순간을 캡쳐로 저장했어야하는데 RemoteJoy라는 프로그램을 깔지 않아서.... 내일 집에 오는대로 RemoteJoy를 설치해서 캡쳐해 올리겠습니다. 물론 소스와 함께 말이지요 >ㅁ<)/~!!!

 그럼 다들 좋은밤 되세요 ^^)/~~


 블로그를 돌다가 헐랭이님(http://swbae.egloos.com/1747493) 블로그에서 보안관련 무료 잡지를 찾았습니다. @0@)/~ 이런 잡지가 있다니 깜짝 놀랄일이군요. ;)

 http://www.net-security.org/insecuremag.php에서 받아 보실 수 있습니다. 시간이 나면 한번 읽어봐야겠군요. 득탬해서 너무 기분이 좋습니다. ㅎㅎ
 
 다들 좋은 주말 보내세요 ;)


 어제 한 2시간을 시도했었는데, 결국 실패했습니다. ㅜ_ㅜ... 소니 정품 메모리만 되는 것인가요? ㅜ_ㅜ 메직 메모리로 설정하고 판도라 배터리를 만들었는데, 샌디스크 메모리라서 그런지 인식이 안되더군요. 흑흑...

 그래서 그냥 펌웨어 버전만 업데이트하고 말았습니다. ㅜ_ㅜ)/~ 쓰던 3.80 버전에 문제가 있는지 가끔 느려지는 경우가 있더군요. 3.90버전으로 올라갔는데 아직은 그런 문제가 안보이네요. 좀 더 테스트를 해보고 글 남기겠습니다. ^^)/~

 주말을 맞아 하루종일 PSP와 NDS를 가지고 놀아야겠네요.
 다들 좋은 주말 보내세요. ;)


 요즘 회사에서 C 언어 교육을 듣고 있습니다. 필수 교육이라고 해서 뭐 그냥 교양 C 수준이겠거니 생각했는데, 의외로 강의내용이 빵빵합니다. 특히 포인터와 배열쪽은 아주 개념을 제대로 잡아주는군요. @0@)/~ 애매하게 알고있었던 펑션 포인터 사용법도 알려주고, 정말 무슨 암호같은 포인터 + 배열 + ()의 앙상블(?)을 어떻게 해석하는지 포인트를 딱 집어줍니다(시간날때 내용을 한번 정리해서 올려야겠습니다). ㅜ_ㅜ)-b

 마지막은 여느 교육과 다름없이 프로젝트로 장식하더군요. 내일까지 발표를 해야하는데, 뭘할까 고민하다가 테트리스를 하기로 했습니다. 사실 만들어 놓은 소스도 있고 하니 그냥 포팅해서 긁어 붙일 심산이었지요. 왠만한 자료는 다 블로그나 스프링노트(http://kkamagui.springnote.com)에 있으니 테트리스 소스도 넣어뒀을꺼라 생각했는데, 믿는 도끼에 발등 찍힌다고.... ㅜ_ㅜ... 글쎄 없는겁니다. 흑흑... ㅠㅠ

 웹에서 검색해서 소스를 찾긴했는데, 뭔가 포팅하기 어려운 구조로 되있고... 결국 눈물을 흘리며 짜기 시작했습니다. 요 근래 코딩을 거의 하지 않은지라 코딩하는데 살짝 감이 안오더군요. ㅡ_ㅡa... 역시 뭐든 꾸준히 해야하나봅니다. ㅎㅎ

 블럭을 하나 하나 만들고, 자료구조 생성하고 뚝딱 뚝딱하다보니 한 4시간 정도가 지났을까요? 대충 돌아가는 테트리스 코드가 나오더군요. @0@... 지금까지 테트리스만 한 3번 정도 짰더니 이제 뭐 그냥 손에서 술술~ ㅎㅎ 과제가 끝나면 소스 그대로 가져와서 PSP에 한번 올려볼까 생각중입니다.

 지금 S3C2440에서 작성되어있는데, 시리얼 케이블을 연결하면 2명이서 대전할 수 있는 구조로 되있거든요 ;). PSP에 좀 더 손봐서 Wifi나 Ad-hoc 통신으로 패킷을 주고받아 대전 가능하게 만들어도 괜찮을 것 같습니다.

 간만에 코딩하니 기분이 너무 좋네요. ;)
 역시 천성이 개발자인가 봅니다. ^^)/~
 

 얼마전에 제 블로그에 태용님께서 조그만 선물을 해주시겠다는 댓글을 남기셨습니다. 재미있는 장난감이라고 하시길래, 게임 시디나 괜찮은 셈플 어플리케이션이겠거니 생각하고 있었는데.... NDS용 닥터를... 그것도 무려 3종류나 기부해 주셨습니다. 태용님께서 홈브루 개발자를 지원하는 프로젝트를 진행하시는데, 제가 거기에 포함된 모양입니다. ㅜ_ㅜ... 이런 영광이.... ㅜ_ㅜ

 아래는 기부해주신 닥터의 사진입니다. DSTT, Acekard2, Acekard R.P.G 3종류입니다.
사용자 삽입 이미지
사용자 삽입 이미지
사용자 삽입 이미지

 제가 쓴 글이 다른 분에게 도움이 되고, 그걸로 인해 제가 다시 도움을 받게 될 줄은 몰랐습니다. 왠지 얼떨떨한 기분이군요. ^^;;;; 뭐랄까... 마치 외국에서만 가능할꺼라고 생각했던 일이 저한테 닥치니... 기분이 굉장히 좋습니다. 안그래도 가지고 있는 구형 NDS에 오래된 M3 SD가 달려있어서 동생이 고생하곤했는데, 이제는 그럴 일이 없겠군요. ^^)/~

 태용님께서 기부해주신 닥터는 더 열심히 개발하고, 홈브루 릴리즈할 때 테스트를 열심히 하라는 뜻인 것 같습니다(맞는가요? ㅎㅎ ^^;;;;). 열심히 하겠습니다. >ㅁ<)/~ 그리고 나중에 시간나면 제가 갖고있는 닥터와 비교해서 리뷰도 하나 쓰겠습니다.

 마지막으로 얼굴도 모르는 저에게 이런 멋진 선물을 주신 태용님께 다시 한번 깊은 감사를 드립니다. ^ㅡ^)/~

 그럼 다들 좋은밤 되세요~


 제 PSP의 커스텀펌웨어 버전은 3.80입니다. 그런데 이 놈이 뭔가 좀 불안한 구석도 있고 동작이 이상하게 될 때도 있어서 펌웨어 업데이트를 찾아보고 있었습니다. 한참을 찾다보니 다크 알렉스(Dark Alex)의 홈페이지가 나오더군요. 정말 여러 버전의 커스텀펌웨어(커펌)를 개발했던데, 완전 킹왕짱입니다. ㅎㅎ 다크 알렉스의 사이트는 http://www.dark-alex.org 이니 관심있으신 분은 한번 들어가보세요. ^^)/~

 다크 알렉스의 사이트에 1.5 Custom Firmware 코드가 있길래 뭔가해서 살펴봤더니 1.5 펌웨어에 패치를 수행하는 코드인 것 같더군요. 그중에서 recovery 소스를 열어봤는데, USB를 사용하는 코드가 있었습니다. 딱봐도 한눈에 알수있던데, USB 제어하는 코드가 flash:0 영역에 모듈형태로 들어있더군요.

  정말 한눈에 딱 봐도 알 수 있지 않습니까? LoadStartModule()함수가 flash:0에서 커널로 로드해주고 있습니다. ^^)/~ PSP 커널은 정말 괴물이군요. 이정도까지 지원해 주다니... 이거 원 홈브루에서는 따로 손댈것도 없을 것 같습니다. 정말 NDS 홈브루를 개발할 때와 너무 비교되는군요.

 어쩌면 이런 지원때문에 NDS보다 PSP가 하드웨어적으로 분석된 자료가 적은 건지도 모르겠습니다. 다들 스펙 정도만 적혀있을 뿐이지 실제 구성도나 포트 I/O 같은 자료는 없더라구요(혹시나 PSP에 대한 자료를 갖고 계신분은 제보 부탁드립니다. ^^;;;).

 그나저나 커펌 버전을 높여야할지 고민입니다. 3.90 M33 버전이 안정적인지도 모르겠고... 아아~ 진짜 고민됩니다. ㅜ_ㅜ... 이걸 어찌해야할까요?


01 따라하는 PSP 홈브루 개발 - Hello World 출력

원문 :http://kkamagui.springnote.com/pages/1075736

 

들어가기 전에...

 

0.시작하면서...

 이 글은 PSP 홈브루(Homebrew)를 Step by Step 형식으로 개발할 수 있도록 도와주는 문서이다. PSP SDK를 사용하는 방법만 단순히 설명하기보다 PSP의 전체적인 동작 방식과 흐름과 함께 설명하는데 목적을 두고 있다. 이번 회에서는 Hello World를 출력하는  간단한 홈브루를 구현해 볼 것이며, 더불이 PSP Kernel과 PSP 응용프로그램의 연결고리도 함께 살펴볼 것이다.

 

1.예제 소스코드

 아래는 처음으로 작성하는 "Hello World" 프로그램이다. 아래의 코드를 DevkitPSP로 컴파일 및 링크하면 EBOOT.PBP 파일을 얻을 수 있다. 이 파일을 메모리스틱에 PSP->GAME->TEST 폴더로 복사하면 PSP Home Menu의 Game 항목에서 볼 수 있다.

  1. #include <pspkernel.h>
    #include <pspdebug.h>

    // 매크로 정의
    #define TRUE 1
    #define FALSE 0
  2. #define printf pspDebugScreenPrintf

    /* Define the module info section */
    PSP_MODULE_INFO("KKAMAGUI", 0, 1, 1);

    /* Define the main thread's attribute value (optional) */
    PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER | THREAD_ATTR_VFPU);

    // 종료 Flag
    int g_bExit = FALSE;

    int ExitCallBack(int arg1, int arg2, void *common)
    {
        printf( "%X %X", arg1, arg2 );
        g_bExit = TRUE;
        return 0;
    }
     
    int main(int argc, char *argv[])
    {
        int cbid;

        pspDebugScreenInit();

        // Call Back 설정
        cbid = sceKernelCreateCallback("Exit Callback", ExitCallBack, NULL);
        sceKernelRegisterExitCallback(cbid);
       
        printf("Hello World\n");

        while( g_bExit == FALSE )
        {
            ;
        }
        sceKernelExitGame();
        return 0;
    }

 

2.예제 소스코드 분석

 그럼 지금부터 위의 소스를 하나하나 분석해보자. 우선 가장 처음에 나오는 PSP_MOUDLE_INFO() 매크로는 pspmoduleinfo.h 파일에 정의되어있으며, 아래와 같이 특수한 섹션(.lib.ent.XX, .lib.stub.XX)에 데이터를 삽입하도록 되어있다. 주석을 보면 Source 파일에 반드시 있어야 한다고하니 필수 요소인 듯 하며, 나중에 PSP Kernel이 Load할 때 참고하는 정보임을 추측할 수 있다. 그냥 필수적으로 타이핑해야 하는 부분이라고 생각하면 된다.

 
  1. // pspmoduleinfo.h
  2. /* Declare a module.  This must be specified in the source of a library or executable. */
    #define PSP_MODULE_INFO(name, attributes, major_version, minor_version) \
        __asm__ (                                                       \
        "    .set push\n"                                               \
        "    .section .lib.ent.top, \"a\", @progbits\n"                 \
        "    .align 2\n"                                                \
        "    .word 0\n"                                                 \
        "__lib_ent_top:\n"                                              \
        "    .section .lib.ent.btm, \"a\", @progbits\n"                 \
        "    .align 2\n"                                                \
        "__lib_ent_bottom:\n"                                           \
        "    .word 0\n"                                                 \
        "    .section .lib.stub.top, \"a\", @progbits\n"                \
        "    .align 2\n"                                                \
        "    .word 0\n"                                                 \
        "__lib_stub_top:\n"                                             \
        "    .section .lib.stub.btm, \"a\", @progbits\n"                \
        "    .align 2\n"                                                \
        "__lib_stub_bottom:\n"                                          \
        "    .word 0\n"                                                 \
        "    .set pop\n"                                                \
        "    .text\n"                                                    \
        );                                                              \
        extern char __lib_ent_top[], __lib_ent_bottom[];                \
        extern char __lib_stub_top[], __lib_stub_bottom[];              \
        SceModuleInfo module_info                                       \
            __attribute__((section(".rodata.sceModuleInfo"),        \
                       aligned(16), unused)) = {                \
          attributes, { minor_version, major_version }, name, 0, _gp,  \
          __lib_ent_top, __lib_ent_bottom,                              \
          __lib_stub_top, __lib_stub_bottom                             \
        }

 

 그 다음에 오는 PSP_MAIN_THREAD_ATTR() 매크로는 pspmoduleinfo.h에 정의되어있으며 변수에 값을 설정하는 간단한 역할만 한다. Optional한 부분이므로 굳이 쓰지 않아도 되나, 만약의 사태를 대비해서 일단 추가해 두자.

  1. // pspmoduleinfo.h 파일에 포함된 내용
  2. /* Define the main thread's attributes. */
    #define PSP_MAIN_THREAD_ATTR(attr) \
        unsigned int sce_newlib_attribute = (attr)

 Thread의 Attribute는 pspthreadman.h 파일에 있으며 아래와 같이 정의되어있다. PspThreadAttributes에 나와있는 주석을 보면 Thread의 종류에따라 Device에 접근할 수 있는 범위가 제한됨을 알 수 있다. 아직은 USB나 WLAN을 접근할 일이 없지만, 추후에 접근할 일이 생기면 Thread의 목적에 맞게 Type을 설정해야 하는 듯 하다. 이런 것도 있다는 것만 알고 넘어가자.

  1. /** Attribute for threads. */
    enum PspThreadAttributes
    {
        /** Enable VFPU access for the thread. */
        PSP_THREAD_ATTR_VFPU = 0x00004000,
        /** Start the thread in user mode (done automatically
          if the thread creating it is in user mode). */
        PSP_THREAD_ATTR_USER = 0x80000000,
        /** Thread is part of the USB/WLAN API. */
        PSP_THREAD_ATTR_USBWLAN = 0xa0000000,
        /** Thread is part of the VSH API. */
        PSP_THREAD_ATTR_VSH = 0xc0000000,
        /** Allow using scratchpad memory for a thread, NOT USABLE ON V1.0 */
        PSP_THREAD_ATTR_SCRATCH_SRAM = 0x00008000,
        /** Disables filling the stack with 0xFF on creation */
        PSP_THREAD_ATTR_NO_FILLSTACK = 0x00100000,
        /** Clear the stack when the thread is deleted */
        PSP_THREAD_ATTR_CLEAR_STACK = 0x00200000,
    };

 

다음은 ExitCallBack() 함수인데, 이 부분은 뒤에 sceKernelRegisterExitCallback() 함수를 설명하면서 같이 진행하기로 하고 main() 함수를 먼저 보자. main() 함수에서 제일 먼저 우리를 반기는 것은 pspDebugScreenInit() 함수다.  pspDebugScreenInit() 함수는 과연 무엇을 하는 함수일까? 함수가 psp라는 Prefix로 시작하는 것을 보아 PSP Library 함수임을 알 수 있으며 실제 함수의 구현부를 보면 아래와 같이 되어있다.

  1. // scr_printf.c 파일의 일부
  2. #define PSP_SCREEN_WIDTH 480
    #define PSP_SCREEN_HEIGHT 272
    #define PSP_LINE_SIZE 512
    #define PSP_PIXEL_FORMAT 3
  3. ... 생략 ...
  4. void pspDebugScreenInit()
    {
       X = Y = 0;
       /* Place vram in uncached memory */
       g_vram_base = (void *) (0x40000000 | (u32) sceGeEdramGetAddr());
       g_vram_offset = 0;
       sceDisplaySetMode(0, PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT);
       sceDisplaySetFrameBuf((void *) g_vram_base, PSP_LINE_SIZE, PSP_PIXEL_FORMAT, 1);
       clear_screen(bg_col);
       init = 1;
    }

 코드에서 Display Mode를 408x272로 설정하고 Display할 데이터가 있는 주소 즉 Graphic Buffer를 FrameBuffer로 설정하는데, g_vram_base를 시작 주소로 설정하는 간단한 코드이다. PSP_LINE_SIZE는 확실치는 않지만 한 라인에 대응하는 Pixel의 수인 듯 하다. SCREEN_WIDTH가 480이고 PSP_LINE_SIZE가 512인 것으로 보아, 여유있게 잡았거나 Align하는 단위의 문제 때문에 좀 더 크게 잡은 것이 아닐까 추측한다. pspDebugScreenPrintf() 함수는 printf() 함수와 하는 역할이 거의 비슷하니 다음 함수로 넘어가겠다. 혹시 세부 구현이 궁금하다면 scr_printf.c 파일에 나와있으므로 관심있으면 참고하자.

 

 pspDebugScreenInit() 함수 아래를 자세히 보면 sceKernelXXX로 시작하는 함수를 볼 수 있다. 이 함수는 sceXXX Prefix로 시작되며, 이것은 PSP의 Kernel Service(Function)임을 나타낸다. sceXXX 로 시작하는 함수는 PSP Kernel로부터 Import 되는 함수로서, PSP Kernel이 프로그램을 로딩하면서 해당 영역에 실제 함수 주소를 연결해 주는 것 같다. 실제로 sceKernelCreateCallback() 함수의 정의를 따라가보면 구현은 없고 아래와 같은 Dummy Table만 볼 수 있다.

  1. // ThreadManForKernel.S 파일의 일부분
  2.     .set noreorder

    #include "pspimport.s"

    #ifdef F_ThreadManForKernel_0000
        IMPORT_START    "ThreadManForKernel",0x00010000
    #endif
    #ifdef F_ThreadManForKernel_0001
        IMPORT_FUNC    "ThreadManForKernel",0x0C106E53,sceKernelRegisterThreadEventHandler
    #endif
    #ifdef F_ThreadManForKernel_0002
        IMPORT_FUNC    "ThreadManForKernel",0x72F3C145,sceKernelReleaseThreadEventHandler
    #endif
    #ifdef F_ThreadManForKernel_0003
        IMPORT_FUNC    "ThreadManForKernel",0x369EEB6B,sceKernelReferThreadEventHandlerStatus
    #endif
    #ifdef F_ThreadManForKernel_0004
        IMPORT_FUNC    "ThreadManForKernel",0xE81CAF8F,sceKernelCreateCallback
    #endif
  3. ... 생략 ...

 IMPORT_FUNC는 pspimport.s 에 포함된 매크로로서 pspimport.s는 아래와 같이 어셈블리어 코드로 치환해주는 역할만 한다. 아래의 IMPORT_FUNC의 가운데 정도에 위치한 .ent 부분이 Loading 후에 실제로 Function Address로 치환되며, 이 위치의 Function Address를 사용하는 것으로 추측된다.


  1. .macro IMPORT_START module, flags_ver

        .set push
        .section .rodata.sceResident, "a"
        .word   0
    __stub_modulestr_\module:
        .asciz  "\module"
        .align  2

        .section .lib.stub, "a", @progbits
        .global __stub_module_\module
    __stub_module_\module:
        .word   __stub_modulestr_\module
        .word   \flags_ver
        .word   0x5
        .word   __executable_start
        .word   __executable_start

        .set pop
    .endm

    .macro IMPORT_FUNC module, funcid, funcname

        .set push
        .set noreorder

        .extern __stub_module_\module
        .section .sceStub.text, "ax", @progbits
        .globl  \funcname
        .type   \funcname, @function
        .ent    \funcname, 0
    \funcname:
        .word   __stub_module_\module
        .word   \funcid
        .end    \funcname
        .size   \funcname, .-\funcname

        .section .rodata.sceNid, "a"
        .word   \funcid

        .set pop
    .endm

    .macro IMPORT_FUNC_WITH_ALIAS module, funcid, funcname, alias

        .set push
        .set noreorder

        .extern __stub_module_\module
        .section .sceStub.text, "ax", @progbits
        .globl  \alias
        .type   \alias, @function
    \alias:
        .globl  \funcname
        .type   \funcname, @function
        .ent    \funcname, 0
    \funcname:
        .word   __stub_module_\module
        .word   \funcid
        .end    \funcname
        .size   \funcname, .-\funcname

        .section .rodata.sceNid, "a"
        .word   \funcid

        .set pop
    .endm

 

 예제의 하부에 있는 sceKernelCreateCallback() 함수는 CallBack Function의 Name과 Function Address, 그리고 Parameter를 받아서 Calback ID를 생성하여 반환한다. 이 반환된 ID를 등록하면 Callback 함수가 동작하는데, 테스트 프로그램에서는 sceKernelRegisterExitCallback() 함수를 사용해서 PSP의 Home 버튼과 연결하였다. sceKernelRegisterExitCallback() 함수는 Program이 끝났을 때, 즉 PSP의 Home 버튼을 눌러서 "예"를 선택했을 때 Callback을 불러주도록 등록하는 역할을 한다.

 Callback 함수의 원형은 아래와 같이 총 3개의 파라메터를 받도록 되어있으며, ExitCallBack() 함수의 생김새와 동일함을 알 수 있다.

  1. // pspthreadman.h 파일의 일부
  2. /** Callback function prototype */
    typedef int (*SceKernelCallbackFunction)(int arg1, int arg2, void *arg);

 ExitCallBack() 함수는  sceKernelRegisterExitCallback()에 의해 등록되었으므로,PSP의 Home 버튼을 눌렀을 때 XMB로 돌아가기를 선택하는 경우 불려진다. 혹시 Home 버튼을 눌렀을때 뜨는 선택 화면에서 호출되는 것이 아닌지 궁금해 할지도 몰라서, 테스트 해보기 위해 아래의 printf() 기능을 넣었다. 만약 Home 버튼을 누른 후 표시되는 메뉴에서 CallBack이 호출된다면 "아니오"를 선택하고 빠져나왔을때 화면에 무엇인가 출력되었어야 한다. 하지만 아무런 값이 출력되지 않은 것을 보아 메뉴에서 "예"를 누른 후 호출되는 것을 알 수 있다.

  1. int ExitCallBack(int arg1, int arg2, void *common)
    {
        printf( "%X %X", arg1, arg2 );
        //g_bExit = TRUE;
        return 0;
    }

 

 마지막 함수는 sceKernelExitGame() 함수이다. sce Prefix가 붙어있으므로 PSP Kenrel Service 임을 알 수 있으며, 이 함수를 호출하면 다시 PSP 메뉴(XMB)로 이동하게 된다. 이 함수를 ExitCallback()에서 부르게 되면 충돌이 발생하여 메뉴로 돌아가지 못하고 멈추므로 주의해야 한다.

 

3.컴파일 및 실행

 DevkitPro가 설치된 폴더의 PSP Sample Code 폴더에 보면 elf_template 폴더가 있다(D:\devkitPro\devkitPSP\psp\sdk\samples\template\elf_template). 그 폴더의 main.c 파일에 예제 소스를 덮어쓰고 cmd.exe를 실행하여 make를 입력하면 EBOO 파일이 생성될 것이다. 이 파일을 PSP 메모리스틱에 H:\PSP\GAME\Test 폴더에 넣은 후, PSP 메뉴의 게임->Memory Stick에 가면 실행할 수 있다. 화면 우측 상단에 하얀색으로 빛나는 멋진 Hello World가 표시될 것이다. @0@)/~

 

 

4.마치면서...

 이것으로 Hello World를 화면에 출력하는 PSP 홈브루(Homebrew)를 완성하였다. 첫시간이니만큼 API의 사용법보다는 전체적인 소스의 구성 및 구조에 더 치중하려고 노력하였다. 다음은 PSP의 키입력 처리에 대해서 알아보도록 하자.

 

 

이 글은 스프링노트에서 작성되었습니다.

+ Recent posts