네이티브 / 체험형 사례 분석 / 읽는 시간: 20분

DX-Ball: 벽돌이 어느 쪽에 있는지 소리로 알 수 있을까요?

REA로 DX-Ball의 스테레오 패닝 함수를 분석하세요. 명령어와 상수를 추적하고 소리 데모를 체험하며 분석으로 파악한 계산을 테스트합니다.

이 페이지의 내용

01. 분석하기 전에 직접 해 보기

왼쪽을 누른 다음 짧은 소리 재생을 누르세요. 오른쪽에서도 반복하세요. 이제 배율을 −1로 설정하면 위치는 그대로인데 소리는 반대편에서 납니다. 배율 0은 소리를 중앙에 놓습니다. 위의 숫자는 분석으로 파악한 계산 결과이며 아래의 소리는 설명용입니다.

스테레오 실험체험 / 관찰 / 설명
화면 X 좌표 320정수 패닝값 0
왼쪽
오른쪽

trunc((320 × 1.5625 − 500) × 1) = 0

헤드폰으로 소리의 위치를 들어 보세요. 재생을 눌러야 소리가 납니다.

수치 규칙은 보고서를 따릅니다. 소리는 정규화한 Web Audio 설명용 데모이며 원본 오디오 엔진이 아닙니다.

만들 결과물

위치를 패닝값으로 바꾸는 함수, 소리로 듣는 설명용 데모, 재구현 결과와 원본 기계어를 비교하는 계획입니다.

분석하기 전에

헤드폰이 있으면 실습에 도움이 됩니다. 바이너리 분석을 따라가려면 직접 준비한 영문 DX-Ball 1.07 실행 파일과 네이티브 분석 프로바이더가 필요합니다. 보고서에는 대상 해시와 기록된 검증 자료가 있습니다. REA 설정하기 →

02. 벽돌 충돌에서 소리 호출까지 추적하기

화면 한쪽에서 벽돌이 깨지는 눈에 보이는 이벤트부터 시작하세요. 소리 호출에서 거슬러 올라가 호출자가 전달하는 값을 찾으세요. 좌표처럼 보이는 숫자가 타일 인덱스, 오프셋, 배율이 적용된 위치일 수도 있습니다.

원본 보고서의 주소를 재사용하기 전에 정확한 릴리스 식별 정보를 확인하세요. 보고된 대상 헬퍼의 시작 주소는 0x406400입니다. 실행 파일이 다르다면 같은 주소가 유효하다고 가정하지 말고 해당 동작을 찾으세요.

이 분석 프롬프트 복사
보고서와 일치하는 내 DX-Ball 1.07 실행 파일을 REA로 분석하세요. 공식 보고서가 식별한 패닝 헬퍼에서 시작해 벽돌 충돌 시 이 함수를 호출하는 코드를 확인하세요. 호출자가 인수를 구성하는 방식을 설명하세요. 호출 지점의 명령어와 헬퍼의 입력 로드 명령을 모두 명시하세요. 디컴파일러의 함수 시그니처가 완전하다고 가정하지 마세요.

03. 의사 코드에서 인수가 사라졌다면 명령어 읽기

기계어 명령어를 볼 수 있어도 디컴파일러가 짧고 도움이 되지 않는 함수 본문을 만들 수 있습니다. 스택 로드, 부동소수점 연산, 참조 데이터, 정수 변환을 함께 확인하세요. 각 상수의 원본 바이트와 함께 자료형 및 바이트 순서를 요청하세요.

문서에 기록된 계산은 trunc((x × 1.5625 − 500) × scale)입니다. 호출자는 가로 위치를 전달합니다. 마지막 변환에 주목하세요. 0 방향으로 소수부를 버리는 처리는 음수에서 중요하며 내림과 다릅니다.

  • 입력이 함수의 어느 위치로 들어오나요?
  • 어떤 참조 바이트를 해석하면 각 부동소수점 상수가 나오나요?
  • scale은 매개변수인가요, 저장된 상태인가요, 고정 리터럴인가요?
  • 테스트 입력 범위에서 변환은 절삭, 반올림, 포화 처리, 오버플로 중 어떻게 동작하나요?

04. 계산 결과를 신중하게 소리로 표현하기

먼저 수치 함수를 구현하고 왼쪽, 중앙, 오른쪽을 확인하세요. 그런 다음 소수 결과가 나오는 인접 위치를 추가하세요. x = 319, scale = 1일 때 원시 값은 −1.5625이고 정수 결과는 −1입니다. 내림 연산을 사용하면 잘못된 값인 −2가 나옵니다.

소리 버튼은 pan / 500을 Web Audio 스테레오 패너에 대응시키고 이 미리듣기 값을 −1…1로 제한합니다. 방향은 쉽게 들을 수 있지만 DirectSound의 음량 곡선이나 원본 게임 오디오를 재현하지는 않습니다. 표시되는 정수에는 상한·하한 제한을 적용하지 않습니다.

이 분석 프롬프트 복사
문서에 기록된 위치-패닝 계산을 독립적으로 구현하세요. 배율 0, 0.5, 1, 20, −1에서 x = 0, 1, 319, 320, 321, 640을 테스트하세요. 0 방향 절삭을 유지하세요. 사용자가 눌러 재생하는 소리 미리듣기를 만들고 정규화 과정을 별도로 표시하세요. 미리듣기의 범위 제한을 분석으로 파악한 수치 동작으로 사용하지 마세요.

05. 3,205개 검증 통과의 의미 이해하기

원본 프로젝트는 정수 위치 641개와 배율 설정 다섯 가지를 원본 x86 함수와 비교했다고 보고합니다. 별도로 명시된 과거 환경에서 컴파일 결과 63바이트가 일치했다고 보고합니다. 선택한 입력에 대한 동작 일치와 생성된 기계어 일치는 서로 다른 검증입니다.

직접 분석할 때는 각 입력 쌍과 양쪽 출력을 보관하세요. 불일치가 나오면 실패하는 최소 사례로 줄이세요. 컴파일러 버전, 옵션, 재배치 처리 방법을 명확히 한 뒤에만 바이트 일치를 시도하세요. 이 사이트의 JavaScript 테스트는 문서에 기록된 산술 연산을 검증하며 원본 바이너리 비교를 반복하지 않습니다.

06. 알려진 결과와 비교하기

다음을 명확한 검증 지점으로 활용하세요. 일치하더라도 이 작은 규칙만 뒷받침하며 앱 전체의 호환성을 입증하지는 않습니다.

화면 X 좌표 / 배율정수 패닝값확인해야 하는 이유
0 / 1−500왼쪽 끝
319 / 1−1음수 절삭
320 / 10중앙
321 / 11양수 절삭
640 / −1−500반대 방향 배율
640 / 2010,000수치 결과가 소리 미리듣기 범위를 초과함

두 파일을 같은 폴더에 저장하고 Node.js로 검증을 실행하세요. 패키지 설치는 필요 없습니다.

터미널
node check-case-labs.mjs

07. 실제로 검증한 범위는?

원본 x86과의 비교 3,205건 및 일치하는 63바이트는 함수 하나에 대한 원본 프로젝트의 결과입니다. 이 사이트는 유리수 기준 구현을 사용해 별도의 산술 구현을 문서에 기록된 동일한 위치/배율 조합으로 테스트합니다. DXBALL.EXE를 실행하거나 게임 전체를 재구현하거나 오디오 엔진을 재현하지 않습니다.

이 사이트의 수치 테스트 결과 보기 →

출처: REA의 DX-Ball 검증 보고서 · 고정 커밋의 유지 관리 중인 패닝 함수. 튜토리얼, 도해, 브라우저 실험은 독립적으로 제작했습니다.

다음 실험200 + 10%는 왜 220일까요? →

REA가 처음인가요? REA란? · 가이드 검증 방법