• 이용안내
  • 이상한 모자
  • 야채인간
  • 김민하 공화국
  • 신간 안내
혁명은 언제나 시기상조

Author: 이상한 모자

안드로이드 에뮬 게임기에서 ES-DE와 Standalone 에뮬레이터 연결 문제

2025년 12월 15일 by 이상한 모자

최근 이 문제를 깊이, AI 친구들과 함께 고민하였다.

증상은 ES-DE를 프론트엔드로 쓰고 있을 때 Retroarch로 구동하는 게임은 문제가 없지만, 외부의 에뮬레이터를 사용해야 하는 경우에는 제대로 작동하지 않고 에뮬레이터의 메인 화면 등으로 연결되는 문제이다. 내 경우에는 Duckstation(PS1), PPSSPP(PSP), Redream(Dreamcast), NetherSX2(PS2)가 말썽이었다.

핵심은 ES-DE가 ROM의 주소(위치)를 개별 에뮬레이터에 넘겨 줄 때, 어떤 형식으로 넘겨줄 것인가의 문제이다. 크게 보면 ES-DE는 3가지 변수를 사용할 수 있다.

1) ROMSAF

일괄 디폴트로 잡혀 있는 변수다. content://com.android.externalstorage.documents/… 와 같은 형태로 주소를 넘겨준다.

2) ROMPROVIDER

ES-DE가 생성하는 변수로 content://org.es_de.frontend.files/…의 형태이다.

3) ROMRAW

/storage/xxxx-xxxx/Games/ps2/xxx.iso와 같이 파일 문자열을 그대로 보낸다.

문제는 에뮬레이터에 따라서 1)로 해결되는 경우, 2)만 먹히는 경우, 3)만 먹히는 경우가 제각각이라는 것이다. 즉, 1)로 주소 전달이 실패하는 경우 2)나 3)으로 시도해봐야 한다는 것이다. 그러면 이 변수는 어디서 어떻게 바꿔줄 수 있는가? es_systems.xml에서 규정해야 한다. 이 파일은 바꾸고 싶은 부분만 발췌한 후 파일로 만든 다음에 ES-DE/custom_systems(처음 ES-DE 구동할 때에 어디에 폴더를 만들 것인지 설정했을 것이다. 바로 그 폴더이다…) 폴더에 저장하면 된다. 가령 기본 설정에 어떻게 반영되는지를 찾아보면 플레이스테이션 2의 경우는 다음과 같은 내용이다.

<system>
   <name>ps2</name>
   <fullname>Sony PlayStation 2</fullname>
   <path>%ROMPATH%/ps2</path>
   <extension>.bin .BIN .chd .CHD .ciso .CISO .cso .CSO .dump .DUMP .elf .ELF .gz .GZ .m3u .M3U .mdf .MDF .img .IMG .iso .ISO .isz .ISZ .ngr .NRG</extension>
   <command label="AetherSX2 (Standalone)">%EMULATOR_AETHERSX2% %ACTIVITY_CLEAR_TASK% %ACTIVITY_CLEAR_TOP% %ACTION%=android.intent.action.MAIN %EXTRA_bootPath%=%ROMSAF%</command>
   <command label="Play! (Standalone)">%EMULATOR_PLAY!% %ACTION%=android.intent.action.VIEW %DATA%=%ROMSAF%</command>
   <platform>ps2</platform>
   <theme>ps2</theme>
</system>

이대로 실행하면 NetherSX2는 파일 이름이 필요하다든지 못 찾겠다고 하면서 아무런 일도 하지 않는다. %EXTRA_bootPath%=%ROMSAF% 부분에서 ‘content://com.android.externalstorage.documents/… ‘을 해석해 ROM 파일 위치를 추출하는 게 아니라, 그냥 문자열 그대로를 파일 이름으로 받아서 ROM 위치를 못 찾는 것이다. 따라서 해당 변수를 ROMRAW로 바꿔 파일명 그대로를 전달해야 한다. 이를 적용하면 es_system.xml은 이렇게 만들어야 할 것이다.

<systemList>
   <system>
    <name>ps2</name>
    <fullname>Sony PlayStation 2</fullname>
    <path>%ROMPATH%/ps2</path>
    <extension>.bin .BIN .chd .CHD .ciso .CISO .cso .CSO .dump .DUMP .elf .ELF .gz .GZ .m3u .M3U .mdf .MDF .img .IMG .iso .ISO .isz .ISZ .ngr .NRG</extension>
    <command label="NetherSX2(AetherSX2) (Standalone)">%EMULATOR_AETHERSX2% %ACTIVITY_CLEAR_TASK% %ACTIVITY_CLEAR_TOP% %ACTION%=android.intent.action.MAIN %EXTRA_bootPath%=%ROMRAW%</command>
    <command label="Play! (Standalone)">%EMULATOR_PLAY!% %ACTION%=android.intent.action.VIEW %DATA%=%ROMSAF%</command>
    <platform>ps2</platform>
    <theme>ps2</theme>
  </system>
</systemList>

나머지도 마찬가지 원리에 따라서 진행하면 된다.

PPSSPP는 ROMPROVIDER, Redream도 ROMPROVIDER, DuckStation은 ROMRAW 변수가 먹혔다. 이를 다 적용하려면 아래와 같은 내용으로 es_system.xml 파일을 작성하면 된다.

<systemList>
<system>
<name>ps2</name>
<fullname>Sony PlayStation 2</fullname>
<path>%ROMPATH%/ps2</path>
<extension>.bin .BIN .chd .CHD .ciso .CISO .cso .CSO .dump .DUMP .elf .ELF .gz .GZ .m3u .M3U .mdf .MDF .img .IMG .iso .ISO .isz .ISZ .ngr .NRG</extension>
<command label="NetherSX2(AetherSX2) (Standalone)">%EMULATOR_AETHERSX2% %ACTIVITY_CLEAR_TASK% %ACTIVITY_CLEAR_TOP% %ACTION%=android.intent.action.MAIN %EXTRA_bootPath%=%ROMRAW%</command>
<command label="Play! (Standalone)">%EMULATOR_PLAY!% %ACTION%=android.intent.action.VIEW %DATA%=%ROMSAF%</command>
<platform>ps2</platform>
<theme>ps2</theme>
</system>
<system>
<name>psx</name>
<fullname>Sony PlayStation</fullname>
<path>%ROMPATH%/psx</path> <extension>.bin .BIN .cbn .CBN .ccd .CCD .chd .CHD .cue .CUE .ecm .ECM .exe .EXE .img .IMG .iso .ISO .m3u .M3U .mdf .MDF .mds .MDS .minipsf .MINIPSF .pbp .PBP .psexe .PSEXE .psf .PSF .toc .TOC .z .Z .znx .ZNX .7z .7Z .zip .ZIP</extension>
<command label="Beetle PSX">%EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mednafen_psx_libretro_android.so %EXTRA_ROM%=%ROM%</command>
<command label="Beetle PSX HW">%EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mednafen_psx_hw_libretro_android.so %EXTRA_ROM%=%ROM%</command>
<command label="PCSX ReARMed">%EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=pcsx_rearmed_libretro_android.so %EXTRA_ROM%=%ROM%</command>
<command label="SwanStation">%EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=swanstation_libretro_android.so %EXTRA_ROM%=%ROM%</command>
<command label="DuckStation (Standalone)">%EMULATOR_DUCKSTATION% %ACTIVITY_CLEAR_TASK% %ACTIVITY_CLEAR_TOP% %EXTRABOOL_resumeState%=false %EXTRA_bootPath%=%ROMRAW%</command>
<command label="ePSXe (Standalone)">%EMULATOR_EPSXE% %ACTION%=android.intent.action.MAIN %EXTRA_com.epsxe.ePSXe.isoName%=%ROMSAF%</command>
<command label="FPseNG (Standalone)">%EMULATOR_FPSE-NG% %ACTION%=android.intent.action.VIEW %DATA%=%ROMPROVIDER%</command>
<command label="FPse (Standalone)">%EMULATOR_FPSE% %ACTION%=android.intent.action.VIEW %DATA%=%ROMPROVIDER%</command>
<platform>psx</platform>
<theme>psx</theme>
</system>
<system>
<name>psp</name>
<fullname>Sony PlayStation Portable</fullname>
<path>%ROMPATH%/psp</path>
<extension>.chd .CHD .cso .CSO .elf .ELF .iso .ISO .pbp .PBP .prx .PRX .7z .7Z .zip .ZIP</extension>
<command label="PPSSPP">%EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=ppsspp_libretro_android.so %EXTRA_ROM%=%ROM%</command>
<command label="PPSSPP (Standalone)">%EMULATOR_PPSSPP% %ACTION%=android.intent.action.VIEW %CATEGORY%=android.intent.category.DEFAULT %DATA%=%ROMPROVIDER%</command>
<platform>psp</platform>
<theme>psp</theme>
</system>
<system>
<name>dreamcast</name>
<fullname>Sega Dreamcast</fullname>
<path>%ROMPATH%/dreamcast</path>
<extension>.cdi .CDI .chd .CHD .cue .CUE .dat .DAT .elf .ELF .gdi .GDI .iso .ISO .lst .LST .m3u .M3U .7z .7Z .zip .ZIP</extension>
<command label="Flycast">%EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=flycast_libretro_android.so %EXTRA_ROM%=%ROM%</command>
<command label="Flycast (Standalone)">%EMULATOR_FLYCAST% %ACTION%=android.intent.action.VIEW %DATA%=%ROM%</command>
<command label="Redream (Standalone)">%EMULATOR_REDREAM% %ACTION%=android.intent.action.VIEW %DATA%=%ROMPROVIDER%</command>
<platform>dreamcast</platform>
<theme>dreamcast</theme>
</system>
</systemList>

위의 파일은 오타가 있을 수 있으니 신중하게 고려하시기 바라고, 아무튼 이렇게 작성한 파일을 아까 파일이 있어야 할 경로로 넣으면 대체로 될 것이다. 다른 에뮬레이터의 경우, 뭐가 되고 뭐가 안 되는지는 맨땅에 헤딩하기로 찾아야 한다.

Azahar(NDS)와 melonDS Nightly(3DS)에 대해 추가 (정리 요약은 챗GPT가 했다)

ES-DE(안드로이드) Standalone 에뮬 연결 기록

대상

  1. Nintendo DS: melonDS Nightly

  2. Nintendo 3DS: Azahar

핵심 결론

  1. melonDS Nightly는 ES-DE에서 android.intent.action.VIEW로 실행하면서, ROM을 DATA에 ROMPROVIDER로 넣었을 때 성공했다.

  2. Azahar는 ES-DE에서 android.intent.action.VIEW로 실행하면서, ROM을 EXTRA_SelectedGame에 ROMSAF로 넣었을 때 성공했다.

왜 이 방식이 먹혔는가(관찰 기반 요약)

  • 같은 “ROM 주소”라도, 앱이 실제로 읽는 자리가 다르다.

  • melonDS Nightly는 “DATA로 들어온 URI” 경로에서 정상 실행이 되었고,

  • Azahar는 “특정 extra 키(SelectedGame)로 들어온 값”에서 정상 실행이 되었다.

적용 방법

  1. ES-DE의 커스텀 시스템 폴더(ES-DE 첫 실행 때 지정했던 저장소 경로)로 이동한다.

  2. custom_systems/es_systems.xml 파일을 만든다(또는 기존 커스텀 파일에 아래 시스템 블록을 추가한다).

  3. ES-DE를 완전히 종료 후 재실행한다.

  4. 해당 시스템(NDS, N3DS)에서 “대체 에뮬레이터” 또는 “실행기 선택”에서 방금 추가한 라벨을 선택해 실행한다.

es_systems.xml 예시

<?xml version="1.0"?>
<systemList>

<system>
<name>nds</name>
<fullname>Nintendo DS</fullname>
<path>%ROMPATH%/nds</path>
<extension>.nds .NDS .zip .ZIP .7z .7Z</extension>
<command label="melonDS Nightly (Standalone) VIEW DATA=ROMPROVIDER">%EMULATOR_MELONDS-NIGHTLY% %ACTIVITY_CLEAR_TASK% %ACTIVITY_CLEAR_TOP% %ACTION%=android.intent.action.VIEW %CATEGORY%=android.intent.category.DEFAULT %DATA%=%ROMPROVIDER%</command>
<platform>nds</platform>
<theme>nds</theme>
</system>

<system>
<name>n3ds</name>
<fullname>Nintendo 3DS</fullname>
<path>%ROMPATH%/3DS</path>
<extension>.3ds .3DS .3dsx .3DSX .app .APP .axf .AXF .cci .CCI .cxi .CXI .elf .ELF .7z .7Z .zip .ZIP</extension>
<command label="Azahar (Standalone) VIEW EXTRA_SelectedGame=ROMSAF">%EMULATOR_AZAHAR% %ACTIVITY_CLEAR_TASK% %ACTIVITY_CLEAR_TOP% %ACTION%=android.intent.action.VIEW %CATEGORY%=android.intent.category.DEFAULT %EXTRA_SelectedGame%=%ROMSAF%</command>
<platform>n3ds</platform>
<theme>n3ds</theme>
</system>

</systemList>

세가 새턴 Yaba Sanshiro 2 Pro 세팅에 대해 추가

  1. 문제를 한 문장으로 요약하면
    ES-DE가 “이 게임 파일을 열어라”라는 지시를 에뮬레이터로 보낼 때, 보통은 DATA 칸에 ROM 주소를 넣어 보냅니다.
    그런데 Yaba Sanshiro 2 Pro는 ROM 주소를 DATA 칸에서 읽지 않고, 특정 EXTRA 칸(정해진 이름의 추가 입력란)에서 읽습니다.
    그래서 ES-DE가 그 EXTRA 칸에 정확히 넣어 주도록 커맨드를 바꿔야 성공합니다.

  2. DATA와 EXTRA는 무엇이 다른가
    Android에서 다른 앱을 실행시키는 방식은 “인텐트”라는 전달 봉투로 생각하시면 됩니다.

(1) DATA는 봉투 겉면의 “대표 주소” 같은 자리입니다.
많은 앱들이 여기(예: DATA)에 파일 경로나 URI를 넣어 주면 그걸 읽고 실행합니다.

(2) EXTRA는 봉투 안에 들어있는 “추가 입력칸”들입니다.
예를 들어 “파일 경로는 이 칸”, “게임 코드(식별자)는 저 칸”처럼, 앱 개발자가 미리 정해둔 칸 이름으로 값을 받습니다.

Yaba Sanshiro 2 Pro는 “대표 주소(DATA)”를 보는 쪽이 아니라, “추가 입력칸(EXTRA)”에서 파일 경로를 읽는 쪽이라는 것이 이번 해결의 핵심입니다.

  1. 왜 Android 15에서 특히 기본 설정이 더 실패하기 쉬운가
    ES-DE 기본 설정은 보통 ROMSAF나 ROMPROVIDER 같은 content:// 형태(권한을 포함한 URI)로 DATA에 넘깁니다.
    Android 15에서는 저장소 권한과 URI 처리 방식이 더 엄격해져서, 어떤 앱은 이 content:// 주소를 제대로 해석하지 못하거나 권한을 못 받아서 실패하는 경우가 늘어납니다.

반면 ROMRAW는 /storage/…/파일명.chd 같은 “실제 파일 경로 문자열”이라, Yaba가 기대하는 방식에 더 가깝습니다.
그래서 이번 성공 커맨드도 ROM 경로는 ROMRAW를 쓰는 쪽으로 정리됩니다.

  1. 그래서 무엇을 어떻게 바꿔야 하나
    바꾸는 파일은 ES-DE의 커스텀 시스템 정의 파일인 es_systems.xml 입니다.

(1) 파일 위치
ES-DE 첫 실행 때 지정했던 저장소 경로 아래 custom_systems 폴더에 둡니다.
즉 “ES-DE가 쓰는 폴더/custom_systems/es_systems.xml” 입니다.

(2) 바꿀 대상
그 파일에서 새턴 시스템 블록, 즉 <name>saturn</name> 이 들어있는 덩어리를 찾습니다.

(3) 핵심 수정
Yaba용 실행 커맨드 한 줄을 추가하거나 수정합니다.
핵심은 ROM 경로를 DATA에 넣지 말고, Yaba가 정해둔 EXTRA 키 이름으로 넣는 것입니다.

  1. 성공한 커맨드가 하는 일(뜻풀이)
    성공 커맨드의 요점은 아래 두 값을 “EXTRA”로 넣는 것입니다.

(1) ROM 파일 경로를 넣는 칸
키 이름: org.uoyabause.android.FileNameEx
여기에 넣을 값: 실제 파일 경로 문자열, 즉 %ROMRAW%

(2) 게임 식별값을 넣는 칸
키 이름: org.uoyabause.android.gamecode
여기에 넣을 값: ES-DE에서 임시로 %BASENAME%를 사용(파일 이름 기반)

즉, 논리 구조는 이런 뜻입니다.
“야바산시로야, 이 파일(FileNameEx)을 열어라. 그리고 식별값(gamecode)은 이 값이다.”

  1. 따옴표가 왜 그렇게 중요하나
    파일 경로에는 공백이 들어갈 수 있습니다. 예를 들어
    /My Games/Saturn/Game Title.chd

따옴표가 없으면 Android 명령줄에서 공백을 기준으로 잘려서,
앞부분만 파일명으로 인식되는 문제가 생깁니다.

그래서 %ROMRAW% 같은 경로 값은 반드시 큰따옴표로 감싸
“%ROMRAW%” 형태로 전달해야 안전합니다.

  1. 적용 후 확인은 어디서 하나
    문제가 남으면 가장 먼저 ES-DE 로그(es_log.txt)를 봅니다.

로그에 다음처럼 찍히면 “EXTRA로 전달 자체는 됐다”는 뜻입니다.
Extra name: org.uoyabause.android.FileNameEx
게임파일.chd

여기에서 공백이 있는 파일명이 중간에서 잘려 보이면, 거의 확실하게 따옴표 처리 문제입니다.
즉 커맨드에 “%ROMRAW%” 형태로 들어갔는지부터 점검하면 됩니다.

  1. 정리
    이번 해결법의 핵심은 단순합니다.

(1) Yaba Sanshiro 2 Pro는 ROM 경로를 DATA가 아니라 EXTRA(정해진 키 이름)로 받는다.
(2) ES-DE의 saturn 시스템 커맨드에서 그 EXTRA 키에 ROMRAW 경로를, 따옴표로 감싸서 넣어 준다.
(3) 적용 후 ES-DE를 완전히 종료하고 재실행한 다음, 새턴에서 해당 라벨을 선택해 실행한다.
(4) 문제 시 로그에서 EXTRA 전달과 따옴표(공백 잘림)를 먼저 확인한다.

<system>
<name>saturn</name>
<fullname>Sega Saturn</fullname>
<path>%ROMPATH%/saturn</path>
<extension>.bin .BIN .ccd .CCD .chd .CHD .cue .CUE .img .IMG .iso .ISO .m3u .M3U .mdf .MDF .mds .MDS .7z .7Z .zip .ZIP</extension>
<command label="Yaba Sanshiro 2 Pro (Standalone)">%EMULATOR_YABASANSHIRO-2% %EXTRA_org.uoyabause.android.FileNameEx%="%ROMRAW%" %EXTRA_org.uoyabause.android.gamecode%="%BASENAME%"</command>
<platform>saturn</platform>
<theme>saturn</theme>
</system>
Posted in: 신변잡기, 잡감 Tagged: Duckstation, ES-DE, NetherSX2, PPSSPP, Redream, 안드로이드, 에뮬레이터

내란 1년

2025년 12월 3일 by 이상한 모자

수요일은 격주로 바쁘다. 한 주는 이것 저것 할 일이 많은데, 다른 한 주는 아예 일이 없다. 이번 주는 일이 없었어야 했던 날이다. 하지만 내란 1년이므로 일이 조금 있었다. 일정은 2개였지만 왠지 바쁘게 느껴졌고, 추웠다.

아무래도 지난해 12월 3일의 상황과 느낌을 개인적 차원에서 설명하는 내용이 많았는데, 남들이 현장에서 이리 저리 부딪칠 때 자리에 앉아서 떠드는 걸로 때운 것 같아 좀 죄책감 비슷한 것이 있었다. 그 때 국회에 가보지 못해 아쉽다는 생각을 해왔는데, 이번에 모처럼 국회를 찾아 일종의 ‘다크투어’를 했다. 옆에서 김종대님이 해설사 역할을 해 그 날의 상황을 생생하게 대리체험 할 수 있었다.

현장에서 보니, ‘이재명은 숲에 숨었지만 여당 대표인 나는 당당히…’라고 잘난 척을 하는 후니횽의 허세를 더 직관적으로 이해할 수 있었다. 국회 동쪽에 담을 넘어서 본관으로 넘어오는 곳에 솔밭이 있다. 해가 지고 나니 컴컴하고 으슥한 것이 매복을 하기에 좋은 공간 같았다. 국회의원들도 그런 생각을 했다고 한다. 당시에는 계엄군이 뭘 할지 예상할 수 없는 상황이었다. 그들로서는 당연히 몸을 조심할 수밖에 없다. 그런데 거기다 대고 나는 당당히 들어갔으며, 내가 모두를 구해낸 거나 다름이 없다는 식으로 말하는 사람을 도대체 어떻게 이해해야 할까?

Q. 국회에선 어땠나요?
A. “정문이 막혀 도서관 쪽으로 진입했는데, 우리가 들어간 직후 죄다 봉쇄됐어요. 본회의장에 들어가니 민주당 의원들이 겁먹은 표정으로 앉아있다가 안도하면서 ‘고맙다’고 인사하더군요. ‘여당이 왔으니 군인들에게 끌려나가진 않겠구나’고 생각한 거죠. 한참 뒤 이재명 대표가 들어왔는데, 굳이 저한테 오더군요. 의원들은 ‘피하세요’ 했지만 맞아줬죠. 뒷얘기인데, 해제 표결이 끝난 뒤에도 이재명 대표·우원식 국회의장이 제게 여러 번 전화했어요. 안 받았죠. 언론플레이 같은 정치적 활용 의도가 훤히 보여서죠.”

https://www.joongang.co.kr/article/25385087 

이런 사람을, 마치 희망은 후니횽 뿐이라는 듯… 일간지에다가 한동훈 각하 만세에 가까운 글을 써제끼는 중궈니횽은 어떻게 이해해야 하나? 심지어 당사자가 얘기를 안 해줬으면 이걸 어떻게 알지 싶은 대목도 있다.

주가조작 재판의 유죄판결은 사건의 전모를 꿰는 수사검사가 재판 전 과정에 참여한 덕. 그는 론스타 측 인사들을 법정에 세워 자백을 받아냈다.

(…)

당시 민주당은 항소를 결정한 당시 법무부 장관에게 엄청난 정치적 압박을 가했다. 심지어 윤 정권도 임기 내에 패소 판정을 받을지 모르는 항소를 달가워하지 않았다. 패소할 경우 주변의 만류에도 항소를 강행한 이는 엄청난 타격을 입을 것이다. 그럼에도 자신에게 닥칠 위험을 공적 책임감으로 기꺼이 끌어안은 관료가 그때만 해도 적어도 한 사람 있었다.

https://www.joongang.co.kr/article/25385441

관련 뉴스가 다 나와 있는데 내가 성실하지 못해 찾지 못한 것일 수도 있다. 어쩄든 이렇게까지… 오직 한 사람~ 분위기로 글을 쓰는 것은 창피하다. 이런 분들이 2022년에 윤석열의 자유민주주의 타령에 속아 오로지 민주당을 혼내줘야 한다는 일념으로 사실상의 윤석열 지지 활동(겉으로는 진보 지지라고 했으나, 아크로비스타까지 갔다고 본인이 실토한 사실을 놓고 보면 윤석열 안 찍었다는 식의 얘기는 포장지, 알리바이에 불과했다고 할 수밖에 없다)을 한 덕에 내란까지 이어지는 하나의 고리가 만들어 졌다고도 볼 수 있을 것이다.

이런 저런 생각을 하며 뒤숭숭한 가운데 저녁을 먹으러 갔다. 해물탕과 굴전을 먹으면서, 김종대님의 흥미진진한 말씀을 들었다. 군인들 얘기 등등을 들으니 헌법존중~~ TF 같은 걸 그냥 줄 세우기라고 평면적으로 평가하는 게 얼마나 게으른 일인지 알 수 있었다.

그런 얘기를 하다가 결국 AI 얘기로 빠졌는데… AI 담론, 정확히는 AGI 담론이 과장돼있다는 얘기로 시작을 했다. 요지는 아래의 글과 같은 얘기다.

샘 올트먼, 일론 머스크와 구글 등 미국의 거대 빅테크들이 한결같이 AGI를 목표로 치열한 AI 경쟁을 하는 것은 잘 알려져 있다. 이들이 새로운 버전의 AI 제품을 출시할 때마다 인간의 능력에 얼마나 가까워졌는지를 매번 강조하며, 앞으로 AGI에 도달할 시간이 얼마 남았는지 점을 치기도 한다. AGI라는 성배를 먼저 움켜쥔 기업과 국가는 엄청난 수익과 권력을 확보할 뿐만 아니라 다른 기업과 국가에 아무것도 남기지 않고 AI의 게임 규칙을 독점하게 된다는 것이 이들의 주장이다.

하지만 정말 그럴까? 최근 ‘포린어페어스’는 ‘AGI 환상에 치르는 대가’라는 기고를 통해, AGI가 무엇인지에 대한 제대로 된 합의도 없는 상황에서 AGI를 목표로 삼는 것은 오히려 경쟁에서 뒤질 가능성을 높인다고 문제 삼았다. 물론 현재 적자에 시달리는 AI 기업이 AGI라는 원대한 환상을 목표로 내걸면, ‘마케팅 차원’에서 투기적인 벤처 자본으로부터 대규모 추가 자본을 동원하는 데는 확실히 유리하다. 그러나 이는 보이지 않는 신화를 향해 헛된 경주를 하는 것이 될 수도 있다.

여기서 묘한 대조를 보이는 나라가 중국이다. 중국 사기업들은 미국처럼 AGI에 매력을 느끼지만, 중국 정치권은 전체적으로 AGI 경쟁보다는 ‘AI의 실용적 응용’에 방점을 찍고 있기 때문이다. 대표적인 사례가 지난 8월26일 중국 정부가 발표한 ‘AI 플러스’ 행동 심층 실시에 관한 의견이다. 과학기술, 산업, 소비, 민생, 거버넌스, 글로벌 협력 등 분야를 중심으로 AI를 다양하게 응용하겠다는 것이다.

https://www.khan.co.kr/article/202510212027015

이런 얘기하면 보통 AI를 제대로 쓰지도 못하는 놈들이 어쩌구 할텐데, 김종대님은 AI를 상당히 고급지게 사용하는 것으로 알려져 있다. 지난 번에 대선할 때 들은 얘기가 있는데, 토론 답변의 모범답안 같은 걸 만들 때 AI로 잘 다듬었다는 것이다. 그러면 그걸 누가 못하냐 라고 할텐데, 그때 내가 들은 얘기는 AI를 학습을 시켜서 자신의 전용 도구로 만들었다는 거였다. 설마 모델을 파인튜닝해서 쓴다는 건가? GPT api를 발급 받아서… 그런 생각을 했었는데, 오늘 들어보니 오픈인터프리터 혹은 anything llm류의 도구까지 활용하는 듯한 인상을 받았다.

그런 식의 AI 활용에 관한 많은 얘기가 있었는데, 연구자면 그런 활용이 필요하겠지만 평론가 수준에서는 그 정도까지는 안 해도 된다. 나이 문제인 것도 같다. 김종대님은 나이를 먹을수록 AI를 활용해 떨어진 기억 및 추론 능력 등을 보조할 필요가 있다고 주장했다. 나는 하는 일도 그렇고 나이(영포티)도 그렇고 아직은 그렇게까지 안 들어가도 될 거 같다. 그래서 챗gpt에다가 글 쓴 걸 던져주고 반론을 받아 보완을 하고, 모르는 학자나 책 이름을 찾아낼 때 실마리를 얻는 정도로 활용하고 있다고 말했는데, 왠지 스스로 쪼렙이 된 거 같아서 기분이 좀 그랬다.

그래서 나에게 필요한 방식으로… 기사를 하이라이트, 저장, 데이터베이스화 하는 등의 방법을 모색해보고자 했다. 이걸 챗gpt에게 물어보니 여러 대안을 가르쳐 줬는데, 유료 서비스를 쓰고 옵시디언을 연동하는 정도로 해결할 수 있다는 것이었다. 이것까지 AI에 의존하다니… 이런 판국에… AI를 그렇게까지 쓰면 지구가 너무 괴롭지 않을까요 라고 말하는 것은 무리였다.

이상하네. 분명 내란 1년으로 시작을 했는데 AI로 끝나버린, 다분히 2025년 같은 그러한 하루였다.

Posted in: 신변잡기, 잡감 Tagged: 김종대, 내란, 다크투어, 비상계엄, 시사인, 윤석열, 한동훈

심야노동을 할 거냐 말 거냐

2025년 11월 22일 by 이상한 모자

SNS에서 새벽배송 논쟁을 했다는 얘기를 전해 듣기는 했다. 그러나 굳이 찾아보지 않았다. SNS 입씨름이 문제 해결에 도움이 된 예를 보지 못했다. 논쟁의 당사자들은 자기들끼리 뭘 배웠다는 둥 진도를 나가자는 둥 하지만, 다 자기만족적 서사에 그칠 뿐이다. SNS 논쟁이라는 걸 한지 15년도 넘었을 텐데, 아직도 담론 수준이 이 모양 이 꼴이라는 걸 보면 알 수 있다. SNS는 공론장도 뭐도 아니고, 술자리에서 떠들다 사라졌을 옹알이들이 온라인에 그럴듯한 얘기처럼 나열되어 있는, 노이즈의 집합체일 뿐이다.

그러니 그냥 SNS에는 일기나 적고 만족하는 것이 좋다. 자기 생각 정리용으로는 괜찮다. 그러나 남의 일기에 관심을 가질 필연은 없다. 이게 내가 SNS 논쟁에 관심을 가지지 않는 이유이다.

유일하게 SNS 논쟁이 효용이 있는 분야라고 한다면, 메타-SNS적 분석을 해야 할 때라고 말할 수 있다. 사람들이 SNS에서 떠드는 양상 자체를 분석하는 것은 유의미하다는 거다. 가령 필터버블이니 뭐 그런 얘기 있잖나.

하여간, 그런 와중에 이 얘기를 소재로 조선일보가 토요일자 칼럼에 떡하니 써놨기에, 여기다가 생각 정리용 메모를 남기는 것이다.

https://www.chosun.com/opinion/2025/11/21/5JUEK4CTHNCCRDZRPCERBLNEKA/

다시 한 번 강조하지만 저 글의 등장인물들이 실제 어떤 주장을 했는지 난 정확히 모른다. 지금 쓰는 것도 저 사람들 주장에 대한 얘기가 아니고, 그간 언론에 등장한 새벽배송을 둘러싼 여러 얘기에 대한 거다. 그러나 나한테 와서 저 글에 등장하는 사람들 얘기는 하지 마시길 바라고.

새벽배송에 대한 토론이니 주장이니 보고 느낀 바는, 그래서 할 것인가 말 것인가 라는 점, 어떤 의미에서는 우선순위의 문제라는 것이다. 가령 여러 우려를 할 수 있다. 심야노동을 금지하면 노동자의 임금 손해가 우려되지 않는가? 그렇다. 심야노동을 금지하더라도 노동자는 임금 보전을 위해 투잡을 뛰지 않겠는가? 그럴 수 있다. 그 외 여러 부작용이 있지 않겠는가? 그럴 수도 있다. 그렇다면 심야노동을 금지하는 것은 오히려 퇴행이 아닌가? 그렇지 않다.

이런 논쟁, 처음하는 게 아니다. 2000년대 초반에 나온 노래를 보면, 이런 가사가 있다. “어느 새 탕뛰기의 노예가 되어 힘겨운 하루가 덧없이 저무네” … 이건 일전에 여기다가 기록을 남겨놓은 바 있으니 궁금하면 찾아보시고… (클릭). 아무튼 이 가사에 나오는 ‘탕뛰기’가 뭐냐면 돈을 일당으로 주는 게 아니고 건당으로 주는 거다. 한 번 왔다갔다 하는 걸 단위로 돈을 주기 때문에 건설기계를 다루는 노동자들이 잠을 줄여서 일을 한다. 한 탕이라도 더 뛰어야 기대수익을 채울 수 있으므로…

이때 노조 등의 주장은 탕뛰기를 거부하고 일당으로 받자는 거였다. 저 노래도 그런 바탕에서 나왔기 때문에 ‘탕뛰기의 노예가 되어’라는 대목이 있는 거다. 현장에서 당연히 볼멘소리들이 있지 않았겠나? 열심히 일한만큼 능력대로 가져가는 게 낫고 그게 더 이익이다 라는 식인데, 그게 사실인 부분도 있을 거다. 그럼에도 일당으로 받자고 한 이유가 뭐겠나? 대개의 사람은 돈이 걸리면 자기 몸을 제대로 챙기지 않기 때문이다. 특히 운전을 하는 분야는 자기 혼자 불행해지는 게 아니라 남까지 불행하게 할 수 있다. 사고라도 내봐라. 실제 그런 불행이 있으니까 이런 결론으로 간 거다.

갑자기 탕뛰기가 왜 나오냐 할 수 있는데, 노동조건을 제한하는 등의 조치가 반드시 노동자에게 도움이 되지 않는다 라는 얘길 갖고 입씨름 하는 이 구도 자체가 이미 고전이고 클리셰라는 거다. 때마다 나오는 거다. 주52시간 얘기 할 때도 똑같이 했다. 그런데 중요한 것은, 그래서 그 결론이 대안을 말하는 것이냐 아니면 결국 아무것도 하지 말자는 거냐로 가느냐에 있다. 가령 위의 조선일보 글에 나온 표현을 쓰자면, 쿠팡만큼 중소기업의 임금이 인상되어야 한다… 그런 얘기 할 수 있다. 그런데 ‘심야노동 제한 또는 금지를 추진할 수 있지만, 전반적인 노동조건 개선을 함께 이룰 수 있는 대안도 제시되어야 한다’고 말하는 것과, ‘전반적인 임금 인상이 어렵기 때문에 심야노동 제한 또는 금지는 말하지 말아야 한다’고 말하는 것은 다른 문제이다.

가령 주5일제든, 주52시간제든, 아니면 심야노동 제한 또는 금지이든 그걸 하기 위해 필요한 전제 조건이 있다고 하면, 우리는 영원히 아무것도 못하는 상태에 머물러 있어야 한다. 업계의 전반적 임금 인상은 언제 달성되는가? 그것에는 전제가 없는가? 이런 저런 전제를 얼마든지 달 수 있다. 심지어 어떤 의미에서는 그게 진보의 목표가 아니었던 적도 없다. 늘 모색하지만 잘 안 되는 여러 주제 중 하나일 뿐이다. 그래서 이런 담론은 보통 조선일보가 썼듯 ‘현실을 모르는 책상머리 진보’, ‘선의의 부작용’, ‘감성에 의존하는 낭만적 진보’ 류의 정치적 프레임으로 연결된다.

누가 옳고 누가 틀렸다는 얘길 하기 위해서 이러고 있는 게 아니라고 분명히 서두에도 썼는데, 내 주요 관심사는 이런 식의 프레이밍에 있다. 진보가 뭘 하자고 주장을 하면 보수 이데올로그들이 보통 이런 구도를 형성한다. 주52시간제도 마찬가지였다. 심지어 문통이 영화 판도라를 보고 탈원전을 결심했다는, 사실이 아닌 핵발전주의자들의 주장도 거의 사실처럼 보도하고 주장했는데, 이것도 같은 프레임(감성과 선의에만 기댄, 현실을 모르는 책상머리 낭만적 진보)에 속해 있다. 조선일보가 이번 일을 소재로 칼럼을 쓴 것도 정확히 여기에 들어간다. 이런 태도는 결국 ‘고통스러운 오늘이 최선’이라는 것으로, 애초에 진보의 주장과 행동을 무력화 하는 것을 목표로 하고 있다.

심야노동의 제한 또는 금지를 주장하는 쪽에서는 오히려 여러 절충안을 얘기하고 있다. 금지는 아니더라도 업무를 줄여 시간을 조정해보자, 정 어려우면 2교대를 해라, 일단 논의에 참여해라 등등… 이런 논의가 담긴 언론 보도와 칼럼을 유튜브에서 소개했는데, 내 나름대로의 노력이다.

상대편에서는 쿠팡 새벽배송이 무슨 택배기사의 축복인 것처럼 떠들기도 했는데, 실제 그렇지 않다는 주장과 보도도 꽤 있었다. 새벽배송 기사들을 대상으로 과거 조사한 결과가 그랬고, 사망한 기사의 유족이 밝힌 것처럼 남의 아이디를 빌려서라도 연속 근무를 대리점이 강요했다는 정황도 있다.

왜 쿠팡은 침묵하고 노동자와 노동자, 노동자와 소비자 간의 대립구도만 남았느냐에 대한 탄식도 있었는데, 당연하지 않나? 다들 이렇게 자본이 가려는 방향을 유지하기 위해 알아서 싸워주고 있는데 기업이 뭐하러 나서겠나?

계획을 최대한 신중하게 세워야 하는 문제가 많지만, 일단 행동에 나선 이후에 고쳐나갈 문제도 있을 것이다. 여러 대안을 통해 심야노동 제한 또는 금지의 조건을 만드는 방법도 있겠지만, 심야노동 제한 또는 금지로부터 시작해야 나머지 조건을 변화시키는 것도 가능할 수 있다는 지적도 있었다. 가령 여러 반대와 이런 저런 전제 조건을 거론하는 목소리에도 불구, 주52시간을 도입했기 때문에 생긴 긍정적 변화들이 있지 않는가. 물론 상대쪽에선 이런 저런 부작용을 열거하겠지만, 그건 주52시간의 토대 위에서 해결하면 되는 것이다.

마지막에 가면, 이게 뭐 그리 긴박한 문제냐 라는 공격에 도달할 수 있다. 그러나 쿠팡이든 SPC든 심야노동을 제한하는 것은 긴박한 과제이다. 심야노동이 발암물질이라면 고등어는 왜 먹느냐 라는 비아냥도 보수언론에 많이 등장하지만, 고등어에는 적어도 선택권이 있다. 그 외 그럴거면 이것도 금지해라, 저것도 금지해라 이딴 소리도 하는데, 할 수 있으면 해야지. 하시죠 그럼? 아무튼, 이건 노동이 밤을 자본에게 속절없이 내주고 있는, 전선의 문제라는 게 본질이다. 많이들 보셨겠으나, 경향신문의 김승섭 교수 인터뷰가 이 문제를 잘 설명하고 있다고 본다.

https://www.khan.co.kr/article/202511192122005

앞에서 쓴 내용 다 관련 기사다 칼럼을 링크할 수 있는데, 어차피 읽지도 보지도 않을 것이므로 안 한다. 심야노동에 대한 얘기를 우리만 하는 게 아니고 서구권도 다 한다. 다만 노동이 상대적으로 강력하게 조직되어 있는 쪽과 아닌 쪽의 상황이 다른 거다. 이런 상황을 조망하는 것에는 상대적으로 무관심하면서 메신저에 대해서만 떠드는 일은 이제 피곤하다.

Posted in: 잡감, 정치 사회 현안 Tagged: 새벽배송, 심야노동, 쿠팡
« 이전 1 2 3 4 … 471 다음 »

최근 글

  • 잉잉 나더러 올드래요 잉잉??
  • 감사하면서 살자
  • 포퓰리즘에 대한 좋은 말씀
  • 2026년, 변비
  • 바이브 코딩

분류

누적 카운터

  • 1,537,797 hits

블로그 구독

Flickr 사진

추가 사진

____________

  • 로그인
  • 입력 내용 피드
  • 댓글 피드
  • WordPress.org

Copyright © 2026 혁명은 언제나 시기상조.

Omega Child (Weirdhat) WordPress Theme by ThemeHall