
ïŒç§ãéçºè
ã§ããïŒ Emboxãªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã§ã¯ãOpenGLã®ãµããŒãããã°ããåã«ç»å ŽããŸããããå®çšçãªããã©ãŒãã³ã¹ãã§ãã¯ã¯ãªããããã€ãã®ã°ã©ãã£ãã¯ããªããã£ããæã€ã·ãŒã³ã®ã¿ãã¬ã³ããªã³ã°ããŸããã
ç§ã¯ã²ãŒã éçºè
ã«æ¬åœã«èå³ã¯ãããŸããã§ãããããã¡ããã²ãŒã ã奜ãã§ãããã¯æ¥œããããšãããã®ã«è¯ãæ¹æ³ã§ãããåæã«OpenGLããã§ãã¯ããã²ãŒã ãOSãšã©ã®ããã«çžäºäœçšãããã確èªããŸãã
ãã®èšäºã§ã¯ãEmboxã§Quake3ããã«ãããŠå®è¡ããæ¹æ³ã«ã€ããŠèª¬æããŸãã
ããæ£ç¢ºã«ã¯ã Quake3èªäœã¯å®è¡ããŸãããã ããã«åºã¥ããŠioquake3ãå®è¡ããŸããããã«ã¯ãªãŒãã³ãœãŒã¹ã³ãŒãããããŸãã ç°¡åã«ããããã«ãioquake3ãåã«quakeãšåŒã³ãŸã:)
ãã®èšäºã§ã¯Quakeã®ãœãŒã¹ã³ãŒããšãã®ã¢ãŒããã¯ãã£ãåæããªãããšãããã«äºçŽããŸãïŒãã®èšäºã«ã€ããŠã¯Habréã«ç¿»èš³ããããŸã ïŒããã®èšäºã§ã¯ãæ°ãããªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã§ã²ãŒã ãéå§ããæ¹æ³ã«çŠç¹ãåœãŠãŸãã
ãã®èšäºã«èšèŒãããŠããã³ãŒããã©ã°ã¡ã³ãã¯ãçè§£ãæ·±ããããã«ç°¡ç¥åãããŠããŸãããšã©ãŒã®ãã§ãã¯ã¯çç¥ãããæ¬äŒŒã³ãŒãã䜿çšãããŠããŸãã ãªãªãžãã«ã®ãœãŒã¹ã¯ãªããžããªã«ãããŸã ã
äŸåé¢ä¿
å¥åŠãªããšã«ãQuake3ã®ãã«ãã«å¿
èŠãªã©ã€ãã©ãªã¯ããã»ã©å€ããããŸããã å¿
èŠãªãã®ïŒ
- POSIX + LibC-
malloc()
/ memcpy()
/ printf()
ãªã© - libcurl-ãããã¯ãŒãã³ã°
- Mesa3D -OpenGLãµããŒã
- SDL-å
¥åããã³ãªãŒãã£ãªããã€ã¹ã®ãµããŒã
æåã®æ®µèœã§ã¯ããã¹ãŠãæç¢ºã«ãªã£ãŠããŸãããããã®é¢æ°ããªããšãCã§éçºãããšãã«è¡ãã®ãé£ããããããã®åŒã³åºãã®äœ¿çšã¯éåžžã«æåŸ
ãããŸãã ãããã£ãŠããããã®ã€ã³ã¿ãŒãã§ã€ã¹ã®ãµããŒãã¯ãäºå®äžãã¹ãŠã®ãªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã§äœããã®æ¹æ³ã§è¡ããããã®å Žåãæ©èœã远å ããå¿
èŠã¯ã»ãšãã©ãããŸããã§ããã ç§ã¯æ®ãã«å¯ŸåŠããªããã°ãªããŸããã§ããã
libcurl
æãç°¡åã§ããã libcurlããã«ãããã«ã¯Libcã§ååã§ãïŒãã¡ãããäžéšã®æ©èœã¯å©çšã§ããŸããããå¿
èŠãããŸããïŒã ãã®ã©ã€ãã©ãªã®æ§æãšã³ã³ãã€ã«ã¯éçã«éåžžã«ç°¡åã§ãã
éåžžãã¢ããªã±ãŒã·ã§ã³ãšã©ã€ãã©ãªã¯åçã«ãªã³ã¯ããŸããã Emboxã§ã¯ãã¡ã€ã³ã¢ãŒãã¯1ã€ã®ç»åã«ãªã³ã¯ããŠããŸãããã¹ãŠãéçã«ãªã³ã¯ããŸãã
䜿çšãããã«ãã·ã¹ãã ã«ãã£ãŠãç¹å®ã®æé ã¯ç°ãªããŸãããæå³ã¯æ¬¡ã®ããã«ãªããŸãã
wget https://curl.haxx.se/download/curl-7.61.1.tar.gz tar -xf curl-7.61.1.tar.gz cd curl-7.61.1 ./configure --enable-static --host=i386-unknown-none -disable-shared make ls ./lib/.libs/libcurl.a
ã¡ãµ/ OpenGL
Mesaã¯ã°ã©ãã£ãã¯ãæäœããããã®ãªãŒãã³ãœãŒã¹ãã¬ãŒã ã¯ãŒã¯ã§ããã倿°ã®ã€ã³ã¿ãŒãã§ã€ã¹ïŒOpenCLãVulkanãªã©ïŒããµããŒãããŠããŸããããã®å Žåã¯OpenGLã«èå³ããããŸãã ãã®ãããªå€§ããªãã¬ãŒã ã¯ãŒã¯ã®ç§»æ€ã¯ãå¥ã®èšäºã®ãããã¯ã§ãã Embox Mesa3Dãæ¢ã«æã£ãŠãããã®ã ãã«å¶éããŸã:)ãã¡ãããããã§ã¯OpenGLå®è£
ãé©ããŠããŸãã
Sdl
SDLã¯ãå
¥åããã€ã¹ããªãŒãã£ãªãã°ã©ãã£ãã¯ã¹ãæäœããããã®ã¯ãã¹ãã©ãããã©ãŒã ãã¬ãŒã ã¯ãŒã¯ã§ãã
ããã§ã¯ãã°ã©ãã£ãã¯ã¹ä»¥å€ã®ãã¹ãŠããã³ããŒã§åŠçãããã¬ãŒã ãæç»ããããã«ããã€ã¹ã¿ã颿°ãåŒã³åºããããã確èªããŸãã
ã°ã©ãã£ãã¯ãæäœããããã®ããã¯ãšã³ãã¯ã SDL2-2.0.8/src/video/SDL_video.c
èšå®ãããŠããŸãã
次ã®ããã«ãªããŸãã
static VideoBootStrap *bootstrap[] = { #if SDL_VIDEO_DRIVER_COCOA &COCOA_bootstrap, #endif #if SDL_VIDEO_DRIVER_X11 &X11_bootstrap, #endif ... }
æ°ãããã©ãããã©ãŒã ã®ãéåžžã®ããµããŒãã«VideoBootStrap
ãªãããã«ã VideoBootStrap
远å ããã ãVideoBootStrap
ç°¡åã«ããããã«ãããšãã°src/video/qnx/video.c
ãŸãã¯src/video/raspberry/SDL_rpivideo.c
ãªã©ã®src/video/raspberry/SDL_rpivideo.c
ã䜿çšã§ããŸãããæåã«å®è£
ãã»ãšãã©ç©ºã«ããŸãã
typedef struct VideoBootStrap { const char *name; const char *desc;``` int (*available) (void); SDL_VideoDevice *(*create) (int devindex); } VideoBootStrap; static SDL_VideoDevice *createDevice(int devindex) { SDL_VideoDevice *device; device = (SDL_VideoDevice *)SDL_calloc(1, sizeof(SDL_VideoDevice)); if (device == NULL) { return NULL; } return device; } static int available() { return 1; } VideoBootStrap EMBOX_bootstrap = { "embox", "EMBOX Screen", available, createDevice };
VideoBootStrap
ãé
åã«è¿œå ããŸãã
static VideoBootStrap *bootstrap[] = { &EMBOX_bootstrap, #if SDL_VIDEO_DRIVER_COCOA &COCOA_bootstrap, #endif #if SDL_VIDEO_DRIVER_X11 &X11_bootstrap, #endif ... }
åºæ¬çã«ããã®æç¹ã§ãã§ã«SDLãã³ã³ãã€ã«ã§ããŸãã libcurlãšåæ§ã«ãã³ã³ãã€ã«ã®è©³çްã¯ç¹å®ã®ãã«ãã·ã¹ãã ã«äŸåããŸãããã©ããããããæ¬¡ã®ãããªããšãããå¿
èŠããããŸãã
./configure --host=i386-unknown-none \ --enable-static \ --enable-audio=no \ --enable-video-directfb=no \ --enable-directfb-shared=no \ --enable-video-vulkan=no \ --enable-video-dummy=no \ --with-x=no make ls build/.libs/libSDL2.a
Quakeèªèº«ã眮ã
Quake3ã¯åçã©ã€ãã©ãªã®äœ¿çšã䌎ããŸãããä»ã®ãã¹ãŠãšåæ§ã«éçã«ãªã³ã¯ããŸãã
ãããè¡ãã«ã¯ãMakefileã§ããã€ãã®å€æ°ãèšå®ããŸã
CROSS_COMPILING=1 USE_OPENAL=0 USE_OPENAL_DLOPEN=0 USE_RENDERER_DLOPEN=0 SHLIBLDFLAGS=-static
æåã®æã¡äžã
ç°¡åã«ããããã«ãqemu / x86ã§å®è¡ããŸãã ãããè¡ãã«ã¯ããããã€ã³ã¹ããŒã«ããå¿
èŠããããŸãïŒãããšä»¥äžã§ã¯Debianã®ã³ãã³ãããããŸããä»ã®ãã£ã¹ããªãã¥ãŒã·ã§ã³ããã±ãŒãžã¯ç°ãªãæ¹æ³ã§åŒã³åºãããå ŽåããããŸãïŒã
sudo apt install qemu-system-i386
ãããŠãæã¡äžãèªäœïŒ
qemu-system-i386 -kernel build/base/bin/embox -m 1024 -vga std -serial stdio
ãã ããQuakeãèµ·åãããšãããã«ãšã©ãŒãçºçããŸã
> quake3 EXCEPTION [0x6]: error = 00000000 EAX=00000001 EBX=00d56370 ECX=80200001 EDX=0781abfd GS=00000010 FS=00000010 ES=00000010 DS=00000010 EDI=007b5740 ESI=007b5740 EBP=338968ec EIP=0081d370 CS=00000008 EFLAGS=00210202 ESP=37895d6d SS=53535353
ãšã©ãŒã¯ã²ãŒã ã§ã¯ãªããªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã«ãã£ãŠè¡šç€ºãããŸãã Debagã¯ããã®ãšã©ãŒã¯QEMUã®x86ã®äžå®å
šãªSIMDãµããŒããåå ã§ããããšã瀺ããŸãããåœä»€ã®äžéšã¯ãµããŒãããããäžæãªã³ãã³ãäŸå€ïŒç¡å¹ãªãªãã³ãŒãïŒãã¹ããŒããŸãã updïŒã³ã¡ã³ãã§WGHã瀺åããããã«ãæ¬åœã®åé¡ã¯ãcr0 / cr4ã§SSEãµããŒããæç€ºçã«æå¹ã«ããã®ãå¿ããŠããããããã¹ãŠãQEMUã§åé¡ãªãããšã§ããã
ããã¯Quakeèªäœã§ã¯ãªããOpenLibMã§çºçããŸãïŒããã¯æ°åŠé¢æ°expf()
ãå®è£
ããããã«äœ¿çšããã©ã€ãã©ãªã§ãïŒã __test_sse()
ãSSEã§å®éã®ãã§ãã¯ãè¡ããªãããã«__test_sse()
ããããé©çšããŸãããåã«ãµããŒãããªããšèããŠããŸãã
äžèšã®æé ã¯å®è¡ããã®ã«ååã§ãããã³ã³ãœãŒã«ã«æ¬¡ã®åºåã衚瀺ãããŸãã
> quake3 ioq3 1.36 linux-x86_64 Nov 1 2018 SSE instruction set not available ----- FS_Startup ----- We are looking in the current search path: //.q3a/baseq3 ./baseq3 ---------------------- 0 files in pk3 files "pak0.pk3" is missing. Please copy it from your legitimate Q3 CDROM. Point Release files are missing. Please re-install the 1.32 point release. Also check that your ioq3 executable is in the correct place and that every file in the "baseq3 " directory is present and readable ERROR: couldn't open crashlog.txt
ãã§ã«æªãã¯ãããŸããããQuake3ã¯èµ·åããããšããŠãšã©ãŒã¡ãã»ãŒãžã衚瀺ããŸãïŒ ã芧ã®ãšããã圌ã«ã¯baseq3
ãã£ã¬ã¯ããªã«ãã¡ã€ã«ãããbaseq3
ã ãµãŠã³ãããã¯ã¹ãã£ããã®ä»ãã¹ãŠãå«ãŸããŠããŸãã pak0.pk3
ã¯ãã©ã€ã»ã³ã¹ãããCD-ROMããååŸããå¿
èŠãããããšã«æ³šæããŠãã ããïŒã¯ãããªãŒãã³ãœãŒã¹ã¯ç¡æäœ¿çšãæå³ãããã®ã§ã¯ãããŸããïŒã
ãã£ã¹ã¯ã®æºå
sudo apt install qemu-utils # qcow2- qemu-img create -f qcow2 quake.img 1G # nbd sudo modprobe nbd max_part=63 # qcow2- sudo qemu-nbd -c /dev/nbd0 quake.img sudo mkfs.ext4 /dev/nbd0 sudo mount /dev/nbd0 /mnt cp -r path/to/q3/baseq3 /mnt sync sudo umount /mnt sudo qemu-nbd -d /dev/nbd0
ããã§ããããã¯ããã€ã¹ãqemuã«è»¢éã§ããŸã
qemu-system-i386 -kernel build/base/bin/embox -m 1024 -vga std -serial stdio -hda quake.img
ã·ã¹ãã ãèµ·åãããããã£ã¹ã¯ã/mnt
ããŠã³ããããã®ãã£ã¬ã¯ããªã§quake3ãå®è¡ããŸããä»åã¯åŸã§ã¯ã©ãã·ã¥ããŸã
> mount -t ext4 /dev/hda1 /mnt > cd /mnt > quake3 ioq3 1.36 linux-x86_64 Nov 1 2018 SSE instruction set not available ----- FS_Startup ----- We are looking in the current search path: //.q3a/baseq3 ./baseq3 ./baseq3/pak8.pk3 (9 files) ./baseq3/pak7.pk3 (4 files) ./baseq3/pak6.pk3 (64 files) ./baseq3/pak5.pk3 (7 files) ./baseq3/pak4.pk3 (272 files) ./baseq3/pak3.pk3 (4 files) ./baseq3/pak2.pk3 (148 files) ./baseq3/pak1.pk3 (26 files) ./baseq3/pak0.pk3 (3539 files) ---------------------- 4073 files in pk3 files execing default.cfg couldn't exec q3config.cfg couldn't exec autoexec.cfg Hunk_Clear: reset the hunk ok Com_RandomBytes: using weak randomization ----- Client Initialization ----- Couldn't read q3history. ----- Initializing Renderer ---- ------------------------------- QKEY building random string Com_RandomBytes: using weak randomization QKEY generated ----- Client Initialization Complete ----- ----- R_Init ----- tty]EXCEPTION [0xe]: error = 00000000 EAX=00000000 EBX=00d2a2d4 ECX=00000000 EDX=111011e0 GS=00000010 FS=00000010 ES=00000010 DS=00000010 EDI=0366d158 ESI=111011e0 EBP=37869918 EIP=00000000 CS=00000008 EFLAGS=00010212 ESP=006ef6ca SS=111011e0 EXCEPTION [0xe]: error = 00000000
ãã®ãšã©ãŒã¯ãQemuã®SIMDã§ãçºçããŸãã updïŒã³ã¡ã³ãã§WGHã瀺åããããã«ãæ¬åœã®åé¡ã¯ãcr0 / cr4ã§SSEãµããŒããæç€ºçã«æå¹ã«ããã®ãå¿ããŠããããããã¹ãŠãQEMUã§åé¡ãªãããšã§ããã ä»åã¯ãåœä»€ãQuake3 x86ä»®æ³ãã·ã³ã§äœ¿çšãããŸãã ãã®åé¡ã¯ãx86ã®å®è£
ãè§£éãããVMã«çœ®ãæããããšã§è§£æ±ºããŸããïŒQuake3ä»®æ³ãã·ã³ãšãååãšããŠã¢ãŒããã¯ãã£äžã®æ©èœã«ã€ããŠã¯ãåãèšäºã§ãã¹ãŠãèªãããšãã§ããŸãïŒã ãã®åŸãSDLã®é¢æ°ãåŒã³åºããå§ããŸããããã¡ããäœãèµ·ãããŸããã ãããã®é¢æ°ã¯ä»ã®ãšããäœãããŸããã
ã°ã©ãã£ãã¯ã¹ã®ãµããŒãã远å ãã
static SDL_VideoDevice *createDevice(int devindex) { ... device->GL_GetProcAddress = glGetProcAddress; device->GL_CreateContext = glCreateContext; ... } SDL_GLContext glCreateContext(_THIS, SDL_Window *window) { OSMesaContext ctx; sdl_init_buffers(); ctx = OSMesaCreateContextExt(OSMESA_BGRA, 16, 0, 0, NULL); OSMesaMakeCurrent(ctx, fb_base, GL_UNSIGNED_BYTE, fb_width, fb_height); return ctx; }
2çªç®ã®ãã³ãã©ãŒã¯ãOpenGLãæäœãããšãã«åŒã³åºã颿°ãSDLã«äŒããããã«å¿
èŠã§ãã
ãããè¡ãã«ã¯ãé
åãéå§ããéå§ããéå§ãŸã§ã次ã®ãããªæ¬ èœããŠããåŒã³åºãã確èªããŸãã
static struct { char *proc; void *fn; } embox_sdl_tbl[] = { { "glClear", glClear }, { "glClearColor", glClearColor }, { "glColor4f", glColor4f }, { "glColor4ubv", glColor4ubv }, { 0 }, }; void *glGetProcAddress(_THIS, const char *proc) { for (int i = 0; embox_sdl_tbl[i].proc != 0; i++) { if (!strcmp(embox_sdl_tbl[i].proc, proc)) { return embox_sdl_tbl[i].fn; } } printf("embox/sdl: Failed to find %s\n", proc); return 0; }
æ°åã®åèµ·åã§ããªã¹ãã¯ã¹ãã©ãã·ã¥ç»é¢ãšã¡ãã¥ãŒãæç»ããã®ã«ååãªãã®ã«ãªããŸãã 幞ããªããšã«ãMesaã«ã¯å¿
èŠãªæ©èœããã¹ãŠåãã£ãŠããŸãã å¯äžã®ããš-äœããã®çç±ã§glGetString()
颿°ããªãããã glGetString()
ã䜿çšããå¿
èŠããã_mesa_GetString()
ã
ã¢ããªã±ãŒã·ã§ã³ãèµ·åãããšãã¹ãã©ãã·ã¥ç»é¢ã衚瀺ãããŸãã

å
¥åããã€ã¹ã远å ãã
SDLã«ããŒããŒããšããŠã¹ã®ãµããŒãã远å ããŸãã
ã€ãã³ããæäœããã«ã¯ããã³ãã©ãŒã远å ããå¿
èŠããããŸã
static SDL_VideoDevice *createDevice(int devindex) { ... device->PumpEvents = pumpEvents; ... }
ããŒããŒãããå§ããŸãããã ããŒãæŒãããé¢ãããããã®ãäžæããæ©èœãåããŸãã ãã®é¢æ°ã¯ã€ãã³ããèšæ¶ããå¿
èŠããããŸãïŒæãåçŽãªã±ãŒã¹ã§ã¯ãããŒã«ã«å€æ°ã«æžã蟌ãã ãã§ãå¿
èŠã«å¿ããŠãã¥ãŒã䜿çšã§ããŸãïŒãç°¡åã«ããããã«ãæåŸã®ã€ãã³ãã®ã¿ãä¿åããŸãã
static struct input_event last_event; static int sdl_indev_eventhnd(struct input_dev *indev) { while (0 == input_dev_event(indev, &last_event)) { } }
次ã«ã pumpEvents()
ã€ãã³ãpumpEvents()
åŠçããSDLã«æž¡ããŸãã
static void pumpEvents(_THIS) { SDL_Scancode scancode; bool pressed; scancode = scancode_from_event(&last_event); pressed = is_press(last_event); if (pressed) { SDL_SendKeyboardKey(SDL_PRESSED, scancode); } else { SDL_SendKeyboardKey(SDL_RELEASED, scancode); } }
ããŒã³ãŒããšSDL_Scancodeã®è©³çްSDLã¯ããŒã³ãŒãã«ç¬èªã®åæåã䜿çšãããããOSããŒã³ãŒããSDLã³ãŒãã«å€æããå¿
èŠããããŸãã
ãããã®ã³ãŒãã®ãªã¹ãã¯ã SDL_scancode.h
ãã¡ã€ã«ã§å®çŸ©ãããŠSDL_scancode.h
ãŸã
ããšãã°ã次ã®ããã«ASCIIã³ãŒãã倿ã§ããŸãïŒãã¹ãŠã®ASCIIæåãããã«ããããã§ã¯ãããŸãããããããã§ååã§ãïŒã
static int key_to_sdl[] = { [' '] = SDL_SCANCODE_SPACE, ['\r'] = SDL_SCANCODE_RETURN, [27] = SDL_SCANCODE_ESCAPE, ['0'] = SDL_SCANCODE_0, ['1'] = SDL_SCANCODE_1, ... ['8'] = SDL_SCANCODE_8, ['9'] = SDL_SCANCODE_9, ['a'] = SDL_SCANCODE_A, ['b'] = SDL_SCANCODE_B, ['c'] = SDL_SCANCODE_C, ... ['x'] = SDL_SCANCODE_X, ['y'] = SDL_SCANCODE_Y, ['z'] = SDL_SCANCODE_Z, };
ããã¯ãã¹ãŠããŒããŒãã§ãæ®ãã¯SDLãšQuakeèªäœã«ãã£ãŠåŠçãããŸãã ãšããã§ãããŒã¹ãããŒã¯ã®åŠçã®ã©ããã§ãquakeã¯QEMUã§ãµããŒããããŠããªãåœä»€ã䜿çšãããããx86ä»®æ³ãã·ã³ããè§£éãããä»®æ³ãã·ã³ã«åãæ¿ããå¿
èŠãããããšãBASE_CFLAGS += -DNO_VM_COMPILED
ããŸããã BASE_CFLAGS += -DNO_VM_COMPILED
ãããMakefileã«BASE_CFLAGS += -DNO_VM_COMPILED
ã远å ããŸãã
ãã®åŸãæåŸã«ãã¹ã¯ãªãŒã³ã»ãŒããŒãèå³ã«ãã¹ããããããã²ãŒã ãéå§ããããšãã§ããŸãïŒãšã©ãŒããããã³ã°ãã:)ïŒã éåžžã«äœãfpsã§ããã«ããããããããã¹ãŠãæ¬æ¥ã®ãšããã«ã¬ã³ããªã³ã°ãããããšã¯å¬ããé©ãã§ããã

ããã§ãããŠã¹ã®ãµããŒããéå§ã§ããŸãã ããŠã¹å²ã蟌ã¿ã®å Žåãå¥ã®ãã³ãã©ãŒãå¿
èŠã«ãªããã€ãã³ãåŠçã¯å°ãè€éã«ãªãå¿
èŠããããŸãã å·ŠããŠã¹ãã¿ã³ã®ã¿ã«å¶éããŸãã åæ§ã«ãæ£ããããŒããã€ãŒã«ãªã©ã远å ã§ããããšã¯æããã§ãã
static void pumpEvents(_THIS) { if (from_keyboard(&last_event)) { ... } else { if (is_left_click(&last_event)) { SDL_SendMouseButton(0, 0, SDL_PRESSED, SDL_BUTTON_LEFT); } else if (is_left_release(&last_event)) { SDL_SendMouseButton(0, 0, SDL_RELEASED, SDL_BUTTON_LEFT); } else { SDL_SendMouseMotion(0, 0, 1, mouse_diff_x(), mouse_diff_y()); } } }
ãã®åŸãã«ã¡ã©ãå¶åŸ¡ããŠæ®åœ±ããããšãå¯èœã«ãªããŸãïŒ å®éãããã§éã¶ã«ã¯ãã§ã«ååã§ã:)

æé©å
ãã¡ãããã³ã³ãããŒã«ãšäœããã®ã°ã©ãã£ãã¯ã¹ãããã®ã¯ã¯ãŒã«ã§ããããã®ãããªFPSã¯çµ¶å¯Ÿã«äŸ¡å€ããããŸããã ã»ãšãã©ã®å Žåãã»ãšãã©ã®æéã¯OpenGLã«è²»ãããïŒããã¯ãœãããŠã§ã¢ã§ãããããã«SIMDã¯äœ¿çšãããŸããïŒãããŒããŠã§ã¢ãµããŒãã®å®è£
ãé·ãããŠé£ããã¿ã¹ã¯ã§ãã
å°ãè¡ã§ã²ãŒã ãã¹ããŒãã¢ããããŠã¿ãŸãããã
ã³ã³ãã€ã©ãŒã®æé©åãšè§£å床ã®åæž
ã²ãŒã ããã¹ãŠã®ã©ã€ãã©ãªãããã³OSèªäœã-O3
ã¢ã»ã³ãã«ããŠã-O3
ïŒçªç¶ã誰ãããã®å Žæãèªãã§ãããã®ãã©ã°ãäœã§ãããããããªãå Žå-GCCæé©åãã©ã°ã®è©³çްã«ã€ããŠã¯ã ãã¡ããåç
§ããŠãã ãã ïŒã
ããã«ãæå°è§£å床-320x240ã䜿çšããŠãããã»ããµã®äœæ¥ã容æã«ããŸãã
Kvm
KVMïŒã«ãŒãã«ããŒã¹ã®ä»®æ³ãã·ã³ïŒã䜿çšãããšãããŒããŠã§ã¢ä»®æ³åïŒIntel VTããã³AMD-VïŒã䜿çšããŠããã©ãŒãã³ã¹ãæ¹åã§ããŸãã Qemuã¯ãã®ã¡ã«ããºã ããµããŒãããŠããŸããããã䜿çšããã«ã¯ã以äžãå®è¡ããå¿
èŠããããŸãã
ãŸããBIOSã§ä»®æ³åãµããŒããæå¹ã«ããå¿
èŠããããŸãã Gigabyte B450M DS3Hãã¶ãŒããŒãã䜿çšããŠãããAMD-Vã¯MIT-> Advanced Frequency Settings-> Advanced CPU Core Settings-> SVM Mode-> EnabledïŒGigabyteãäœãåé¡ãªã®ã§ããïŒïŒã§ãªã³ã«ããŸãã
次ã«ãå¿
èŠãªããã±ãŒãžãé
眮ããé©åãªã¢ãžã¥ãŒã«ã远å ããŸã
sudo apt install qemu-kvm sudo modprobe kvm-amd
ããã§ãqemuãã©ã°-enable-kvm
ïŒãŸãã¯ããŒããŠã§ã¢ã¢ã¯ã»ã©ã¬ãŒã·ã§ã³ã䜿çšããªãããã«-no-kvm
ïŒãæž¡ãããšãã§ããŸãã
ãŸãšã
ã²ãŒã ãéå§ãããã°ã©ãã£ãã¯ãå¿
èŠã«å¿ããŠè¡šç€ºãããã³ã³ãããŒã«ãæ©èœããŠããŸãã æ®å¿µãªãããã°ã©ãã£ãã¯ã¹ã¯1ã€ã®ã¹ã¬ããã§CPUäžã«æç»ãããSIMDããããŸãããããã¯ãfpsãäœãããïŒ1ç§ããã2ã3ãã¬ãŒã ïŒãå¶åŸ¡ãéåžžã«äžäŸ¿ã§ãã
ç§»æ€ããã»ã¹ã¯è峿·±ããã®ã§ããã å°æ¥çã«ã¯ãããŒããŠã§ã¢ã°ã©ãã£ãã¯ã¹ã¢ã¯ã»ã©ã¬ãŒã·ã§ã³ãåãããã©ãããã©ãŒã äžã§å°éãéå§ããããšãå¯èœã«ãªããããããŸããããä»ã®ãšããã¯äœã§ãããã«ã€ããŠèª¬æããŸãã