SDL이 이제 DOS를 지원함
(github.com/libsdl-org)- DJGPP 기반 DOS 포트가 SDL에 추가됐고, 비디오·오디오·입력·스레딩·타이머·파일시스템·빌드 체인까지 폭넓게 갖춘 상태로 main에 병합됨
- VGA와 VESA 1.2+ 비디오, Sound Blaster 계열 오디오 재생, PS/2 키보드와 마우스, BIOS 기반 조이스틱, 협력형 스레딩과 PIT 타이머까지 DOS 환경에 맞춘 구현이 들어감
- DJGPP의 seek/read 문제는 seek 시 버퍼를 덤프하고 복원하는 방식으로 우회해
SDL_LoadWAV의 잘못된 읽기와 수 초 지연을 없앴고, 오디오 경로도 IRQ 재진입과 stutter를 줄이는 쪽으로 다듬어짐 - fullscreen 검은 화면은 INDEX8 모드 선택과 연결돼 있었고, DOS 전용 hint를 두는 대신 모드 순서를 논리적으로 정렬하는 방향으로 조정됐으며, 커서 투명도 문제도 추가 커밋으로 수정됨
- 실기기 테스트는 제한적이고 오디오 녹음,
SDL_LoadObject,SDL_TIME의 DOS 전용 구현 같은 일부 기능은 빠져 있지만, 46개 체크를 통과해 병합됐고 3.6.0 기능으로 잡힘
DOS 플랫폼 지원 범위
- SDL에 DOS 포팅이 추가됐고, DJGPP 기반으로 비교적 완성도 높은 상태에 도달함
- 작업은 여러 사람이 나눠 진행했고, 마지막 단계에서 안정성 수정과 빠진 기능 보완이 더해짐
- DevilutionX를 DOSBox에서 광범위하게 테스트했지만, 실기기 테스트는 없음
- 테스트 방법이 마땅하지 않은 기능은 일부러 제외한 부분도 있음
- 지원 기능이 구체적으로 정리되어 있음
- 비디오는 VGA와 VESA 1.2+ 프레임버퍼, RGB와 8비트 인덱스 컬러, VGA DAC 팔레트 프로그래밍, vsync와 하드웨어 페이지 플리핑, 종료 시 VBE 상태 저장과 복원을 포함함
- 오디오는 Sound Blaster 16, Sound Blaster Pro, Sound Blaster 2.0/1.x를 지원하고, IRQ 기반 DMA와 이중 버퍼 auto-init 경로를 사용함
- 입력은 확장 스캔코드를 포함한 PS/2 키보드, INT 33h 마우스, BIOS INT 15h 기반 gameport 조이스틱을 포함함
- 스레딩은
setjmp/longjmp와 스택 패칭을 이용한 협력형 스케줄러를 사용하며, mutex, semaphore, TLS, condition variable의 일반 fallback도 갖춤 - 이벤트 펌프와 delay 함수에 yield 지점을 넣어 오디오와 다른 스레드의 응답성을 유지함
- 타이머는 DJGPP의
uclock()을 사용한 PIT 기반 구현으로 약 1.19 MHz 해상도를 가짐 - 파일시스템은
GetBasePath와GetPrefPath를 DJGPP의searchpath()로 처리하고, POSIX 파일시스템 연산 fallback도 포함함 - 빌드는 CMake 크로스 컴파일 툴체인 파일, DJGPP CI 작업, 빠른 configure를 위한 preseed cache를 포함함
- 포함되지 않은 기능도 명확히 적혀 있음
- 오디오 녹음은 빠져 있고 재생만 지원함
SDL_TIME의 네이티브 구현은 따로 없고, DJGPP의 POSIX 레이어를 통한 Unixgettimeofday를 재사용함- 공유 라이브러리 로딩은 지원하지 않아
SDL_LoadObject가 없음
구현 과정과 핵심 변경
- DOS 포트는 여러 커밋을 거치며 비디오, 오디오, 입력, 타이머, 스레딩, 빌드 체인이 단계적으로 추가됨
- 초기 작업 이후 stdio 버퍼링, 오디오 구현, 비디오 서브시스템, 파일시스템, 마우스, 키보드, CI, 플랫폼 감지까지 순서대로 보완됨
- stdio와 파일 접근에서는 DJGPP 특유의 seek/read 문제를 우회함
- stdio SDL_IOStreams의 버퍼를 끄는 시도도 있었지만, 이후 seek 시 버퍼를 덤프하고 복원하는 방식으로 바뀜
- 이 변경은 버퍼를 완전히 끄는 것보다 훨씬 빠르고,
fseek이후 잘못된 읽기가 나오는 문제도 피함 SDL_LoadWAV가test/sample.wav를 읽을 때 수 초 걸리던 현상이 사라지고, 올바른 데이터가 들어오게 됨
- 오디오 처리 방식도 안정성 중심으로 계속 조정됨
- Sound Blaster 16 구현으로 시작했고, 이후 pre-SB16 8비트 mono와 SB Pro stereo 지원이 추가됨
- 오디오 믹싱은 IRQ 핸들러에서 직접 돌리던 방식에서 메인 루프를 거쳐, 다시 SDL 오디오 스레드 쪽으로 이동함
- IRQ 안에서 재진입 문제가 생기지 않도록 방향을 바꿨고, 로드 중 오래된 DMA 버퍼 절반을 silence 처리해 stutter를 줄임
- 샘플레이트 조정과 DSP 상태 polling, DMA 메모리 할당 근거, 인터럽트 벡터 복원 후 IRET wrapper 해제까지 정리됨
- 비디오도 DOS 환경 제약에 맞춰 세부 기능이 확장됨
- VESA 인터페이스로 소프트웨어 렌더러와 동작하는 초기 구현이 들어감
- 이후 8비트 팔레트 지원, VBE 페이지 플리핑, 상태 복원, 단일 버퍼 모드 vsync, VESA banked framebuffer 모드가 추가됨
- VBE 1.2+에서 LFB가 없는 경우 bank switching으로 프레임버퍼를 복사하며, 이 모드에서는 페이지 플리핑을 비활성화함
- 비디오 초기화와 종료 시 전체 VBE 상태를 저장하고 복원해 모드 전환을 깨끗하게 처리함
- 입력과 인터럽트 처리도 실사용 수준까지 다듬어짐
- 키보드는 확장 스캔코드와 Pause 키까지 다루고, 이벤트 저장에는 단순 ring buffer를 사용함
- 마우스는 INT 33h function
0x1B로 감도를 조회해 사용함 - 조이스틱은 BIOS timing loop 비용을 줄이기 위해 축 polling을 약 60 Hz로 제한하고, 버튼은 응답성을 위해 항상 직접 polling함
- ISR 코드와 데이터를 잠가 인터럽트 중 페이지 폴트를 막음
- 빌드와 플랫폼 감지 문제도 수정됨
- DJGPP용 CI job이 추가됐고, DOS용 CMake 플랫폼 감지가 들어감
SDL_PLATFORM_DOS를SDL_RunApp()제외 목록에 넣어 DOS 전용 런처와 충돌하지 않게 함- DJGPP가
__unix__를 정의해도 DOS에는 GTK나 display server가 없으므로SDL_Gtk_Quit()를 DOS에서 제외해 링크 오류를 막음 - 일부 DJGPP 툴체인이
i386-pc-msdosdjgpp-gcc접두사를 쓰는 점까지 반영함
테스트 상태와 남아 있던 제약
- 자동화 테스트는 모두 매끄럽게 끝나지는 않았지만, 패치로 완주 가능한 수준까지 도달함
- 표준 formatting 함수 일부 문제 때문에 자동화 테스트가 끝까지 가지 못했고, 이를 우회하는 패치로 테스트 자체는 완료함
- 여전히 실패하는 케이스가 남아 있었지만, 해당 formatting 함수를 어떻게 고치는 게 맞는지 확신이 없어 포함하지 않음
- 대부분의 데모는 대체로 기대 가능한 수준으로 동작한다고 정리됨
- 실제 사용 결과도 추가됨
- DOSBox와 DOS 6.22 on a Vortex86 board에서 비전체화면 창은 테스트 프로그램과 사용자 코드 모두 잘 동작함
- 다만 fullscreen은 당시 시점에
draw.exe --fullscreen같은 예시에서 검은 빈 화면이 나옴 - 속도는 느리지만 사용할 수 있는 수준으로 적혀 있음
- 일부 테스트 프로그램 문제도 함께 확인됨
sprite.exe는 DOSBox에서 즉시 종료됨wm.exe와draw.exe는 렌더링이 되지 않지만 ESC를 누르면 종료되는 상태였음testpalette는 segfault가 발생함
전체화면 색심도 선택 문제와 조정
- fullscreen 검은 화면의 직접 원인은
SDL_GetClosestFullscreenDisplayMode()가 INDEX8 모드로 떨어지는 동작이었음- 애플리케이션이 INDEX8 렌더링을 처리하지 못하면 화면이 검게 나옴
- 내부 구현에서는 사용자가 이미 INDEX8 fullscreen 모드를 설정한 경우에만 INDEX8을 고려하도록 다룸
- 처음에는 DOS에서만
SDL_HINT_DOS_ALLOW_INDEX8_MODES뒤에 INDEX8 모드를 숨기는 대응이 들어감- 애플리케이션이 제대로 처리할 수 있을 때만 명시적으로 opt-in 하게 만들려는 목적이었음
- 하지만 메인 브랜치에서 최저 bit depth 대신 최고 bit depth를 고르는 변경이 이미 들어가 있었고, 이것으로 해결되는지 확인하는 흐름이 이어짐
- 이 변경은 bpp 문제는 해결했지만, 640x480 best fit 요청에 1024x768이 선택되는 새 문제가 생김
- 해당 변경은 결국 되돌려졌고, 더 나은 수정은 별도 PR로 다루는 방향으로 정리됨
- 최종적으로 DOS 전용 hint는 제거되고, 모드 순서를 논리적으로 정렬하는 쪽으로 바뀜
Remove SDL_HINT_DOS_ALLOW_INDEX8_MODES and order modes logically커밋이 추가됨- #15442가 병합되면, 팔레트를 설정하지 않거나 fullscreen 모드를 직접 고르지 않는 앱에서도 자동 모드 선택이 올바르게 동작할 수 있다고 정리됨
- 기존 SDL의 다른 문제까지 이 PR에서 끝없이 파고들지는 않겠다는 선도 그어짐
데모 렌더링과 커서 수정
- 데모가 검게 보이던 문제는 이 PR 단독이 아니라 #15442 병합 상태에 좌우됐음
SDL_GetClosestFullscreenDisplayMode()가 가장 낮은 색심도를 선호하는 동안에는 이 포트에서 INDEX8이 선택되고, 앱이 팔레트를 설정하지 않으면 검은 화면이 됨- 해당 PR을 로컬에 병합하자 테스트 대상이 모두 동작했다는 확인이 나옴
- 남은 시각적 문제는 커서 투명도였음
- 로컬 확인 뒤 커서만 투명하지 않다는 점이 추가로 드러남
- 이를 고치기 위해
Don't convert cursor if dest is not INDEX8커밋이 들어감 - 수정 후에는 RGB 모드에서 최적화되지 않은 버전을 사용하지만, RGB와 INDEX8 모두에서 올바르게 동작하도록 맞춰짐
- XRGB1555와 RGB565에서 약간 더 나은 성능 여지는 남았지만 우선순위는 낮게 취급됨
리뷰와 병합 결정
- PR은 squash merge가 적합하다고 판단됨
- GitHub가 결과 커밋에서 PR 참조를 유지하므로, 작업 과정도 추적 가능하다고 봄
- 결과 커밋에는 추가 공로 표기를 넣자는 제안도 함께 적혀 있음
Co-authored-by두 명과Tested-by한 명을 추가하자는 구체적 문구도 포함됨
- 리뷰어는 병합 뒤에 일부 빌드 스크립트 표현을 더 깔끔하게 다시 쓰겠다고 남김
- 최종 병합 직전에는 다른 관련 PR까지 함께 병합하고 DOS PR도 진행하는 쪽으로 정리됨
- “Last call on DOS pull request!” 이후, 관련 PR 병합 상태가 확인됨
- 이어서 46 checks passed 상태로 main에 병합됨
- 병합 후 릴리스 범위도 명확히 정리됨
- 이 변경은 3.6.0 feature로 간주됨
-
3.4.x로 cherry-pick 하지 않음
- 병합 다음 날 DOS 작업 브랜치는 삭제됨
후속 과제와 남은 하드웨어 이슈
- 일부 Nvidia GPU의
4f07(SetDisplayStart)구현이 제대로 동작하지 않는 문제도 제기됨- VOGONS 스레드 링크와 함께, 보고상으로는 지원한다고 나오지만 실제로는 동작하지 않는 GPU가 있다는 점이 적혀 있음
- 테스트 범위는 GeForce 9300부터 3060까지 더 넓을 수 있다고 적혀 있지만, 보유 장비 기준이라 완전한 범위는 아님
- 프로젝트 쪽 테스트에서도 같은 표시 문제가 관찰됨
- GPU vendor 기준으로 SDL이 기능을 끄는 방식은 바람직하지 않다고 보고, 사용자 제어용 hint 가능성도 거론됨
page_flip_available를 사용자가 직접 제어하는 새 hint가 더 나을 수 있다는 방향이 나옴- 즉시 처리하지 않고 나중에 추가할 수 있다는 선에서 마무리됨
- 병합 뒤에는 직접 프레임버퍼 사용 hint도 함께 적혀 있음
SDL_HINT_DOS_ALLOW_DIRECT_FRAMEBUFFER를 켜면, 위SetDisplayStart이슈가 크게 중요하지 않을 수 있다고 적혀 있음
Hacker News 의견들
-
이제 UEFI용 SDL만 있으면 게임을 OS 부팅 전 환경에서도 돌릴 수 있게 됨
- 모든 Intel 칩셋에서 도는 Intel Management Engine / Minix는 요즘도 여전한지 궁금함
보안이 더 단단해졌는지, 아니면 여전히 접근 가능한지도 궁금하고 https://www.zdnet.com/article/minix-intels-hidden-in-chip-operating-system/ - 그건 사실 그렇게까지 어렵진 않을 듯함
다만 UEFI엔 사운드 드라이버가 없는 걸로 알고 있고, 요즘은 오디오 코덱 칩조차 NDA 전용 데이터시트뿐이라 직접 작성하기도 까다로움
더 황당한 건 graphics output protocol에 vsync 정보가 없어서 찢김 없는 blitting이 안 된다는 점이고, 이건 문자 그대로 VGA보다 못함 - UEFI는 약간 현대식 DOS처럼 느껴짐
- 솔직히 엄청 멋진 그림임
grub 같은 메뉴로 부팅했더니 고전 게임 목록이 쭉 뜬다고 생각하면 꽤 설렘 - 한마디로 bare metal용 SDL임
- 모든 Intel 칩셋에서 도는 Intel Management Engine / Minix는 요즘도 여전한지 궁금함
-
이 스크린샷이 특히 웃긴 이유는 DosBOX 자체가 SDL 위에서 만들어졌기 때문임
- 그럼 이제 DOS 안에서 도는 dosbox가 필요해짐
- SDLception 그 자체임
-
이건 DJGPP를 쓰고 있어서 DPMI로 CPU를 32비트 모드로 전환함
그래서 segmented memory, near pointer, 온갖 64KB 제한이 난무하던 진짜 올드스쿨 감성은 못 느끼게 됨 -
멋짐
SDL 바인딩을 지원하는 FreeBASIC의 386+ 대상 MS-DOS 실행 파일과 함께 쓰면 어떻게 될지 궁금해짐
[1] - https://github.com/freebasic/fbc- 직접 확인해볼 생각임
원래 DOS 출신인 OHRRPGCE를 다시 DOS로 포팅해야지 하고 몇 년째 마음먹고 있었음
그리고 SDL 1.2 시절에 있던 거의 모든 포트와 OS 지원을 SDL이 공격적으로 쳐냈던 걸 생각하면, SDL3가 DOS 지원을 되찾은 것은 꽤 놀라움
- 직접 확인해볼 생각임
-
완벽함
오늘 아침에 macOS 안의 VMware Fusion 안의 Debian GNU/Linux 안의 DOSBox-X 안의 Turbo C로 개발하고 있었는데 딱 맞는 소식임- 농담이었는지 진심이었는지 꼭 알고 싶음
- Linux용 turboc 변종이 있었나 싶음
수십 년 전에 turboc로 작업했던 기억이 어렴풋이 남아 있음 - 그렇다면 영화 Inception도 재밌게 볼 듯함 :)
-
엄밀히 말하면 이건 이미 HXDOS로 가능했음
DirectDraw를 SDL이 쓸 수 있을 만큼 충분히 잘 에뮬레이션했기 때문임- 잠깐, 뭐라고?
그럼 어떤 SDL 타깃으로 컴파일하는 건지 궁금함
Win32 독점 전체화면인지, 아니면 640x480 같은 VESA 해상도인지 궁금함
- 잠깐, 뭐라고?
-
SDL 같은 오픈소스 프로젝트에서 이런 지원이 들어가는 건 보통 변경이 얼마나 침습적인지, 그리고 기여자가 실제로 유지보수까지 계속할지에 달려 있음
프로젝트마다 정책은 다르고 SDL 정책은 모르지만, 이미 포트가 많으니 스스로 무엇을 감당하는지 알고 들어가는 거라 봄- 이런 희귀 아키텍처 지원은 거의 항상 꿈을 가진 한 사람, 그리고 그걸 실제로 만들고 유지하는 한 명의 영웅이 떠받침함
내가 가장 좋아하는 예는 openbsd luna88k https://www.openbsd.org/luna88k.html임
실제 사용자가 얼마나 있는지는 전혀 모르겠음. 아마 일본에서만 나온 꽤 희귀한 기계였던 것 같고, 사용자가 있다면 대부분 일본 쪽일 텐데 내 시야 밖이라 체감상 사용자는 포터 한 명뿐임
그런데도 매 릴리스마다 정식 공개일보다 몇 주 뒤 숲에서 툭 튀어나오듯 luna88k 파일과 패키지를 올려줌
실제 luna88k에서 컴파일하느라 오래 걸리는 게 아닐까 싶고, 어쨌든 그 정도면 OpenBSD의 공식 하드웨어 플랫폼으로 유지되기에 충분함
나 자신은 luna88k를 갖고 싶지도 않지만, 그렇게 계속 굴러가게 만드는 그 사람은 정말 존경스러움
- 이런 희귀 아키텍처 지원은 거의 항상 꿈을 가진 한 사람, 그리고 그걸 실제로 만들고 유지하는 한 명의 영웅이 떠받침함
-
SDL이 다시 Loki 시절의 뿌리로 돌아가는 느낌임
-
멋짐
왜냐고? 이유는 몰라도 멋지면 된다고 봄- 이제 DOS에서 Dota 2를 돌릴 수 있으니까
- 브라우저 기반 DOSBox가 워낙 쉽고 빠르게 돌아가서, DOS는 작은 게임은 물론 꽤 본격적인 게임까지도 올릴 수 있는 휴대성 좋은 타깃이 됨
인터넷 아카이브를 보면 알 수 있듯, 키보드와 마우스만 있으면 중반 90년대 AAA급 복잡도까지는 사실상 어디서나 실행 가능함
Tomb Raider, Command & Conquer, Quake 같은 게임들이 그렇고, 그냥 잘 돌아가는 플랫폼을 원한다면 꽤 매력적임
여기에 SDL까지 생기면 훨씬 쉬워짐 - FreeDOS는 기술적으로 보면 지금도 활발히 지원되는 현대적인 DOS임
- SDL은 크로스플랫폼 멀티미디어 라이브러리고, DOS도 플랫폼임
-
정말 기쁨
이건 나를 아주 행복하게 만듦