Trawling

브라우저 게임 세 경로…PSP·NFSU2는 사전 변환하고 PS2는 실행 중 JIT

PSP Web Recomp와 Need for Speed: Underground 2 브라우저판은 게임 코드를 C++·C로 사전 변환하지만, TabStationToo는 PCSX2를 WebAssembly로 옮겨 브라우저에서 PS2 구성요소를 실행 중 JIT 컴파일합니다. 프로젝트별 프레임률과 실기 PS2 대비 속도는 게임·장면·측정 기준이 달라 단일 순위로 비교하기 어렵습니다. NFSU2 온라인판은 서버에 따라 접속 정원이 달라지며, 자리가 차면 대기열이 생깁니다.

브라우저에서 PSP·PS2 게임과 Need for Speed: Underground 2를 실행하는 프로젝트들은 모두 WebAssembly를 쓰지만, 게임 코드를 옮기는 경로는 다릅니다. GitHub 계정 snuri00의 PSP Web Recomp와 th0mk의 nfsu2-web은 게임별 실행 코드를 C++ 또는 C로 미리 변환합니다. TabStationToo는 PS2 에뮬레이터 PCSX2를 WebAssembly로 빌드하고 브라우저에서 PS2 구성요소를 실행 중 변환합니다. 각 경로는 지원하는 게임 범위와 이용자가 준비할 파일, 실행 환경에도 차이를 만듭니다.

게임별 사전 변환과 PSP 동작 재현

PSP Web Recomp는 PSP 게임 디스크 이미지에서 실행 파일을 추출하고 복호화합니다. PSPRecomp가 실행 파일의 MIPS 기계어를 분석해 함수별 C++ 코드로 바꾸면 Emscripten이 이를 WebAssembly로 컴파일합니다. 변환된 코드는 PSP의 레지스터와 메모리를 본뜬 환경에서 실행됩니다.

게임이 PSP 운영체제에 요청하는 기능은 프로젝트가 구현한 고수준 에뮬레이션 계층이 처리합니다. 이 계층은 협력형 스레드와 메모리 분할, 파일 읽기, 컨트롤러 입력, 오디오, 저장 기능 등을 맡습니다. 게임 데이터는 HTTP Range 요청으로 필요한 부분을 읽어 옵니다. 실행 파일은 먼저 내려받지만 디스크 이미지 전체를 처음부터 한꺼번에 받을 필요는 없습니다.

그래픽 처리에서는 PSP의 그래픽 칩 GE가 내보내는 디스플레이 목록을 CPU 쪽 코드가 해석하고, WebGL2 렌더러가 화면을 그립니다. PSP에서는 GE가 한 프레임을 처리하는 동안 CPU가 다음 프레임을 준비합니다. 이 겹침을 활용하기 위해 PSP Web Recomp는 GE와 WebGL 문맥을 OffscreenCanvas를 사용하는 작업 스레드에 둡니다. 그래픽 목록을 대기열에 넣은 뒤 CPU는 다음 작업을 이어가고, 명시적인 동기화 호출에서만 기다립니다. 프레임 처리 시간은 두 작업 시간을 더한 값이 아니라 더 오래 걸린 쪽의 영향을 받습니다.

저장소가 실행 사례로 든 게임은 God of War: Chains of Olympus와 Ghost of Sparta입니다. 두 작품은 같은 개발사 Ready at Dawn이 같은 엔진으로 만들었습니다. 프로젝트는 다른 게임에서 구현되지 않은 시스템 호출이나 지원하지 않는 GE 그래픽 기능을 만나면 실행이 멈출 수 있다고 설명합니다. 따라서 이 두 작품의 실행 사례만으로 다른 게임의 지원 범위를 가늠하기는 어렵습니다.

TabStationToo는 게임마다 코드를 미리 바꾸는 대신 PCSX2 에뮬레이터의 핵심을 Emscripten으로 WebAssembly에 맞춰 빌드합니다. 다만 PCSX2의 기존 재컴파일러는 호스트용 x86·ARM 기계어를 생성해 브라우저에서 그대로 쓸 수 없습니다. TabStationToo는 PS2의 주 CPU인 EE와 입출력 CPU인 IOP, 벡터 유닛 VU0·VU1을 실행 중 WebAssembly 모듈로 바꾸는 자체 JIT 컴파일러를 둡니다. 프로젝트는 이 코드의 결과를 PCSX2 인터프리터와 비트 단위로 대조한다고 밝힙니다.

그래픽은 PCSX2 하드웨어 렌더러를 WebGPU로 옮겨 처리합니다. WebGPU를 쓸 수 없는 환경에서는 PCSX2 소프트웨어 렌더러가 2D 캔버스에 그립니다. 이용자는 보유한 콘솔에서 추출한 BIOS와 자신의 게임 디스크 이미지를 준비합니다. 디스크 이미지는 업로드하지 않으며, 작업 스레드가 게임이 요청하는 부분을 이용자의 파일에서 읽습니다. 공유 메모리 스레드를 쓰려면 페이지가 교차 출처 격리된 상태로 제공돼야 합니다. 저장소가 안내하는 로컬 서버는 이를 위한 응답 헤더를 보내므로, 브라우저에서 파일을 직접 열어 실행하는 방식과 다릅니다. 프로젝트는 현재 상태를 초기 실험 단계라고 설명합니다.

성능 수치는 서로 다른 기준을 씁니다

PSP 저장소는 God of War: Chains of Olympus가 노트북의 Chrome·Firefox에서 측정한 장면 기준으로 초당 60프레임을 내고, PSP 해상도의 최대 네 배로 그려진다고 설명합니다. Ghost of Sparta는 기본 해상도의 세 배에서 초당 55~60프레임이라고 보고합니다. 두 수치는 해당 게임과 측정 장면에 대한 프로젝트 측 설명입니다.

TabStationToo의 성능 문서는 속도를 실기 PS2 속도에 대한 에뮬레이터 속도의 백분율로 정의합니다. Apple M1 Max가 별도 표기가 없는 측정의 기준 장비입니다. README는 Chrome에서 Guitar Hero의 한 곡이 드물게 속도 저하를 겪으며 100%로 실행되고, Grand Theft Auto: San Andreas의 도보 장면은 평균 약 99%라고 적었습니다. 이는 실기 PS2 속도를 기준으로 한 비율입니다.

nfsu2.xyz는 Need for Speed: Underground 2가 와이드스크린 자유 주행과 온라인 레이스에서 최대 초당 120프레임을 낸다고 소개합니다. 이 수치도 서비스 측 설명입니다. 세 프로젝트의 수치는 게임과 장면, 지표가 서로 달라 하나의 성능 순위로 환산할 수 없습니다.

NFSU2 온라인은 서버와 접속 정원을 씁니다

th0mk의 nfsu2-web은 2004년 PC판 실행 파일의 x86 코드를 C로 미리 바꾸고 WebAssembly로 빌드합니다. 브라우저에서 게임을 실행하려면 코드 변환 외에도 Windows, Direct3D 9, DirectSound, DirectInput의 동작을 재구현해야 합니다. 프로젝트는 그래픽을 WebGPU에 연결하고, 작업 스레드들이 공유 메모리를 사용하도록 구성했습니다. Rust 서버는 게임 페이지와 데이터를 제공하고 플레이어를 연결합니다.

서비스 이용자는 같은 서버 주소로 접속합니다. 서버가 게임 파일을 브라우저에 제공하며, 외부 컴퓨터에서 접속할 서버는 HTTPS로 운영해야 합니다. 직접 빌드해 호스팅하는 경우에는 북미판 1.2 PC 게임과 특정 SPEED2.EXE가 필요합니다. 이용자는 별도 프로그램을 설치하거나 게임 파일을 직접 고르지 않고 웹페이지에서 시작합니다.

접속 정원은 서버 구성에 따라 달라집니다. 안내 문서는 web/deploy 구성에서 최대 24,000명, 구형 Node 서버에서 최대 2,000명, 수동 실행 서버에서 128명을 제시합니다. 수동 서버의 정원은 운영자가 바꿀 수 있습니다. 자유 주행과 LAN·Online 화면은 접속 자리를 차지하지만 싱글 플레이는 그렇지 않습니다. 정원이 차면 선착순 대기열에 들어가며, 기다리는 동안 혼자 플레이하다 자리가 나면 다른 이용자들과 합류합니다.

자유 주행은 같은 서버에서 이 기능을 켠 이용자끼리 공유됩니다. 게임은 컴퓨터에서 차량 32대, 태블릿에서 24대, 휴대전화에서 16대를 기본 표시값으로 두며 16·24·32·48·64대로 바꿀 수 있습니다. 서버가 바쁠 때는 표시 차량이 최소 8대까지 줄어들 수 있고, 차량을 많이 표시할수록 프레임률이 낮아질 수 있습니다. 다른 이용자가 레이스나 상점, 메뉴에 들어가면 자유 주행 화면에서 차량이 사라지고 돌아온 뒤 다시 나타납니다.

참고 자료

오류 제보