TECH 으로 돌아가기
TECH HACKER NEWS 오늘 8분 읽기 32 READS

PS2 게임을 브라우저에서? 에뮬레이터 없이 ‘정적 재컴파일’로 웹어셈블리에 옮긴 프로젝트

PS2 게임을 브라우저에서? 에뮬레이터 없이 ‘정적 재컴파일’로 웹어셈블리에 옮긴 프로젝트
SOURCE IMAGE · HACKER NEWS
PS2 게임을 브라우저에서? 에뮬레이터 없이 ‘정적 재컴파일’로 웹어셈블리에 옮긴 프로젝트

에뮬레이터가 아니라 ‘번역’이에요

플레이스테이션 2(PS2) 게임을 웹 브라우저에서 돌리는 오픈소스 프로젝트 ps2-web-recomp가 공개됐어요. “그거 에뮬레이터 웹 버전 아니야?” 싶을 수 있는데 접근 방식이 꽤 달라요. 게임을 실행하는 순간에 PS2 흉내를 내는 게 아니라, PS2 게임의 기계어를 실행 전에 미리 번역해서 브라우저가 이해하는 웹어셈블리(WebAssembly)로 만들어두는 방식이거든요.

최근 레트로 게임 씬에서 가장 뜨거운 키워드가 이 정적 재컴파일(static recompilation)인데요, 그 흐름이 PS2와 브라우저까지 넘어왔다는 점에서 한번 짚어볼 만해요.

인터프리터, JIT, 그리고 정적 재컴파일

다른 기기용 프로그램을 돌리는 방법은 크게 세 가지가 있어요. 통역에 비유해볼게요.

정적 재컴파일의 가장 큰 장점은 번역 결과가 결국 평범한 C 코드나 네이티브 코드라서 현대 컴파일러의 최적화를 그대로 받을 수 있다는 거예요. 원본 기기의 한계를 벗어나 고해상도나 높은 프레임레이트 같은 개선을 붙이기도 쉽고요. 애플이 인텔용 맥 앱을 애플 실리콘에서 돌릴 때 쓴 Rosetta 2도 가능한 한 설치 시점에 미리 번역하는 방식을 썼어요.

이 흐름에 불을 붙인 건 2024년 N64 게임을 PC 네이티브로 옮긴 N64Recomp였어요. 젤다의 전설: 무쥬라의 가면 PC 포트로 유명해졌죠. 이어서 Xbox 360용 XenonRecomp로 소닉 언리쉬드가 PC에 옮겨지면서 “이게 진짜 되네?” 하는 분위기가 만들어졌고요. 이번 프로젝트는 같은 아이디어를 PS2에 적용하면서 최종 목적지를 브라우저로 잡았다는 점이 흥미로워요.

PS2라서 더 까다로운 부분

PS2는 재컴파일하기 꽤 어려운 기계예요. 메인 CPU인 이모션 엔진(Emotion Engine)은 MIPS 계열 R5900인데, 일반 MIPS에는 없는 128비트 정수 SIMD 명령어(MMI)를 갖고 있어요. 여기에 VU0, VU1이라는 두 개의 벡터 유닛이 따로 있어서 3D 좌표 변환 같은 계산을 별도 마이크로코드로 처리해요. 그래픽은 GS(Graphics Synthesizer)라는 독특한 칩이, 입출력은 PS1 CPU를 거의 그대로 가져온 IOP가 맡고요. CPU 하나가 아니라 성격이 다른 여러 프로세서를 함께 다뤄야 하는 거죠.

유명한 함정이 하나 더 있는데, 바로 부동소수점이에요. PS2의 FPU는 우리가 아는 IEEE 754 표준을 완전히 따르지 않아요. 무한대나 NaN을 만드는 대신 최댓값으로 고정(clamp)해버리는 식이라, 현대 CPU 방식 그대로 계산하면 캐릭터가 엉뚱한 곳으로 날아가거나 물리 연산이 틀어질 수 있어요. PCSX2에 ‘클램핑 모드’ 옵션이 따로 있는 이유예요.

정적 재컴파일이면 어디서나 만나는 숙제도 있어요. 함수 포인터처럼 실행 중에야 목적지를 알 수 있는 간접 점프나, 게임이 디스크에서 코드 조각(오버레이)을 런타임에 불러오는 경우는 미리 번역하기가 어렵거든요. 그래서 보통은 원본 주소를 번역된 함수로 이어주는 조회 테이블을 두거나, 게임별로 손을 봐주는 작업이 필요해요.

웹어셈블리와 궁합이 좋은 이유

웹어셈블리는 브라우저에서 네이티브에 가까운 속도로 돌아가는 바이너리 포맷이에요. PS2와는 몇 가지 점에서 잘 맞아요. PS2 메인 메모리는 32MB라서 웹어셈블리의 선형 메모리 안에 통째로 올려두고 주소 변환을 단순하게 처리할 수 있어요. 또 웹어셈블리 SIMD가 128비트 벡터를 지원하니까, 이모션 엔진의 128비트 연산과 폭이 딱 맞는 것도 반가운 부분이에요. 그래픽은 WebGL2나 WebGPU로, 사운드는 Web Audio API로 옮기게 되고요.

물론 브라우저만의 제약도 있어요. 멀티스레드를 쓰려면 SharedArrayBuffer가 필요한데, 이걸 쓰려면 서버에서 COOP/COEP 헤더로 cross-origin isolation을 켜줘야 해요. 웹어셈블리 프로젝트를 배포해본 분들이 한 번씩 막히는 지점이죠.

한국 개발자에게 주는 시사점

당장 업무에 쓸 기술은 아니지만 배울 거리는 많아요.

첫째, 컴파일러와 바이너리 번역 공부의 좋은 교재예요. 기계어를 해석하고, 제어 흐름을 파악하고, 다른 형태로 내보내는 과정이 실제로 돌아가는 코드로 공개돼 있거든요.

둘째, 레거시 마이그레이션과 닮아 있어요. 소스 코드가 사라진 오래된 시스템을 새 플랫폼으로 옮겨야 하는 일은 실무에서도 생각보다 자주 생겨요. 게임 재컴파일 기법을 알아두면 그런 문제를 보는 시야가 넓어져요.

셋째, 웹어셈블리 실전 사례로서 가치가 있어요. C/C++로 된 무거운 엔진을 브라우저로 가져오는 일은 디자인 툴, 영상 편집, CAD 쪽에서 이미 활발해요. 메모리, 스레드, 그래픽 API 연결 같은 문제를 어떻게 풀었는지 코드를 읽어보면 좋은 공부가 돼요.

참고로 이런 프로젝트들은 보통 게임 데이터를 포함하지 않고, 본인이 소유한 게임에서 직접 추출해서 쓰도록 만들어요. 저작권이 민감한 분야라서 직접 써보거나 기여할 땐 꼭 확인하세요.

마무리

“에뮬레이션에서 번역으로”, 정적 재컴파일이 PS2와 브라우저까지 넘어오면서 레트로 게임을 보존하고 즐기는 방식이 바뀌고 있어요.

여러분은 어떻게 보세요? 정적 재컴파일이 언젠가 에뮬레이터를 대체할 수 있을까요, 아니면 게임마다 손이 많이 가는 특수한 방법으로 남을까요? 웹어셈블리로 뭔가 옮겨본 경험이 있다면 같이 이야기해봐요.


🔗 출처: Hacker News

SOURCE · HACKER NEWS
원문 전체 보기 → https://github.com/snuri00/ps2-web-recomp
SHARE
NEXT · CHOOSE

변화를 읽었다면,
내가 만들 수익 구조를 고릅니다.

정보를 더 모으는 데서 멈추지 않고, 광고·외주·판매·중개·구독 중 내 상황에 맞는 출발점을 정해보세요.

21가지 수익 구조 살펴보기 →
처리 중...