Class 2. ~한글화 강좌 - 중급 편~

 

 본 강좌는, 콘솔등의 에뮬레이터 게임롬의 한글화에 대해서 소개하고 있습니다. 초급편에 이어서 중급편을 집필하게 되었습니다.

중급편에서는 간단하게 대사 입/출력과 포인터의 사용법에 대해서 알아보도록 하겠습니다. 그 외 한글화에 필요한 테크닉 중에

"롬 확장""폰트 확장"등의 기술이 있으나, 저는 그 정도 수준까지는 알지 못하므로 강좌는 중급 편까지만 쓰도록 하겠습니다.

 본 강좌는 제가 작성한 "한글화 강좌 - 초급 편"에 이어서 작성된 것이므로, 혹시라도 이해가 되지 않는 부분이 있으시면 초급 편의

강좌를 참조하시기 바랍니다.

 

 - 목 차 -

1. 대사 추출

2. 대사 입력 관련 팁

3. 포인터란 무엇인가?

 

 

1. 대사 추출

 앞서서 초급강좌에서는 한글화를 하는 가장 기본적인 방법에 대해서 알아보았습니다. 하지만, 실제로 한글화를 시작하려고 하면 롬 안에 저장되어 있는

대사들을 모두 추출할 필요가 있습니다. 대사 추출 방법에는 여러 가지가 있고, 툴도 많지만 실제로는 거의 자작툴이 많아서 사용하기 까다롭습니다.

그래서 저는 "대사장"을 이용해서 대사를 추출하곤 합니다만, 이 방식은 비교적 고전적인 방식이라 시간이 오래걸리고 힘든 편입니다. 그래도 저는

자작 툴을 만들 능력이 안되서, 그냥 노가다로 대사를 뽑곤 합니다. 그럼 본론으로 들어가서, 일단 앞에서 헥스를 고칠 때처럼 대사장을 켜고 테이블표를

불러옵니다. 그리고 "Thingy 보기 활성화"를 체크하면 우측에 보라색 글씨로 글자들이 보입니다. 그런데, 이 글자들이 전부 다 대사인 건 아닙니다.

"글자의 배열을 보고서 대사인지 아닌지 확인해야 됩니다." 그렇기 때문에 일본어를 모르면 조금 난감할 수 있습니다. 대사추출 전에는 반드시 모든

제어코드를 다 분석해 놓아야 합니다. 게임에 따라서 2바이트를 차지하는 제어코드가 나올 때가 있는데, 그런 경우에는 대사가 제대로 추출되지 않습니다.

하여튼 Page Down 키를 이용해서 대사가 모여있는 곳을 찾아봅시다. 이 부분은 설명하기 어렵네요. 롬 내부를 처음부터 끝까지 스캔한다고 생각하면

될 듯 합니다. Page Down키를 누른 상태로 보라색 글씨 덩어리들이 많이 모여있는 부분을 찾아봅시다.

 자, 드디어 대사를 찾았습니다.(이거 찾느라고 무려 15분 걸렸음... ㅠ_ㅜ) 대사를 찾았으면 이제 할 일은 간단합니다. 대사 부분을 드래그합니다.

노란색으로 된 부분이 드래그 한 부분입니다. 초급강좌에서도 언급했지만, 좌측은 헥스 우측은 대사입니다. 어느 쪽을 드래그해도 상관은 없습니다.

편하신대로 고르시면 됩니다. 보통 대사 덩어리는 매우 크기 때문에, 드래그를 굉장히 많이 해야 합니다.

 자, 드디어 대사가 끝나는 부분까지 드래그를 했습니다. 이제 노란색으로 드래그 된 부분의 아무데나 마우스 우클릭을 하고 보시는 것처럼

"Thingy Copy"를 클릭하면 아래와 같은 창이 뜹니다.("Ctrl + C"를  눌러도 똑같이 아래와 같은 창이 뜹니다.)

 다른 거 건드릴 필요없이, 그냥 확인 만 클릭해주면 됩니다. 그러면 대사가 클립보드에 복사됩니다. 이 상태에서 아무 텍스트 프로그램(메모장도

상관없습니다만, 저는 주로 아래아 한글을 사용합니다.)에 붙혀넣기 하면 됩니다.

 그러면 위와 같이 대사가 추출됩니다. 이 대사는 철저히 고유번호표에 대입하여 추출된 것이기 때문에, 고유번호표에 잘못된 부분이 있으면 대사가

엉터리로 추출되므로 주의하시기 바랍니다. 위의 상태에서 대사를 정리해서 번역을 하고 패치를 하면 됩니다. 이것으로 대사추출 부분은 완료됩니다.

 

 

2. 대사 입력 관련 팁

 초급강좌에서 설명한대로, 대사입력의 기본 방식은 헥스 노가다입니다. 하지만 실제로 헥스노가다는 효율이 너무 떨어지기 때문에 보통 전용툴을 많이

사용한다고 앞서서 언급한 바 있습니다. 그런데 저는 전용툴을 만들 줄 모르기 때문에 계속 헥스 노가다를 했습니다만... 대사장을 이용해서 훨씬 편하게

패치할 수 있는 방법이 있습니다. (참조 링크) 일단 대사장을 열고 테이블표를 불러오는데, 한글 테이블표를 불러옵니다.

 보시는 것과 같이 한글로 바꾼 폰트를 기준으로 만들어진 테이블표를 불러옵니다. 그리고 패치를 할 대사가 있는 위치로 이동합니다.

 패치할 대사의 시작지점에 커서를 위치시키고 "ENTER"를 누르면 보시는 것처럼 대사입력창이 뜹니다. 흰색 대사창(?)에 글자를 입력하면 아래에

입력 될 대사와 해당 헥스가 뜹니다. 이 때, 입력한 글자가 테이블표에 없으면 스크린샷에서 보시다시피 그 글자는 표시되지 않습니다. 그러므로 아래에

표시되는 글자를 잘 확인하셔야 합니다. 이 상태에서 다시 ENTER를 누르면 해당 헥스가 커서 시작지점을 기준으로 입력이 됩니다. 이 방식을 쓰면

패치를 할 때마다 일일이 헥스를 확인하면서 입력하는 번거로움을 줄일 수 있습니다. 일단 이 창이 뜨면 엔터를 누르는 것 이외에는 창을 닫게 할 수

없으므로, 위치가 틀리거나 해서 창을 끄고 싶을 때는 대사창을 다 비워두고 엔터를 누르시면 됩니다.

 

 

3. 포인터란 무엇인가?

 포인터는 한글화에 쓰이는 기술 중 하나입니다... 만 알고 있어도 설명하기는 어렵네요. 그래서 제가 포인터를 배울 때 봤던 글을 여기에 적어보겠습니다.

영어로 되어 있으며, 중요한 부분은 해석이 되어있으나 중간중간 해석되지 않은 부분이 있습니다. 강좌의 내용을 차근차근 훏어보면 어떤 내용인지

이해할 수 있을 것입니다. 해석은 BANDCY님...이 하신 것 같습니다. 오래되서 기억이 잘 안나네요. 아래부터가 본문입니다.

----------------------------[ 아   래 ]------------------------------------------------------------------------------------------------

What are pointers?

포인터란 무엇인가?

Pointers actually have nothing to do with text.  A pointer is, quite simply, a reference to

포인터는 텍스트를 수정하는 것은 아니다.        포인터는, 간단하게 말해서, 다른 곳의 주소를 말한다.

somewhere else.  Anyone who's ever used any kind of basic programming has used a simple

               다른 종류의 기초적인 프로그래밍을 써 본 사람이라면 간단한 포인터를 사용해 봤다.

pointer.  Consider:

         고려사항:


     10 Print "Pointers are our friends."

     20 Goto 10


Line 20 is a pointer.  It POINTS to line 10 and says "GO THERE."

20행이 포인터이다.    그것은 10행을 가르키며 “그곳으로 가라”라는 뜻이다.

Choose-Your-Own-Adventure books (anybody remember these).  Go to page XX.  That's a

너의 모험책을 선택해라              (누구라도 이것을 기억한다.)   XX 페이지를 펴라.

pointer.

그것이 포인터이다.

Now, these are admittedly very simple pointers, but the fundamental principal behind them are

이제, 이것들은 매우 간단한 포인터들이다, 하지만 근본적인 공식은 똑같다.

the same.  And the beautiful thing is, NES pointers aren't THAT much more complicated than

            그리고 아름다운 것은 그것을 찾는 것이다. NES 포인터들은 찾는 것만, 예재보다 복잡하게 되어있다.

these themselves, only finding them.


Uh-huh.  So how do I find them?

흠흠.     그러면 어떻게 찾을 수 있을까?

Whoa, slow down.  First you need to understand what they are, or else knowing where they are

와우, 천천히 하자고. 먼저 당신은 그들의 위치를 이해하거나, 또는 ??

won't do you any good.  Go ahead and read further down if you want to, but I take no

                        계속하고 원한다면 더 읽어보아라, 하지만 나는 당신이 헷갈리는 것에

responsibility for the confusion you WILL cause yourself.

대해서 책임져야 할 의무는 없다?

Will pointers let me change how the text appears on the screen?

포인터는 화면에 텍스트가 화면에 나타나는 것을 바꿀까?

No.  Pointers have nothing to do with how text is DISPLAYED.  That's somewhere and

아니다. 포인터는 텍스트가 출력되는 것에 관여하지 않는다.       그것은 어딘가 그리고

something else completely.

다른 것이다.

I can see the blank space on the screen where I need to write just 1 or 2 more characters, why

나는 내가 글자를 더 써야 할 1~2글자의 빈 공간을 화면에서 볼 수 있다, 그것을 쓸 수는 없을까?

can't I just use that?


Just because you can SEE blank space on the screen doesn't mean that you can USE that blank

당신이 화면에서 빈칸을 보았다고 해서, 당신이 그 빈칸을 사용할 수 있다는 것은 아니다.

space.  On a Nintendo, what we see as a blank space at the end of a line the NES sees as just

        패밀리에서는, 우리가 라인의 끝에서 볼 수 있는 공백은 아무것도 없는 공간이다.

somewhere that nothing has been written.  Consider: (NOTE: This exercise only works on some


programs- like Notepad or Netscape)


A sentence.

문장.


Select the sentence.  Go ahead, highlight the entire line with your mouse.  Notice how even

문장을 선택하라. 계속해서 당신의 마우스로 완벽한 줄을 표시해라.           알아둬라.

though you can see blank space all the way to the edge of your screen, when it's highlighted,

당신이 화면의 끝에 있는 빈 칸을 볼 수 있다고 해서, 그것이 표시되었을 때,

there's nothing there?  That's how it is on the NES.  Once it hits what it knows to be the end of

거기에 아무것도 없다?  그것이 패밀리이다.?

the line, that's it.  Fortunately, with pointers, we can change where the end of the text is, so we

운좋게, 우리는 텍스트의 끝나는 부분을 바꿀 수 있다. 그래서 우리는 이 방어벽을 극복할 수 있다.

can overcome this barrier.


Cool.  So, pointers will give me access to unlimited space, right?

좋아~ 그래서, 포인터는 무한한 공간을 우리에게 주었다, 맞지?

No, Pointers (on the NES and sometimes on the SNES) do NOT give you unlimited space.  Far

아니다, 포인터는 (패밀리 게임이나 일부 슈퍼패미컴에서는) 무한한 공간을 준 것이 아니다.     늘린

from it.  Most of the time you are still limited by amount of space set aside within the rom for

것이다.  대부분의 시간 당신은 매우화가 나도록 좁은 공간을 맞이하게 될 것이다.

text, which can be an extremely infuriating thing.  What using pointers does allow you to do is

                                             포인터를 씀으로써 당신은 좀 더 긴 텍스트를 사용

use the space you've got more efficiently.  With pointers, if you cut one string down by 4

할 수 있는 기회를 허락받았다.              포인터로, 당신이 한 단어를 4글자를 줄였다면,

characters, for instance, you can elongate another one by 4.  There are some ways around this

          대신해서, 당신은 4글자를 늘릴 수 있다.            여기에는 몇가지 나중에 설명할

which I'll get into later.

몇가지 방법이 있다.


Well, what about rom expansion?  I hear that's really easy.

그럼, 롬 확장은 어떨까?          매우 쉽다고 들었다.

That's only on the SNES, and even then that's not always the case.  NES rom expansion is so

이것은 슈퍼패미컴에서만이고 그것도 모두 롬에 해당하는 것은 아니다.    패미컴롬 확장은 매우 어렵고

difficult and time consuming that you might as well think of it as impossible.

힘들다.

But I'm willing to learn 6502.

하지만, 나는 기꺼이 6502를 배운다.

Good for you.  Go learn it, then.  When you come back you'll understand why it's practically

               그러면 배워라.     배우고 난 뒤에는 왜 그것이 불가능 한 지 깨닳을 것이다.

impossible to do.


But there's no way I can possibly fit all of this text in the limited space I've got.  Why are you

하지만, 제한된 공간안에 텍스트를 넣을 방법이 없다.                             왜 그렇게 힘들고

being such an asshole and refusing to tell me how to do it?

...

(I originally had a big writeup here about why rom expansion was so close to impossible, but I've

been unable to confirm it by the time of posting this file.  If somebody who knows 6502

assembly would like to write their own section on why it's impossible, or would care to read over

what I've got and make corrections, it'd be very much appreciated)


But I really want to do it.

하지만 나는 정말로 그것을 하고 싶다.

Give it up.  You're not going to be able to, and those who might be able to do it for you are smart

포기해라.   할 수 없을 것이고,

enough that they don't need you.  You're just going to have to make due with the rest of us.



Anyway, how do I use pointers?

암튼, 포인터를 어떻게 사용할까?

Once you understand what pointers are, you may find it difficult to figure out how to use the

당신이 포인터가 무엇인지 이해하고 나면, 당신은 포인터를 사용하는 것은 어렵다.

pointers.  The simplest way to use pointers is as follows:

         아래의 방법이 가장 간단한 방법이다.


Let's use the most basic example possible, Yes/No.  (Translators may note that this example

가장 기초적인 예재를 사용해 보자, Yes/No.

actually becomes quite useful in some situations, since the Japanese word for yes is two

characters, and the word for no is 3)

The strings are stored in the rom as:

문장은 롬에 아래처럼 저장되어 있다.

*   *

Yes#No# (Note, the # is just a code which tells the NES that it's reached the end of the line.  See

          (노트, #은 단지 라인의 끝을 나타내는 코드 일 뿐이다. 그것의 사용법은 다른 문서를 참고해라)

other docs to learn how to use that)



Let's say, for the sake of example, that you wanted to switch them (playing a malicious trick on

말하자, 예재를 위해서, 그것을 바꾸고 싶다. ( 당신 친구에게 장난을 치기 위해서? 수치다 ;) )

your friends?  Shame on you ;) ).  Without any modification, they'd display as follows:

                                수정하기 전에는 아래와 같이 나타난다.


Yes

No



Now, if you just went into the rom and made the following change:

이제, 당신은 롬을 열고 아래와 같이 바꾸어 보자:

No#Yes#


you'd get the following output:

아래와 같이 나타날 것이다.


No

es



Hmmm, well, that's no good.  Why does it do that?  Because elsewhere in the rom, there's a

흠, 글쎄, 대략 좋지 않다.      왜 저렇게 나왔을까?    그 이유는 롬의 어는 곳에서, 각각의 문장의

pointer which tells the NES where each string begins.  Looking back, you'd find that the pointers

시작위치를 포인터가 가리키고 있기 때문이다.           나중에 보면, 당신은 포인터들이 아래의 위치를

actually point to the following locations (noted as the star above the position):

가리키는 것을 알 수 있을 것이다.


*     *

Yes#No#



Now, when you change only the text, you aren't changing the pointers, so they keep pointing to

지금, 당신이 포인터를 바꾸지 않고 텍스트만을 바꾸었을 때, 그래서 포인터들이 같은 장소를 가리키고

the same place.  Hence, your new version reads to the NES as:

있을때.


*      *

No#Yes#


The No reads in fine, since it starts where the NES thinks it does.  To the NES, the Yes,

No는 잘 나온다. 그것의 시작점이 공통됨으로.                     

however, begins at the e, and so it only reads in the es# for that string.  With pointer remapping

하지만, Yes는 e에서 시작한다 그리고, 문장에서 오직 es#만을 읽는다.        포인터로 리맵핑하면

we can change where the NES thinks the strings begin to reflect how they actually are:

롬이 가리키는 곳을 반영시킬 수 있다.

*    *

No#Yes#


Voila.  If we ran that through the NES, we'd get an output of:

어때? 그대로 하면, 아래와 같은 출력이 나타날 거야:


No

Yes



Hurray, it worked!

웁스~, 제대로 되는군!


Is that the only way to use pointers?

이것이 포인터를 쓰는 유일한 방법일까?

No, there are two other ways to use text pointers.

아니, 포인터를 쓰는 방법은 두 가지가 더 있지.

1) If you have multiple people who used to say different things, but now you want them all to say

1) 여러사람들이 각기 다른 말을 한다면, 하지만 당신은 그들이 모두 같은 말을 하기를 원한다면, 당신은

the same thing, you can use pointers to change that.  Yes, more than one pointer can point to a

포인터로 그것을 바꿀 수 있어. 그래, 하나 이상의 포인터로 롬에서의 위치를 바꿀 수 있어.

location in the rom.


Example: In game X, you have two towns people.  The first, when spoken to, says "Ohh..." while

예: 어떤 게임에서, 두 마을의 사람이 있어. 첫째 마을 사람은 “오...”라고 말하지, 다른 사람은 “아...”라고

the second says "Ahhh...".  With pointers, you can make it so that they both say "Ohhh..."  Yes,

하고. 포인터를 사용하면, 두 사람이 모두 “오...”라고 말 하게 할 수 있다고. 물론, 두 번째 사람이 말 할

you could just change the text of the second person in the rom, but here's the advantage to just

포인터를 바꿔 줌으로써 말이야. 게다가, 여기에 중요한 장점이 하나 있지:

changing the pointer: The area where "Ahhh..." had been stored can now be considered EMPTY,

                    “아...”라고 말하는 장소를 장소로 남겨놓을 수 있다는 거야.

meaning that you can use that area to fit even more text in elsewhere!

당신이 다른 텍스트로 채워 넣을 수 있는 장소로 말야!


2) Blank space in the rom can be your best friend, if you're lucky.  If there's blank space in the

2) 롬에서 빈공간은 최고의 선물이야, 당신 행운아군. 만약에 그곳에 빈 공간이 있다면, 그곳에다가 여분의

right area, you may be able to put extra text there.  I'll go over how to find it and take the best

텍스트를 채워 넣을 수 있어.                       나중에 정말 요긴하게 써 먹을 수 있을 거야.

advantage of that later.


Ok, so NOW can we learn how to find pointers?

좋아, 그럼 이제 어떻게 포인터를 찾는 지 배워 볼까?

Not quite yet.  First we have to go over how to Calculate them.  In working with NES roms, I've

아니, 아직.     먼저 우리는 반복해서 그것을 계산해야 한다.        NES 롬에서 작업하는 중에, 포인터

found 5 major systems of pointer calculation.  I'll explain them in more detail down below, but

계산의 5가지 중요 시스템을 알아냈다.          아래에 좀더 자세하게 설명하겠지만, 지금은

for right now we'll work with the STANDARD HEADER system (my name for them).  The

스텐다드 헤더 시스템(제가 작명했어요)

standard header system for pointers is your most basic system for pointers, and is the easiest to

포인터를 위한 스텐다드 헤더 시스템은 포인터를 위한 가장 중요하고 근본적인 시스템이며, 가장쉬운

work with.

작업방식입니다.


For illustrative purposes, I'll use the Final Fantasy rom.  This is where thingy comes in helpful.

설명을 위해서, 나는 파일널 판타지롬을 사용하겠습니다.   

Let's say you wanted to change "Nothing here." to read "The Princess always worries about you."

당신이 “Noting here."을 ”The Princess always worries about you."라고 말을 바꾸고 싶다고 해 봅시다.

So, we follow these simple, handy dandy steps.

그럼, 하나씩 아래의 예를 따라 해 봅시다.


1) Locate the string we want to replace (remember, take the HEX value)

1) 바꾸고 싶은 문장으로 이동합니다. (HEX값을 기억하십시요)

2) Locate the new string (remember, take the HEX value)

2) 새로운 문장으로 이동합니다. (HEX값을 기억하십시요)

3) Since we know that this rom uses the STANDARD HEADER system (defined below), we can

3) 우리는 이 롬이 스텐다드 헤더 시스템(위에서 정의한)을 사용한다는 것을 알고 있고, 우리는

use that to calculate the header value.  Don't worry, I'm going to walk you through it right here

이를 이용해서 헤더값을 계산할 수 있습니다. 걱정마세요, 자세히 설명해 드릴테니까요

for your first time.

4) Take the location that you want to calculate your pointer for (The first text string: "Nothing

4) 포인터를 계산하기 원하는 위치에 가십시오 (첫 문장:“Nothing here.",for instance).

here.", for instance).


Because these are STANDARD HEADER pointers, we use the following steps:

이것은 스텐다드 헤더 포인터이기 때문에, 아래의 단계를 거치면 됩니다:

First we'll do: "Nothing here."

먼저 우리는: “Nothing here."

It's position is at 28210

이것은 위치는 28210입니다.


5) Subtract 10 from it. (hex)

5) 그것에서 10(hex)을 뺍니다.

Why 10?  NES cartridges do not have headers on them.  The headers are added by the people

왜 10이냐고? NES 카트리지는 헤더를 가지고 있지 않기 때문이지. 헤더는 롬을 덤프한 사람들이

who dump the rom to contain information that's needed for the emulators to run.  The NES,

에뮬레이터로 구동시키기 위해서 추가한 것이거든.                                게다가 NES

therefore, doesn't recognize the existence of the header, and so we have to take it out.  (The

에서는 헤더의 존재를 인식하지 못하니까 빼 버리는 거야.

emulators do this automatically when they run the rom, but it doesn't change the values

(에뮬레이터는 롬을 구동할 때 자동적으로 이런 과정을 거치지만, 스스로 코드에 추가된 값을

embedded in the code itself)

바꾸지는 않거든)


Will I always need to do this?

항상 이런 작업이 필요할까?

Yes.  At least, I've never encountered or even heard of a rom where this wasn't true.

그래. 적어도, 앞에 말한 것과 다른 것들은 보지도 듣지도 못했다고.


RUNNING TOTAL: 28200

계산된 위치값: 28200

6) Now, drop the "Ten thousands" place digit (the first 2 here)

6) 그럼 이제 만단위 값을 빼자고. (여기서는 앞의 2)


RUNNING TOTAL: 8200

계산된 위치값: 8200


7) You should have a four digit number now.  If you don't, add in a zero at the beginning (that is,

7) 이제 4자리의 위치값이 남았을거야.          그렇지 않다면, 앞에서부터 0을 채우도록 해

C77 -> 0C77)

(예를 들어 C77라면 0C77라는 식으로 말야)


8) Break this number apart into two pairs, each with 2 digits.

8) 이제, 이것을 2자리씩 끊는 거야.


RUNNING TOTAL: 82 00

계산된 위치값: 82 00


9) Switch these numbers

9) 이 숫자를 바꿔줘


RUNNING TOTAL: 00 82

계산된 위치값: 00 82


10) Wait, there is no step 10.  00 82 is YOUR POINTER VALUE.  Congratulations, you've just

10) 잠깐, 10단계는 없어. 00 82가 포인터 값이야. 축하해~, 너는 처음으로 NES 포인터 값을 계산

calculated your first NES pointer.

해 낸 거라고.


Umm... now what?

음... 이제 어쩌지?

Well, now we go back and repeat the process, this time with our new pointer (the one that points

글쎄, 이번에는 이 새로운 포인터로작업을 계속해야지,                         ("The Princess always

to "The Princess always worries about you.").  Go ahead and try it.

worries about you."를 가리키는 곳). 가서 해 보자고.


(Did you find a location of: 282CD and a Pointer of: BD 82 ?  If you did, then you're right.)

(282CD 와 포인터:BD 82 값을 찾았어? 만약 그랬다면, 꽤 잘했는데.)

Ok.  I've got the pointers.  Now what do I do with them?

좋아. 포인터를 찾았으니, 이제 이걸로 뭘 해 볼까?

Well, you just scroll on down here to:

음, 아래의 내용을 훑어보자.


LOCATING POINTER TABLES (the easy way):

포인터 테이블의 위치 (쉬운 방법):

Yes, it's actually time to get down to what you've been waiting for.  Now, aren't you glad you

그래, 이제껏 기다려왔던 시간이야.                                지금, 너무 기쁘지 않아?

waited (if you did.  If you skipped down to this point, get back up there to the top where you

belong!)?


Since we know what system the pointers use, finding the pointer tables for this rom are actually

포인터 사용 시스템을 알고 나서는, 이 롬에서 포인터 테이블을 찾는 것은 정말로 쉽다고.

quite easy.  The easiest way (but one which is by no means guaranteed to work- it will for Final

            가장 쉬운 방법은

Fantasy though, trust me) is to open up the rom in your hexeditor, and go down to the text block

                        헥스에디터로 파일을 열고, 텍스트가 있는 곳을 찾아가.

(you've already got the address written down for it: 28010- where you found "Nothing here."). 

(이미 알고 있잖아 : 28010 - “Nothing here.").


In your hex editor, do a search, set it to search upwards, and type in the value of your old pointer.

헥스에디터에서, 찾아서 오래된 포인터 값을 입력하라고.

The first value you try should be your pointer (in Final Fantasy.  In other roms this may not be

처음으로 시도할 값은

the case, but if you've got the entire pointer, it probably is).


So, once you've located that, replace it's value (the 00 82) with the pointer you calculated for

그래서, 한 번 위치하면, 그 값을(00 82) 새로 계산한 값으로(BD 82) 바꿔 주는 거야

your new pointer (BD 82).


Save it (ALWAYS KEEP A BACKUP of the rom you're working off of, though, because you

저장하라고. (항상 백업하는 습관을 들이도록 해, 왜냐하면, 롬에서 잘못된 위치에다가 작업을

never know when you'll find the wrong location and mess up the game itself).

할 지도 모르는 일이니까.)


Now, go into NESticle, and try it out.  Talk to air while you're in town.  If, instead, it says "The

그럼, NESticle을 실행시키고 해 봐. 마을의 허공에다가 대고 말을 해 봐. 만약에 "The

Princess always worries about you.", congratulations, you've just remapped your first pointer.

Princess always worries about you.", 라고 말한다면 축하해, 포인터를 사용해서 리맵핑을 성공한거야.


Ok, that's fine if I know the pointer system.  So, how do I figure out that?

좋아, 좋아 만약 내가 포인터 시스템을 알고 있다면, 그걸 어떻게 파악하지?

Ironically enough, you figure it out from the pointer table.  Before I start to explain that, though,

하하, 포인터 테이블에서 알아 낼 수가 있지.               먼저 설명할게,

I should explain the major types of pointers.

포인터타입의 몇가지 형태를 설명할게.


(NOTE: Although Standard header and SetOff X000 are technically all the same thing, I've got

them broken up for simplicities sake)


STANDARD HEADER

스텐다드 헤더

By far the simplest and quickest pointers to work with.  These pointers appear somewhat

사용하기에 훨씬 간단하고 빠른 포인터.                  이 포인터는 종종 나타난다.

frequently.  Calculating them is simple (Final Fantasy uses Standard Header pointers, and the

           그것을 계산하는 것은 쉽다. (파이널 판타지가 이 방법을 쓰고, 위에서 설명한 방법대로

procedure for calculating them is stepped through above).  In brief, you:

하면 된다고)

1) Determine the position of the text. (SAMPLE: 12345)

1) 텍스트의 위치를 파악할 것. (예: 12345)

2) Subtract 10 for the header. (SAMPLE: 12335)

2) 헤더값에서 10을 뺄 것. (예: 12335)

3) Drop the Ten-thousands digit, if there is one. (SAMPLE: 2335)

3) 천자리수가 있을 경우 천자리의 값을 뺄 것. (예: 2335)

4) Break the number into two pairs.  (SAMPLE: 23 35)

4) 둘로 나눌것. (예: 23 35)

5) Swap the number pairs. (SAMPLE: 35 23)

5) 숫자의 위치를 바꿀 것. (예: 35 23)

Voila, you have your pointer value.

얏호~, 포인터 값을 구했어


SetOff X000

By far the most common type of pointers on the NES, SetOff X000 pointers are pointers whose

position within the rom is modified for whatever reason.  This amount of modification is

indicated by the X000 value.  Why they're modified isn't important, only how.  To calculate

them, you follow the same procedure as STANDARD HEADER pointers with one additional

step.  (IMPORTANT NOTE: You can only calculate X by locating the pointer table, which is

described below)  If you know X000, they are calculated by:

1) Determine the position of the text.  (SAMPLE: 12345)

2) Subtract 10 for the header. (SAMPLE: 12335)

3) Add X000 to your value. (SAMPLE: if you found X000 to be 3000, then 12335 + 3000 =>

15335)

4) Drop the Ten-thousands digit, if there is one.  (SAMPLE: 5335)

5) Break the number into two pairs. (SAMPLE: 53 35)

6) Swap the number pairs. (SAMPLE: 53 35)

Voila, you have your pointer value.

If you do not know X000, you need to follow the steps outlined below in LOCATING THE

POINTER TABLES.  When you get there, read through that section below, and then come back

up here and re-read this one to gain the best understanding of SetOff X000 pointers.


Some notes about SetOff X000:

1) Standard Header pointers are just SetOff 0000 pointers, but usually it's just easier to think of

them as their own type.

2) For whatever reason, X seems to be 8 more frequently than most other values.

3) Although it is theoretically possible to have SetOff 1500 pointers, or some other value which

is not a multiple of 1000, I have never encountered them, and have reason to believe that they

are not possible on the NES.


SEQUENTIAL TEXT

Technically, this is not even a pointer system, but I include it here because being able to

recognize this when it's used can save you hours of headache and searching.  Sequential text

systems don't use pointers, making their widths adjustable without any problem.  The Yes/No

example above would actually reduce to being as simple as replacing:

Yes#No#

with:

No#Yes#

Although it is not used with a lot of frequency, it does get used in some games.  The Adventures

of Musashi (j) uses this system.

One important note: With this system, it know's it's done when it reads in enough strings.

Therefore, you cannot simply remove a string you don't want in the game.  When using this

system, make sure you have AT LEAST as many strings as you started with (if you have more,

they won't get read in, however)


FIXED LENGTH

Rarely used for text, this system is frequently used for item and spell listings.  The game knows

that the text string is X characters long (usually 16, sometimes 8), and reads them accordingly.

You don't really need to do anything with these.  (The Adventures of Musashi uses these for it's

item, spell, enemy, and town lists)


SEQUENTIAL POINTERS

If you see these, run for cover, because they're annoying in the extreme to work with.  I've only

encountered them once, in RockBoard, and I'm still trying to figure out how they know

everything they're supposed to.  Anyway, I'm including them here for completeness, but you're

free to skip this section until you come across some pointers which you just can't find.

Sequential pointers are stored in their simplest form, two digits (as opposed to the 4 used in

SetOff X000 and Standard Header pointers).  They're calculated as follows:

1) Determine the position of the text.  (SAMPLE: 12345)

2) Subtract 10 for the header. (SAMPLE: 12335)

4) Drop all digits except for your ones and tens places.  (SAMPLE: 35)

Voila, you have your pointer value.

Seems easy, doesn't it?  Well, it's not, because as you try to remap these pointers, all kinds of

weird things can happen without the hundreds and thousands place.  Space constraints are worse

here than anywhere else.  Trust me, you really don't want to deal with these unless you

absolutely have to.



Well, there you have your standard pointer systems.  Are there others?  Probably.  I've only

encountered one other system on the NES, and I'm STILL trying to figure that one out...


So, now, can we finally get to finding the pointer table?

그러면 이제, 마지막으로 포인터 테이블을 찾을 수 있을까?

Yes.  You've read this far.  Now it's time to pull it all together.  You're reward for having read

그래.

through this far.


FINDING POINTER TABLES and your pointer system (the easy way):

(if you need an example, refer back up to the Final Fantasy one above)

Does the rom use a SEQUENTIAL TEXT or FIXED WIDTH systems?

1) To determine if you've got a FIXED WIDTH system, just look at your text strings.  If you've

got a bunch of strings that are exactly the same length (especially if they use 00s at the end to

guarantee that), odds are you've got a fixed width system at work.

2) To test and make sure, locate a string you can bring up easily in the game.  Overwrite it with

something longer which runs into the next string in your hex editor.  Save, then load the rom and

bring up that item.  If it cuts off after a certain length, you've got a fixed width system.

3) To test if you've got SEQUENTIAL TEXT, locate dialog you can bring up easily in the game.

Go into your hex editor, and locate that string.  Now, go into the string BEFORE it and add an

end of line code (you should have figured these out BEFORE looking for the pointers.  If you

don't know how, read someone else's doc, then try this one again.) right in the middle of it.

Save, and load up your rom again.  Bring up the dialog you used before.  If it's different, then

you've got a SEQUENTIAL TEXT system.


If your rom does not use the SEQUENTIAL TEXT or FIXED WIDTH systems:

1) Open the rom in your hex editor.

2) Locate a string of dialog which you can bring up in the game easily or quickly.  Don't use

menu options, or other types of text, as these tend to be stored differently in the rom.

3) Write down your position.

4) Subtract 10 from your position for the header.

5) Note down the last two digits of your value.  (If your adjusted position was 12345, the 45)

6) In your hex editor, Search UP for this value. (the 45)

7) Usually, you'll find one close to where you started your search.  Regardless, write down the

two digit number to the right of the one you just found (Let's say, searching for 45, your search

returned the 45 in the following line:  AB 45 FE  write down the FE)

8) Check the second digit in the number you just wrote down (In FE it'd be the E).  Compare that

value with the hundreds place in your adjusted position (In 12345 it'd be the 3).  If they match,

you may have found the beginning of your pointer table.  In they don't, continue searching UP.

9) Since the values didn't match, we continue searching upwards until they do.  (Finally, we find

it a line that includes 82 45 83)

10) Now that we've found a potential pointer, we need to test it.  Change the pointer so that the

text will display differently (my favorite is to just set the ones place ahead by 1, so that the first

letter doesn't display.  When that happens, you know it worked.  Sometimes, when you've got

control characters this isn't possible.  Then you'll need to remap the pointer to another string of

text, and see if it changed like you expected it to -> This is what we did in the Final Fantasy

example above.)

11) If the text changed as you expected it to, CONGRATULATIONS, YOU'VE JUST

LOCATED THE POINTER TABLE.

12) To figure out which pointer system you're dealing with, you only need to look at the pointer

you've found and compare it to the position of the text you're using.  Take the first digit of the

right number in your pointer (45 83 -> Take the 8) and compare this to the thousands digit of

your position (12345 -> The 2).  If they're the same, you're dealing with STANDARD HEADER

pointers, otherwise you've got SetOff X000 pointers (where X is the number you just examined

from the pointer -8- less the number you just took from the position -2-, or 6 => Therefore,

you're dealing with SetOff 6000 pointers)


That's it.  This system will work for most of the games that many of you will want to hack out

there.  Now that you know the pointer system, you can calculate the pointer for the first item in

your text block.  Find that, and you've found the beginning of your pointer table.



FINDING THE POINTER TABLES (a harder way):

If the above system didn't work for you, make sure you don't have any control codes (described

below).  If you're sure that there aren't any in there, try this system:

1) Test for SEQUENTIAL TEXT and FIXED WIDTH systems, as outlined above.

2) Locate a string you can bring up easily in the game.  Find it in the rom.

3) Using it's position, calculate the pointer using the STANDARD HEADER system.

4) Search the hex for this value.  Change every occurrence slightly (remember, change the

second digit of the first number pair for minor changes).

5) Save, and load the rom.  If the change you wanted occurred, then you know it's a

STANDARD HEADER system.  Change matches one by one until you find the right one.

6) If that doesn't work, then calculate the pointer using the SetOff 8000 system.  Search for this

value in the rom, changing every occurrence slightly.

7) Save, and load the rom.  If the changes you wanted occurred, then you know it's a SetOff 8000

system.  Change matches one by one until you find the right one.


If these don't work, then I'm afraid you'll have to resort to:


BRUTE FORCE POINTER LOCATION (the tedious way):

The system of last resort.  This will work 99.9% of the time if you know that you're not dealing

with a FIXED WIDTH or SEQUENTIAL TEXT system, and that there are no control codes

throwing you off (and in that 0.1% of the time, you don't want to deal with it anyway).

1) Locate a dialog string you can bring up easily in the rom.

2) Locate that string in the rom.

3) Calculate the pointer for it using the SEQUENTIAL POINTER system (no, don't worry.

Using this method does not automatically mean you've got sequential pointers).

4) From the beginning of the rom, search through for that value.  One by one, change that value

slightly.  Saving and testing to see each time if you've found the right one.

5) EVENTUALLY you'll come across it (hey, if you're lucky there will only be 500 occurrences

in the rom).  From there you can figure out the pointer system as described under the easy way

above.



So, is that it?  Do I now know everything I need to about pointers?

Almost.  There are only two more minor things for me to address.


Empty Space in the Rom:

Fitting all of the text you need to into the rom can be quite troublesome.  Fortunately, there is a

solution... sometimes.  On some occasions there will be blank space within the rom which you

can use to fit some extra text in.  You can recognize this space because it's usually just a large

block of 00 or FFs (although I've also seen it take the form of alternating FF 00 from time to

time).  Look at the end of your rom and you'll probably see a good example of it.

Now, because NES pointers are limited to 4 digits, so too are your pointers.  Therefore, your

range is limited to the 10000.  Scan through the ROM for blank space.

Finding blank space isn't a guarantee that you can use it, however.  Often that blank space is out

of the range of the pointer, or otherwise unusable.  But, there's only one way to find out.  Try it.

Put some text there, remap a pointer to it, and see what happens.  Sometimes you get lucky.


Control Characters:

Ballz calls these "Ballzy Tables," but I prefer to give them a name that has to do with their

function (much less, a name that isn't horribly inaccurate.  These aren't tabled information at

all.).  Control characters are codes that programmers put in with the text which tell the NES how

to display it.  Much like the font tables themselves, these vary from game to game.  End of line

and End of page are two examples of control characters.

I bring these up because if the text string you're using has one (or more) of these at it's beginning,

the pointer will point to THAT instead of the first displayed character in the string.

How do I recognize them if they're there?

Well, the easiest way is to work backwards.  Figure out the End of Text character (End of Line,

End of Page, whatever applies).  Pick a string of text from the game, and find it in the rom (note:

it can't be the first string in the rom).  Look to the left of that first character.  If that's your End of

Whatever code, then you're fine.  If it's something else, try changing it.  If it effects the text when

you load up the game again, then you've got a control code (I won't go over how to use control

codes here because they vary with every game).  Continue until you've found the TRUE

beginning of the string.  That's what you have to look for the pointer to.


WOW.  COULD IT BE?  FINISH!!!!!!!!


(This document is copyrighted 1998 to Timothy R. Dennie.  Please do not redistribute it without

his permission.  Just ask, he'll probably let you.  You can e-mail him at tdennie@hotmail.com)


------------------------------------------------------------------------------------------------[ 끝 ]--------------

 이상이 포인터에 대한 설명입니다. 축약하자면, 포인터는 모든 대사의 시작지점을 가리키는 코드이며, 2바이트로 이루어져있습니다. 포인터를 찾는 법은

해당 대사의 시작지점의 주소에서 만 단위를 제거하고 -> 10을 빼고 -> 둘로 나눠서 앞뒤로 위치를 바꾸는 것. 물론, 각 기종에 따라서 포인터를 찾는 법은

다릅니다. 하지만 모든 기종이 전부 다른 방식은 아니고, 몇몇 기종은 포인터 찾는 방식이 틀리다고 합니다. 위에서 설명한 방식은 NES를 기준으로

한 것이지만, NES 게임 중에서도 저 방식으로 포인터를 찾을 수 없는 게임이 있습니다.("고양이 당인전 테얀데"라는 게임은 위의 방식으로 포인터를

검색했지만, 나오지 않았습니다.) 그러므로 대충 포인터는 이런 거다 라고 개념만 잡으시고, 궁금한 점은 한식구에 문의하시기 바랍니다.

 

 이상으로 중급강좌를 마치겠습니다. 강좌에 대한 문의사항이나 궁금한 점이 있으시면 자유게시판을 통해 문의하시기 바랍니다.

그럼 오늘도 즐거운 하루 되시길... ^-^