From 7fe91626d6592ed4e606e85c396ba76c512f34c4 Mon Sep 17 00:00:00 2001 From: pcem_emulator Date: Mon, 29 May 2017 15:38:48 +0100 Subject: [PATCH] Added new GUI based on wxWidgets. Patch from bit. --- src/Makefile.am | 4 +- src/Makefile.in | 98 +- src/Makefile.linux32 | 2 +- src/Makefile.linux32-wx-sdl2 | 51 + src/Makefile.linux64 | 2 +- src/Makefile.linux64-wx-sdl2 | 51 + src/Makefile.mingw-wx-sdl2 | 46 + src/Makefile.osx64-wx-sdl2 | 51 + src/cdrom-image.cc | 9 +- src/cdrom-ioctl-osx.c | 170 ++ src/fdc.c | 12 +- src/hdd_esdi.c | 4 +- src/ibm.h | 6 + src/icons/cd.png | Bin 0 -> 673 bytes src/icons/disk.png | Bin 0 -> 620 bytes src/icons/drive.png | Bin 0 -> 346 bytes src/icons/pause.svg | 43 + src/icons/pause24.png | Bin 0 -> 635 bytes src/icons/play-button.svg | 41 + src/icons/play24.png | Bin 0 -> 758 bytes src/icons/refresh.svg | 50 + src/icons/refresh24.png | Bin 0 -> 1144 bytes src/icons/stop.svg | 39 + src/icons/stop24.png | Bin 0 -> 622 bytes src/ide.c | 27 +- src/mfm_at.c | 8 +- src/mfm_xebec.c | 8 +- src/pc.c | 30 + src/pc.xrc | 1617 ++++++++++++++++++ src/vid_voodoo.c | 4 +- src/video.h | 2 +- src/wx-app.cc | 224 +++ src/wx-app.h | 134 ++ src/wx-common.c | 34 + src/wx-common.h | 26 + src/wx-config.c | 863 ++++++++++ src/wx-config_sel.c | 249 +++ src/wx-deviceconfig.cc | 268 +++ src/wx-deviceconfig.h | 10 + src/wx-dialogbox.cc | 45 + src/wx-dialogbox.h | 21 + src/wx-display.h | 36 + src/wx-main.cc | 15 + src/wx-resources.cpp | 3010 ++++++++++++++++++++++++++++++++++ src/wx-sdl2-display.c | 755 +++++++++ src/wx-sdl2-hdconf.c | 956 +++++++++++ src/wx-sdl2-joystick.c | 15 + src/wx-sdl2-keyboard.c | 23 + src/wx-sdl2-midi.c | 14 + src/wx-sdl2-mouse.c | 59 + src/wx-sdl2-status.c | 162 ++ src/wx-sdl2-video.c | 344 ++++ src/wx-sdl2-video.h | 38 + src/wx-sdl2.c | 889 ++++++++++ src/wx-sdl2.h | 16 + src/wx-status.cc | 351 ++++ src/wx-status.h | 70 + src/wx-thread.c | 169 ++ src/wx-utils.cc | 442 +++++ src/wx-utils.h | 112 ++ 60 files changed, 11647 insertions(+), 78 deletions(-) create mode 100644 src/Makefile.linux32-wx-sdl2 create mode 100644 src/Makefile.linux64-wx-sdl2 create mode 100644 src/Makefile.mingw-wx-sdl2 create mode 100644 src/Makefile.osx64-wx-sdl2 create mode 100644 src/cdrom-ioctl-osx.c create mode 100644 src/icons/cd.png create mode 100644 src/icons/disk.png create mode 100644 src/icons/drive.png create mode 100644 src/icons/pause.svg create mode 100644 src/icons/pause24.png create mode 100644 src/icons/play-button.svg create mode 100644 src/icons/play24.png create mode 100644 src/icons/refresh.svg create mode 100644 src/icons/refresh24.png create mode 100644 src/icons/stop.svg create mode 100644 src/icons/stop24.png create mode 100644 src/pc.xrc create mode 100644 src/wx-app.cc create mode 100644 src/wx-app.h create mode 100644 src/wx-common.c create mode 100644 src/wx-common.h create mode 100644 src/wx-config.c create mode 100644 src/wx-config_sel.c create mode 100644 src/wx-deviceconfig.cc create mode 100644 src/wx-deviceconfig.h create mode 100644 src/wx-dialogbox.cc create mode 100644 src/wx-dialogbox.h create mode 100644 src/wx-display.h create mode 100644 src/wx-main.cc create mode 100644 src/wx-resources.cpp create mode 100644 src/wx-sdl2-display.c create mode 100644 src/wx-sdl2-hdconf.c create mode 100644 src/wx-sdl2-joystick.c create mode 100644 src/wx-sdl2-keyboard.c create mode 100644 src/wx-sdl2-midi.c create mode 100644 src/wx-sdl2-mouse.c create mode 100644 src/wx-sdl2-status.c create mode 100644 src/wx-sdl2-video.c create mode 100644 src/wx-sdl2-video.h create mode 100644 src/wx-sdl2.c create mode 100644 src/wx-sdl2.h create mode 100644 src/wx-status.cc create mode 100644 src/wx-status.h create mode 100644 src/wx-thread.c create mode 100644 src/wx-utils.cc create mode 100644 src/wx-utils.h diff --git a/src/Makefile.am b/src/Makefile.am index babad39..7c2a47e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -10,13 +10,13 @@ CLEANFILES = $(noinst_SCRIPTS) amrefresh: -pcem_CFLAGS = $(allegro_CFLAGS) +pcem_CFLAGS = $(allegro_CFLAGS) -DPCEM_ALLEGRO pcem_LDADD = $(allegro_LIBS) -lopenal pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c acer386sx.c ali1429.c allegro-gui.c \ allegro-gui-config-sel.c allegro-gui-configure.c allegro-gui-deviceconfig.c allegro-gui-hdconf.c allegro-joystick.c allegro-keyboard.c allegro-main.c \ -allegro-midi.c allegro-mouse.c allegro-video.c amstrad.c cdrom-ioctl-linux.c cdrom-image.c cdrom-null.c \ +allegro-midi.c allegro-mouse.c allegro-video.c amstrad.c cdrom-ioctl-linux.c cdrom-image.cc cdrom-null.c \ codegen.c codegen_ops.c codegen_timing_486.c codegen_timing_686.c codegen_timing_pentium.c codegen_timing_winchip.c compaq.c config.c cpu.c \ dac.c dells200.c device.c disc.c disc_fdi.c disc_img.c disc_sector.c dma.c fdc.c fdc37c665.c fdd.c fdi2raw.c gameport.c \ hdd.c hdd_esdi.c headland.c i430lx.c i430fx.c i430vx.c ide.c intel.c intel_flash.c io.c jim.c joystick_ch_flightstick_pro.c joystick_standard.c joystick_sw_pad.c \ diff --git a/src/Makefile.in b/src/Makefile.in index 8066b6a..cf50055 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -112,13 +112,13 @@ am__pcem_SOURCES_DIST = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c \ allegro-gui-configure.c allegro-gui-deviceconfig.c \ allegro-gui-hdconf.c allegro-joystick.c allegro-keyboard.c \ allegro-main.c allegro-midi.c allegro-mouse.c allegro-video.c \ - amstrad.c cdrom-ioctl-linux.c cdrom-iso.c cdrom-null.c \ + amstrad.c cdrom-ioctl-linux.c cdrom-image.cc cdrom-null.c \ codegen.c codegen_ops.c codegen_timing_486.c \ codegen_timing_686.c codegen_timing_pentium.c \ codegen_timing_winchip.c compaq.c config.c cpu.c dac.c \ - device.c disc.c disc_fdi.c disc_img.c disc_sector.c dma.c \ - fdc.c fdc37c665.c fdd.c fdi2raw.c gameport.c hdd.c hdd_esdi.c \ - headland.c i430lx.c i430fx.c i430vx.c ide.c intel.c \ + dells200.c device.c disc.c disc_fdi.c disc_img.c disc_sector.c \ + dma.c fdc.c fdc37c665.c fdd.c fdi2raw.c gameport.c hdd.c \ + hdd_esdi.c headland.c i430lx.c i430fx.c i430vx.c ide.c intel.c \ intel_flash.c io.c jim.c joystick_ch_flightstick_pro.c \ joystick_standard.c joystick_sw_pad.c joystick_tm_fcs.c \ keyboard.c keyboard_amstrad.c keyboard_at.c keyboard_olim24.c \ @@ -143,8 +143,8 @@ am__pcem_SOURCES_DIST = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c \ vid_svga_render.c vid_tandy.c vid_tandysl.c vid_tgui9440.c \ vid_tkd8001_ramdac.c vid_tvga.c vid_unk_ramdac.c vid_vga.c \ vid_voodoo.c video.c wd76c10.c vid_wy700.c x86seg.c x87.c \ - xtide.c sound_dbopl.cc sound_resid.cc dosbox/dbopl.cpp \ - dosbox/vid_cga_comp.c resid-fp/convolve.cc \ + xtide.c sound_dbopl.cc sound_resid.cc dosbox/cdrom_image.cpp \ + dosbox/dbopl.cpp dosbox/vid_cga_comp.c resid-fp/convolve.cc \ resid-fp/convolve-sse.cc resid-fp/envelope.cc \ resid-fp/extfilt.cc resid-fp/filter.cc resid-fp/pot.cc \ resid-fp/sid.cc resid-fp/voice.cc resid-fp/wave6581_PS_.cc \ @@ -167,24 +167,24 @@ am_pcem_OBJECTS = pcem-386.$(OBJEXT) pcem-386_dynarec.$(OBJEXT) \ pcem-allegro-keyboard.$(OBJEXT) pcem-allegro-main.$(OBJEXT) \ pcem-allegro-midi.$(OBJEXT) pcem-allegro-mouse.$(OBJEXT) \ pcem-allegro-video.$(OBJEXT) pcem-amstrad.$(OBJEXT) \ - pcem-cdrom-ioctl-linux.$(OBJEXT) pcem-cdrom-iso.$(OBJEXT) \ + pcem-cdrom-ioctl-linux.$(OBJEXT) cdrom-image.$(OBJEXT) \ pcem-cdrom-null.$(OBJEXT) pcem-codegen.$(OBJEXT) \ pcem-codegen_ops.$(OBJEXT) pcem-codegen_timing_486.$(OBJEXT) \ pcem-codegen_timing_686.$(OBJEXT) \ pcem-codegen_timing_pentium.$(OBJEXT) \ pcem-codegen_timing_winchip.$(OBJEXT) pcem-compaq.$(OBJEXT) \ pcem-config.$(OBJEXT) pcem-cpu.$(OBJEXT) pcem-dac.$(OBJEXT) \ - pcem-device.$(OBJEXT) pcem-disc.$(OBJEXT) \ - pcem-disc_fdi.$(OBJEXT) pcem-disc_img.$(OBJEXT) \ - pcem-disc_sector.$(OBJEXT) pcem-dma.$(OBJEXT) \ - pcem-fdc.$(OBJEXT) pcem-fdc37c665.$(OBJEXT) pcem-fdd.$(OBJEXT) \ - pcem-fdi2raw.$(OBJEXT) pcem-gameport.$(OBJEXT) \ - pcem-hdd.$(OBJEXT) pcem-hdd_esdi.$(OBJEXT) \ - pcem-headland.$(OBJEXT) pcem-i430lx.$(OBJEXT) \ - pcem-i430fx.$(OBJEXT) pcem-i430vx.$(OBJEXT) pcem-ide.$(OBJEXT) \ - pcem-intel.$(OBJEXT) pcem-intel_flash.$(OBJEXT) \ - pcem-io.$(OBJEXT) pcem-jim.$(OBJEXT) \ - pcem-joystick_ch_flightstick_pro.$(OBJEXT) \ + pcem-dells200.$(OBJEXT) pcem-device.$(OBJEXT) \ + pcem-disc.$(OBJEXT) pcem-disc_fdi.$(OBJEXT) \ + pcem-disc_img.$(OBJEXT) pcem-disc_sector.$(OBJEXT) \ + pcem-dma.$(OBJEXT) pcem-fdc.$(OBJEXT) pcem-fdc37c665.$(OBJEXT) \ + pcem-fdd.$(OBJEXT) pcem-fdi2raw.$(OBJEXT) \ + pcem-gameport.$(OBJEXT) pcem-hdd.$(OBJEXT) \ + pcem-hdd_esdi.$(OBJEXT) pcem-headland.$(OBJEXT) \ + pcem-i430lx.$(OBJEXT) pcem-i430fx.$(OBJEXT) \ + pcem-i430vx.$(OBJEXT) pcem-ide.$(OBJEXT) pcem-intel.$(OBJEXT) \ + pcem-intel_flash.$(OBJEXT) pcem-io.$(OBJEXT) \ + pcem-jim.$(OBJEXT) pcem-joystick_ch_flightstick_pro.$(OBJEXT) \ pcem-joystick_standard.$(OBJEXT) \ pcem-joystick_sw_pad.$(OBJEXT) pcem-joystick_tm_fcs.$(OBJEXT) \ pcem-keyboard.$(OBJEXT) pcem-keyboard_amstrad.$(OBJEXT) \ @@ -238,7 +238,7 @@ am_pcem_OBJECTS = pcem-386.$(OBJEXT) pcem-386_dynarec.$(OBJEXT) \ pcem-video.$(OBJEXT) pcem-wd76c10.$(OBJEXT) \ pcem-vid_wy700.$(OBJEXT) pcem-x86seg.$(OBJEXT) \ pcem-x87.$(OBJEXT) pcem-xtide.$(OBJEXT) sound_dbopl.$(OBJEXT) \ - sound_resid.$(OBJEXT) dbopl.$(OBJEXT) \ + sound_resid.$(OBJEXT) cdrom_image.$(OBJEXT) dbopl.$(OBJEXT) \ pcem-vid_cga_comp.$(OBJEXT) convolve.$(OBJEXT) \ convolve-sse.$(OBJEXT) envelope.$(OBJEXT) extfilt.$(OBJEXT) \ filter.$(OBJEXT) pot.$(OBJEXT) sid.$(OBJEXT) voice.$(OBJEXT) \ @@ -426,20 +426,20 @@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_SCRIPTS = ../pcem CLEANFILES = $(noinst_SCRIPTS) -pcem_CFLAGS = $(allegro_CFLAGS) $(am__append_2) +pcem_CFLAGS = $(allegro_CFLAGS) -DPCEM_ALLEGRO $(am__append_2) pcem_LDADD = $(allegro_LIBS) -lopenal pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c \ acer386sx.c ali1429.c allegro-gui.c allegro-gui-config-sel.c \ allegro-gui-configure.c allegro-gui-deviceconfig.c \ allegro-gui-hdconf.c allegro-joystick.c allegro-keyboard.c \ allegro-main.c allegro-midi.c allegro-mouse.c allegro-video.c \ - amstrad.c cdrom-ioctl-linux.c cdrom-iso.c cdrom-null.c \ + amstrad.c cdrom-ioctl-linux.c cdrom-image.cc cdrom-null.c \ codegen.c codegen_ops.c codegen_timing_486.c \ codegen_timing_686.c codegen_timing_pentium.c \ codegen_timing_winchip.c compaq.c config.c cpu.c dac.c \ - device.c disc.c disc_fdi.c disc_img.c disc_sector.c dma.c \ - fdc.c fdc37c665.c fdd.c fdi2raw.c gameport.c hdd.c hdd_esdi.c \ - headland.c i430lx.c i430fx.c i430vx.c ide.c intel.c \ + dells200.c device.c disc.c disc_fdi.c disc_img.c disc_sector.c \ + dma.c fdc.c fdc37c665.c fdd.c fdi2raw.c gameport.c hdd.c \ + hdd_esdi.c headland.c i430lx.c i430fx.c i430vx.c ide.c intel.c \ intel_flash.c io.c jim.c joystick_ch_flightstick_pro.c \ joystick_standard.c joystick_sw_pad.c joystick_tm_fcs.c \ keyboard.c keyboard_amstrad.c keyboard_at.c keyboard_olim24.c \ @@ -464,8 +464,8 @@ pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c \ vid_svga_render.c vid_tandy.c vid_tandysl.c vid_tgui9440.c \ vid_tkd8001_ramdac.c vid_tvga.c vid_unk_ramdac.c vid_vga.c \ vid_voodoo.c video.c wd76c10.c vid_wy700.c x86seg.c x87.c \ - xtide.c sound_dbopl.cc sound_resid.cc dosbox/dbopl.cpp \ - dosbox/vid_cga_comp.c resid-fp/convolve.cc \ + xtide.c sound_dbopl.cc sound_resid.cc dosbox/cdrom_image.cpp \ + dosbox/dbopl.cpp dosbox/vid_cga_comp.c resid-fp/convolve.cc \ resid-fp/convolve-sse.cc resid-fp/envelope.cc \ resid-fp/extfilt.cc resid-fp/filter.cc resid-fp/pot.cc \ resid-fp/sid.cc resid-fp/voice.cc resid-fp/wave6581_PS_.cc \ @@ -560,6 +560,8 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cdrom-image.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cdrom_image.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/convolve-sse.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/convolve.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dbopl.Po@am__quote@ @@ -585,7 +587,6 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-allegro-video.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-amstrad.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cdrom-ioctl-linux.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cdrom-iso.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cdrom-null.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_ops.Po@am__quote@ @@ -599,6 +600,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-config.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cpu.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-dac.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-dells200.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-device.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-disc.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-disc_fdi.Po@am__quote@ @@ -1028,20 +1030,6 @@ pcem-cdrom-ioctl-linux.obj: cdrom-ioctl-linux.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-cdrom-ioctl-linux.obj `if test -f 'cdrom-ioctl-linux.c'; then $(CYGPATH_W) 'cdrom-ioctl-linux.c'; else $(CYGPATH_W) '$(srcdir)/cdrom-ioctl-linux.c'; fi` -pcem-cdrom-iso.o: cdrom-iso.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-cdrom-iso.o -MD -MP -MF $(DEPDIR)/pcem-cdrom-iso.Tpo -c -o pcem-cdrom-iso.o `test -f 'cdrom-iso.c' || echo '$(srcdir)/'`cdrom-iso.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-cdrom-iso.Tpo $(DEPDIR)/pcem-cdrom-iso.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cdrom-iso.c' object='pcem-cdrom-iso.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-cdrom-iso.o `test -f 'cdrom-iso.c' || echo '$(srcdir)/'`cdrom-iso.c - -pcem-cdrom-iso.obj: cdrom-iso.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-cdrom-iso.obj -MD -MP -MF $(DEPDIR)/pcem-cdrom-iso.Tpo -c -o pcem-cdrom-iso.obj `if test -f 'cdrom-iso.c'; then $(CYGPATH_W) 'cdrom-iso.c'; else $(CYGPATH_W) '$(srcdir)/cdrom-iso.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-cdrom-iso.Tpo $(DEPDIR)/pcem-cdrom-iso.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cdrom-iso.c' object='pcem-cdrom-iso.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-cdrom-iso.obj `if test -f 'cdrom-iso.c'; then $(CYGPATH_W) 'cdrom-iso.c'; else $(CYGPATH_W) '$(srcdir)/cdrom-iso.c'; fi` - pcem-cdrom-null.o: cdrom-null.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-cdrom-null.o -MD -MP -MF $(DEPDIR)/pcem-cdrom-null.Tpo -c -o pcem-cdrom-null.o `test -f 'cdrom-null.c' || echo '$(srcdir)/'`cdrom-null.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-cdrom-null.Tpo $(DEPDIR)/pcem-cdrom-null.Po @@ -1196,6 +1184,20 @@ pcem-dac.obj: dac.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-dac.obj `if test -f 'dac.c'; then $(CYGPATH_W) 'dac.c'; else $(CYGPATH_W) '$(srcdir)/dac.c'; fi` +pcem-dells200.o: dells200.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-dells200.o -MD -MP -MF $(DEPDIR)/pcem-dells200.Tpo -c -o pcem-dells200.o `test -f 'dells200.c' || echo '$(srcdir)/'`dells200.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-dells200.Tpo $(DEPDIR)/pcem-dells200.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dells200.c' object='pcem-dells200.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-dells200.o `test -f 'dells200.c' || echo '$(srcdir)/'`dells200.c + +pcem-dells200.obj: dells200.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-dells200.obj -MD -MP -MF $(DEPDIR)/pcem-dells200.Tpo -c -o pcem-dells200.obj `if test -f 'dells200.c'; then $(CYGPATH_W) 'dells200.c'; else $(CYGPATH_W) '$(srcdir)/dells200.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-dells200.Tpo $(DEPDIR)/pcem-dells200.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dells200.c' object='pcem-dells200.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-dells200.obj `if test -f 'dells200.c'; then $(CYGPATH_W) 'dells200.c'; else $(CYGPATH_W) '$(srcdir)/dells200.c'; fi` + pcem-device.o: device.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-device.o -MD -MP -MF $(DEPDIR)/pcem-device.Tpo -c -o pcem-device.o `test -f 'device.c' || echo '$(srcdir)/'`device.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-device.Tpo $(DEPDIR)/pcem-device.Po @@ -3114,6 +3116,20 @@ pcem-codegen_x86-64.obj: codegen_x86-64.c @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` +cdrom_image.o: dosbox/cdrom_image.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT cdrom_image.o -MD -MP -MF $(DEPDIR)/cdrom_image.Tpo -c -o cdrom_image.o `test -f 'dosbox/cdrom_image.cpp' || echo '$(srcdir)/'`dosbox/cdrom_image.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cdrom_image.Tpo $(DEPDIR)/cdrom_image.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='dosbox/cdrom_image.cpp' object='cdrom_image.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o cdrom_image.o `test -f 'dosbox/cdrom_image.cpp' || echo '$(srcdir)/'`dosbox/cdrom_image.cpp + +cdrom_image.obj: dosbox/cdrom_image.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT cdrom_image.obj -MD -MP -MF $(DEPDIR)/cdrom_image.Tpo -c -o cdrom_image.obj `if test -f 'dosbox/cdrom_image.cpp'; then $(CYGPATH_W) 'dosbox/cdrom_image.cpp'; else $(CYGPATH_W) '$(srcdir)/dosbox/cdrom_image.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cdrom_image.Tpo $(DEPDIR)/cdrom_image.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='dosbox/cdrom_image.cpp' object='cdrom_image.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o cdrom_image.obj `if test -f 'dosbox/cdrom_image.cpp'; then $(CYGPATH_W) 'dosbox/cdrom_image.cpp'; else $(CYGPATH_W) '$(srcdir)/dosbox/cdrom_image.cpp'; fi` + dbopl.o: dosbox/dbopl.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT dbopl.o -MD -MP -MF $(DEPDIR)/dbopl.Tpo -c -o dbopl.o `test -f 'dosbox/dbopl.cpp' || echo '$(srcdir)/'`dosbox/dbopl.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dbopl.Tpo $(DEPDIR)/dbopl.Po diff --git a/src/Makefile.linux32 b/src/Makefile.linux32 index 69c1330..2b47115 100644 --- a/src/Makefile.linux32 +++ b/src/Makefile.linux32 @@ -1,7 +1,7 @@ VPATH = . dosbox resid-fp CPP = g++ CC = gcc -CFLAGS = -O3 -fomit-frame-pointer -msse2 -m32 +CFLAGS = -DPCEM_ALLEGRO -O3 -fomit-frame-pointer -msse2 -m32 LDFLAGS = -m32 OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o allegro-gui.o \ allegro-gui-configure.o allegro-gui-config-sel.o allegro-gui-deviceconfig.o allegro-gui-hdconf.o allegro-joystick.o allegro-keyboard.o allegro-main.o \ diff --git a/src/Makefile.linux32-wx-sdl2 b/src/Makefile.linux32-wx-sdl2 new file mode 100644 index 0000000..d95f9f9 --- /dev/null +++ b/src/Makefile.linux32-wx-sdl2 @@ -0,0 +1,51 @@ +VPATH = . dosbox resid-fp +CPP = g++ +CC = gcc +WXRC = wxrc +CFLAGS = -O3 -fomit-frame-pointer -msse2 -m32 $(shell wx-config --cxxflags) $(shell sdl2-config --cflags) +OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl-linux.o cdrom-image.o cdrom-null.o \ +codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.c compaq.o config.o cpu.o \ +dac.o dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ +hdd.o hdd_esdi.o headland.o i430lx.o i430fx.o i430vx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o \ +joystick_tm_fcs.o keyboard.o keyboard_amstrad.o keyboard_at.o keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o \ +lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ +opti495.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o serial.o sis496.o sound.o \ +sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_emu8k.o sound_gus.o \ +sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_sb.o sound_sb_dsp.o sound_sn76489.o \ +sound_speaker.o sound_ssi2001.o sound_wss.o sound_ym7128.o soundopenal.o tandy_eeprom.o tandy_rom.o \ +timer.o um8669f.o um8881f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o vid_ati28800.o \ +vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_ega.o vid_et4000.o vid_et4000w32.o vid_genius.o vid_hercules.o \ +vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o vid_olivetti_m24.o vid_oti067.o vid_paradise.o vid_pc200.o \ +vid_pc1512.o vid_pc1640.o vid_pcjr.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o \ +vid_stg_ramdac.o vid_svga.o vid_svga_render.o vid_tandy.o vid_tandysl.o vid_tgui9440.o \ +vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o vid_vga.o vid_voodoo.o vid_wy700.o video.o wd76c10.o \ +x86seg.o x87.o xtide.o sound_dbopl.o sound_resid.o \ +wx-main.o wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o wx-sdl2-keyboard.o wx-sdl2-video.o wx-sdl2-midi.o \ +wx-sdl2.o wx-config.o wx-deviceconfig.o wx-sdl2-hdconf.o wx-status.o wx-sdl2-status.o wx-resources.o wx-thread.o wx-common.o wx-sdl2-display.o +DBOBJ = cdrom_image.o dbopl.o vid_cga_comp.o +SIDOBJ = convolve.o convolve-sse.o envelope.o extfilt.o filter.o pot.o sid.o voice.o wave6581__ST.o wave6581_P_T.o wave6581_PS_.o wave6581_PST.o wave8580__ST.o wave8580_P_T.o wave8580_PS_.o wave8580_PST.o wave.o + + +LIBS = -lopenal -lstdc++ -lpthread -lm $(shell wx-config --libs) $(shell sdl2-config --libs) + +PCem-wx-SDL2: $(OBJ) $(DBOBJ) $(SIDOBJ) + $(CC) $(OBJ) $(DBOBJ) $(SIDOBJ) -o "PCem-wx-SDL2" $(LIBS) + +all : PCem-wx-SDL2 + +clean : + rm *.o + rm PCem-wx-SDL2 + +wx-resources.o : pc.xrc + $(WXRC) -c pc.xrc -o wx-resources.cpp + $(CPP) $(CFLAGS) -c wx-resources.cpp + +%.o : %.c + $(CC) $(CFLAGS) -c $< + +%.o : %.cc + $(CPP) $(CFLAGS) -c $< + +%.o : %.cpp + $(CPP) $(CFLAGS) -c $< diff --git a/src/Makefile.linux64 b/src/Makefile.linux64 index 70ea9d7..1dc72e1 100644 --- a/src/Makefile.linux64 +++ b/src/Makefile.linux64 @@ -1,7 +1,7 @@ VPATH = . dosbox resid-fp CPP = g++ CC = gcc -CFLAGS = -O3 -fomit-frame-pointer -msse2 -m64 +CFLAGS = -DPCEM_ALLEGRO -O3 -fomit-frame-pointer -msse2 -m64 OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o allegro-gui.o \ allegro-gui-configure.o allegro-gui-config-sel.o allegro-gui-deviceconfig.o allegro-gui-hdconf.o allegro-joystick.o allegro-keyboard.o allegro-main.o \ allegro-midi.o allegro-mouse.o allegro-video.o amstrad.o cdrom-ioctl-linux.o cdrom-image.o cdrom-null.o \ diff --git a/src/Makefile.linux64-wx-sdl2 b/src/Makefile.linux64-wx-sdl2 new file mode 100644 index 0000000..014c895 --- /dev/null +++ b/src/Makefile.linux64-wx-sdl2 @@ -0,0 +1,51 @@ +VPATH = . dosbox resid-fp +CPP = g++ +CC = gcc +WXRC = wxrc +CFLAGS = -Doff64_t=__off64_t -O3 -fomit-frame-pointer -msse2 -m64 $(shell wx-config --cxxflags) $(shell sdl2-config --cflags) +OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl-linux.o cdrom-image.o cdrom-null.o \ +codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.c compaq.o config.o cpu.o \ +dac.o dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ +hdd.o hdd_esdi.o headland.o i430lx.o i430fx.o i430vx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o \ +joystick_tm_fcs.o keyboard.o keyboard_amstrad.o keyboard_at.o keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o \ +lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ +opti495.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o serial.o sis496.o sound.o \ +sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_emu8k.o sound_gus.o \ +sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_sb.o sound_sb_dsp.o sound_sn76489.o \ +sound_speaker.o sound_ssi2001.o sound_wss.o sound_ym7128.o soundopenal.o tandy_eeprom.o tandy_rom.o \ +timer.o um8669f.o um8881f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o vid_ati28800.o \ +vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_ega.o vid_et4000.o vid_et4000w32.o vid_genius.o vid_hercules.o \ +vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o vid_olivetti_m24.o vid_oti067.o vid_paradise.o vid_pc200.o \ +vid_pc1512.o vid_pc1640.o vid_pcjr.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o \ +vid_stg_ramdac.o vid_svga.o vid_svga_render.o vid_tandy.o vid_tandysl.o vid_tgui9440.o \ +vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o vid_vga.o vid_voodoo.o vid_wy700.o video.o wd76c10.o \ +x86seg.o x87.o xtide.o sound_dbopl.o sound_resid.o \ +wx-main.o wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o wx-sdl2-keyboard.o wx-sdl2-video.o wx-sdl2-midi.o \ +wx-sdl2.o wx-config.o wx-deviceconfig.o wx-sdl2-hdconf.o wx-status.o wx-sdl2-status.o wx-resources.o wx-thread.o wx-common.o wx-sdl2-display.o +DBOBJ = cdrom_image.o dbopl.o vid_cga_comp.o +SIDOBJ = convolve.o convolve-sse.o envelope.o extfilt.o filter.o pot.o sid.o voice.o wave6581__ST.o wave6581_P_T.o wave6581_PS_.o wave6581_PST.o wave8580__ST.o wave8580_P_T.o wave8580_PS_.o wave8580_PST.o wave.o + + +LIBS = -lopenal -lstdc++ -lpthread -lm $(shell wx-config --libs) $(shell sdl2-config --libs) + +PCem64-wx-SDL2: $(OBJ) $(DBOBJ) $(SIDOBJ) + $(CC) $(OBJ) $(DBOBJ) $(SIDOBJ) -o "PCem64-wx-SDL2" $(LIBS) + +all : PCem64-wx-SDL2 + +clean : + rm *.o + rm PCem64-wx-SDL2 + +wx-resources.o : pc.xrc + $(WXRC) -c pc.xrc -o wx-resources.cpp + $(CPP) $(CFLAGS) -c wx-resources.cpp + +%.o : %.c + $(CC) $(CFLAGS) -c $< + +%.o : %.cc + $(CPP) $(CFLAGS) -c $< + +%.o : %.cpp + $(CPP) $(CFLAGS) -c $< diff --git a/src/Makefile.mingw-wx-sdl2 b/src/Makefile.mingw-wx-sdl2 new file mode 100644 index 0000000..bebef57 --- /dev/null +++ b/src/Makefile.mingw-wx-sdl2 @@ -0,0 +1,46 @@ +VPATH = . dosbox resid-fp +CPP = g++ +CC = gcc +WXRC = wxrc +CFLAGS = -DRELEASE_BUILD -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign +OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl.o cdrom-image.o \ + codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o dac.o \ + device.o dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o headland.o i430lx.o i430fx.o \ + i430vx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o joystick_tm_fcs.o keyboard.o keyboard_amstrad.o keyboard_at.o \ + keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o \ + mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti495.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o \ + scat.o serial.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_dbopl.o \ + sound_emu8k.o sound_gus.o sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_resid.o \ + sound_sb.o sound_sb_dsp.o sound_sn76489.o sound_speaker.o sound_ssi2001.o sound_wss.o \ + sound_ym7128.o soundopenal.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ + vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_ega.o vid_et4000.o \ + vid_et4000w32.o vid_et4000w32i.o vid_genius.o vid_hercules.o vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o \ + vid_olivetti_m24.o vid_oti067.o vid_paradise.o vid_pc1512.o vid_pc1640.o vid_pc200.o \ + vid_pcjr.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_stg_ramdac.o vid_svga.o \ + vid_svga_render.o vid_tandy.o vid_tandysl.o vid_tgui9440.o vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o \ + vid_vga.o vid_voodoo.o vid_wy700.o video.o wd76c10.o x86seg.o x87.o xtide.o \ + wx-main.o wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o wx-sdl2-keyboard.o wx-sdl2-video.o wx-sdl2-midi.o \ + wx-sdl2.o wx-config.o wx-deviceconfig.o wx-sdl2-hdconf.o wx-status.o wx-sdl2-status.o wx-resources.o wx-thread.o wx-common.o wx-sdl2-display.o +DBOBJ = cdrom_image.o dbopl.o vid_cga_comp.o +SIDOBJ = convolve.o convolve-sse.o envelope.o extfilt.o filter.o pot.o sid.o voice.o wave6581__ST.o wave6581_P_T.o wave6581_PS_.o wave6581_PST.o wave8580__ST.o wave8580_P_T.o wave8580_PS_.o wave8580_PST.o wave.o + + +LIBS = -mwindows -lopenal32 -lstdc++ -lwxbase31u -lwxmsw31u_core -lwxmsw31u_xrc -lmingw32 -lSDL2main -lSDL2 -mwindows -Wl,--no-undefined -lm -ldinput8 -ldxguid -ldxerr8 -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lversion -luuid -static + +PCem-wx-SDL2.exe: $(OBJ) $(DBOBJ) $(SIDOBJ) + $(CC) $(OBJ) $(DBOBJ) $(SIDOBJ) -o "PCem-wx-SDL2.exe" $(LIBS) + +all : PCem-wx-SDL2.exe + +clean : + del *.o + del PCem-wx-SDL2.exe + +%.o : %.c + $(CC) $(CFLAGS) -c $< + +%.o : %.cc + $(CPP) $(CFLAGS) -c $< + +%.o : %.cpp + $(CPP) $(CFLAGS) -c $< diff --git a/src/Makefile.osx64-wx-sdl2 b/src/Makefile.osx64-wx-sdl2 new file mode 100644 index 0000000..813ec2a --- /dev/null +++ b/src/Makefile.osx64-wx-sdl2 @@ -0,0 +1,51 @@ +VPATH = . dosbox resid-fp +CPP = g++ +CC = gcc +WXRC = wxrc +CFLAGS = -D__unix=1 -DPCEM_RENDER_WITH_TIMER -DPCEM_RENDER_TIMER_LOOP -Dfopen64=fopen -Dfseeko64=fseeko -Dftello64=ftello -Doff64_t=off_t -O3 -fomit-frame-pointer -msse2 -m64 $(shell wx-config --cxxflags) $(shell sdl2-config --cflags) -I/usr/local/opt/openal-soft/include -I/usr/local/include +OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl-osx.o cdrom-image.o cdrom-null.o \ +codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.c compaq.o config.o cpu.o \ +dac.o device.o dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ +hdd.o hdd_esdi.o headland.o i430lx.o i430fx.o i430vx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o \ +joystick_tm_fcs.o keyboard.o keyboard_amstrad.o keyboard_at.o keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o \ +lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ +opti495.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o serial.o sis496.o sound.o \ +sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_emu8k.o sound_gus.o \ +sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_sb.o sound_sb_dsp.o sound_sn76489.o \ +sound_speaker.o sound_ssi2001.o sound_wss.o sound_ym7128.o soundopenal.o tandy_eeprom.o tandy_rom.o \ +timer.o um8669f.o um8881f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o vid_ati28800.o \ +vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_ega.o vid_et4000.o vid_et4000w32.o vid_genius.o vid_hercules.o \ +vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o vid_olivetti_m24.o vid_oti067.o vid_paradise.o vid_pc200.o \ +vid_pc1512.o vid_pc1640.o vid_pcjr.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o \ +vid_stg_ramdac.o vid_svga.o vid_svga_render.o vid_tandy.o vid_tandysl.o vid_tgui9440.o \ +vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o vid_vga.o vid_voodoo.o vid_wy700.o video.o wd76c10.o \ +x86seg.o x87.o xtide.o sound_dbopl.o sound_resid.o \ +wx-main.o wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o wx-sdl2-keyboard.o wx-sdl2-video.o wx-sdl2-midi.o \ +wx-sdl2.o wx-config.o wx-deviceconfig.o wx-sdl2-hdconf.o wx-status.o wx-sdl2-status.o wx-resources.o wx-thread.o wx-common.o wx-sdl2-display.o +DBOBJ = cdrom_image.o dbopl.o vid_cga_comp.o +SIDOBJ = convolve.o convolve-sse.o envelope.o extfilt.o filter.o pot.o sid.o voice.o wave6581__ST.o wave6581_P_T.o wave6581_PS_.o wave6581_PST.o wave8580__ST.o wave8580_P_T.o wave8580_PS_.o wave8580_PST.o wave.o + + +LIBS = -lopenal -lstdc++ -lpthread -lm $(shell wx-config --libs) $(shell sdl2-config --libs) -L/usr/local/opt/openal-soft/lib + +PCem64-wx-SDL2: $(OBJ) $(DBOBJ) $(SIDOBJ) + $(CC) $(OBJ) $(DBOBJ) $(SIDOBJ) -o "PCem64-wx-SDL2" $(LIBS) + +all : PCem64-wx-SDL2 + +clean : + rm *.o + rm PCem64-wx-SDL2 + +wx-resources.o : pc.xrc + $(WXRC) -c pc.xrc -o wx-resources.cpp + $(CPP) $(CFLAGS) -c wx-resources.cpp + +%.o : %.c + $(CC) $(CFLAGS) -c $< + +%.o : %.cc + $(CPP) $(CFLAGS) -c $< + +%.o : %.cpp + $(CPP) $(CFLAGS) -c $< diff --git a/src/cdrom-image.cc b/src/cdrom-image.cc index 464adf3..3ce4d46 100644 --- a/src/cdrom-image.cc +++ b/src/cdrom-image.cc @@ -4,13 +4,20 @@ extern "C" { -#include "ibm.h" +//#include "ibm.h" #include "ide.h" int cdrom_drive; int old_cdrom_drive; +void pclog(const char *format, ...); } +#define CD_STATUS_EMPTY 0 +#define CD_STATUS_DATA_ONLY 1 +#define CD_STATUS_PLAYING 2 +#define CD_STATUS_PAUSED 3 +#define CD_STATUS_STOPPED 4 + char image_path[1024]; static int image_changed = 0; diff --git a/src/cdrom-ioctl-osx.c b/src/cdrom-ioctl-osx.c new file mode 100644 index 0000000..5243ebd --- /dev/null +++ b/src/cdrom-ioctl-osx.c @@ -0,0 +1,170 @@ +#include +#include +#include +#include "ibm.h" +#include "ide.h" +#include "cdrom-ioctl.h" + +static ATAPI ioctl_atapi; + +void ioctl_audio_callback(int16_t *output, int len) +{ + memset(output, 0, len * 2); +} + +void ioctl_audio_stop() +{ +} + +static int get_track_nr(uint32_t pos) +{ + return 0; +} + +static int is_track_audio(uint32_t pos) +{ + return 0; +} + +static int ioctl_is_track_audio(uint32_t pos, int ismsf) +{ + return 0; +} + +static void ioctl_playaudio(uint32_t pos, uint32_t len, int ismsf) +{ +} + +static void ioctl_pause(void) +{ +} + +static void ioctl_resume(void) +{ +} + +static void ioctl_stop(void) +{ +} + +static void ioctl_seek(uint32_t pos) +{ +} + +static int read_toc(int fd, struct cdrom_tocentry *btoc) +{ + return 0; +} + +static int ioctl_ready(void) +{ + return 0; +} + +static int ioctl_get_last_block(unsigned char starttrack, int msf, int maxlen, int single) +{ + return 0; +} + +static int ioctl_medium_changed(void) +{ + return 0; +} + +static uint8_t ioctl_getcurrentsubchannel(uint8_t *b, int msf) +{ + return 0x13; +} + +static void ioctl_eject(void) +{ +} + +static void ioctl_load(void) +{ +} + +static int ioctl_readsector(uint8_t *b, int sector) +{ + return 0; +} + +static int lba_to_msf(int lba) +{ + return 0; +} + +static void ioctl_readsector_raw(uint8_t *b, int sector) +{ +} + +static int ioctl_readtoc(unsigned char *b, unsigned char starttrack, int msf, int maxlen, int single) +{ + return 0; +} + +static int ioctl_readtoc_session(unsigned char *b, int msf, int maxlen) +{ + return 0; +} + +static int ioctl_readtoc_raw(unsigned char *b, int maxlen) +{ + return 0; +} + +static uint32_t ioctl_size() +{ + return 0; +} + +static int ioctl_status() +{ + return CD_STATUS_EMPTY; +} +void ioctl_reset() +{ +} + +void ioctl_set_drive(char d) +{ + atapi = &ioctl_atapi; +} + +int ioctl_open(char d) +{ + atapi = &ioctl_atapi; + return 0; +} + +void ioctl_close(void) +{ +} + +static void ioctl_exit(void) +{ + +} + +static ATAPI ioctl_atapi= +{ + ioctl_ready, + ioctl_medium_changed, + ioctl_readtoc, + ioctl_readtoc_session, + ioctl_readtoc_raw, + ioctl_getcurrentsubchannel, + ioctl_readsector, + ioctl_readsector_raw, + ioctl_playaudio, + ioctl_seek, + ioctl_load, + ioctl_eject, + ioctl_pause, + ioctl_resume, + ioctl_size, + ioctl_status, + ioctl_is_track_audio, + ioctl_stop, + ioctl_exit +}; diff --git a/src/fdc.c b/src/fdc.c index 3714324..948df5b 100644 --- a/src/fdc.c +++ b/src/fdc.c @@ -575,7 +575,7 @@ bad_command: // pclog("Read a track track=%i head=%i sector=%i eot=%i\n", fdc.track[fdc.drive], fdc.head, fdc.sector, fdc.eot[fdc.drive]); disc_readsector(fdc.drive, SECTOR_FIRST, fdc.track[fdc.drive], fdc.head, fdc.rate, fdc.params[4]); disctime = 0; - readflash = 1; + readflash_set(READFLASH_FDC, fdc.drive); fdc.inread = 1; break; @@ -601,7 +601,7 @@ bad_command: disc_writesector(fdc.drive, fdc.sector, fdc.track[fdc.drive], fdc.head, fdc.rate, fdc.params[4]); disctime = 0; fdc.written = 0; - readflash = 1; + readflash_set(READFLASH_FDC, fdc.drive); fdc.pos = 0; if (fdc.pcjr) fdc.stat = 0xb0; @@ -621,7 +621,7 @@ bad_command: disc_readsector(fdc.drive, fdc.sector, fdc.track[fdc.drive], fdc.head, fdc.rate, fdc.params[4]); disctime = 0; - readflash = 1; + readflash_set(READFLASH_FDC, fdc.drive); fdc.inread = 1; break; @@ -815,7 +815,7 @@ void fdc_callback() return; case 2: /*Read track*/ - readflash = 1; + readflash_set(READFLASH_FDC, fdc.drive); fdc.eot[fdc.drive]--; // pclog("Read a track callback, eot=%i\n", fdc.eot[fdc.drive]); if (!fdc.eot[fdc.drive] || fdc.tc) @@ -861,7 +861,7 @@ void fdc_callback() case 5: /*Write data*/ if (!fdc.in_seek_mt) { - readflash = 1; + readflash_set(READFLASH_FDC, fdc.drive); fdc.sector++; if (fdc.sector > fdc.params[5]) { @@ -911,7 +911,7 @@ void fdc_callback() // rpclog("Read data %i\n", fdc.tc); if (!fdc.in_seek_mt) { - readflash = 1; + readflash_set(READFLASH_FDC, fdc.drive); fdc.sector++; if (fdc.sector > fdc.params[5]) { diff --git a/src/hdd_esdi.c b/src/hdd_esdi.c index db708ec..56c49c3 100644 --- a/src/hdd_esdi.c +++ b/src/hdd_esdi.c @@ -445,7 +445,7 @@ static void esdi_callback(void *p) fatal("Read past end of drive\n"); fseek(drive->hdfile, esdi->rba * 512, SEEK_SET); fread(esdi->data, 512, 1, drive->hdfile); - readflash = 1; + readflash_set(READFLASH_HDC, esdi->cmd_dev == ATTN_DEVICE_0 ? 0 : 1); } // pclog("Read sector %i %i %08x\n", esdi->sector_pos, esdi->data_pos, esdi->rba*512); while (esdi->data_pos < 256) @@ -540,7 +540,7 @@ static void esdi_callback(void *p) fwrite(esdi->data, 512, 1, drive->hdfile); esdi->rba++; esdi->sector_pos++; - readflash = 1; + readflash_set(READFLASH_HDC, esdi->cmd_dev == ATTN_DEVICE_0 ? 0 : 1); esdi->data_pos = 0; } diff --git a/src/ibm.h b/src/ibm.h index 82bb8bd..e2c5b64 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -3,6 +3,12 @@ #include #define printf pclog +#define READFLASH_FDC 0 +#define READFLASH_HDC 4 +#define readflash_set(offset, drive) readflash |= 1<<(offset+drive) +#define readflash_clear(offset, drive) readflash &= ~(1<<(offset+drive)) +#define readflash_get(offset, drive) ((readflash&(1<<(offset+drive))) != 0) + /*Memory*/ uint8_t *ram; diff --git a/src/icons/cd.png b/src/icons/cd.png new file mode 100644 index 0000000000000000000000000000000000000000..ef4322357cbc34e0b5eeed34f9fdf553a1de2ee7 GIT binary patch literal 673 zcmV;S0$%-zP)fk+XBT$+GFLor|=G~7Z=&Bd_^zJLLP z{dbOmhNM(Q`mp7h`OloWYysF>=iU40Tf#?V356IC6~fPKul?5pw+W80zw#nVEgemD zincj})E^?AZGqXAKHDz@mch}3iwfqB3rPo#(gwa141DiTF(xO6U^eE%d{-hX0gf3o z8{W?(@4ZV6pRS)EXbxQZMi1!D!oC#YJOO&yAsn%9V=twmsxF*P_%ZxvD(XXc8T9DS zr0103x=g@fvEJ!1y5C7b$Hz+ryB7+I5>V>_sj5lWnV>%bWD?LRmBAb^h}fbg923Y3 zqK41OM-q_X|0W}n)p3}pGlwoCoNU0Ppf+VweFB8`9D=Abd!7lXx6+7Cma$90A4ue; zVKQTfc(bHa=}i!!qJ}b>M^UnvkNQWze=dVN?ZJ22Mf(14f#NRkt=PP(cyuKepkb#y3Gz>xmDvuMC zIuoRtGlX&@?9*%nGA0rvwq8W9jW)GLrXJl50KN-ci9ozQ$MNkH;k<IV|^+8goU4jB6C^%Mg5h>3Q7RCr>7r_DEKw7k44$|vUmJAm;${=2wBT`(Pek9N? z+*$Z3+nYyu(=ufrbdbTWW%|!LE6aD^rgi=em@XcV9q^{200000NkvXX Hu0mjf|3D;c literal 0 HcmV?d00001 diff --git a/src/icons/disk.png b/src/icons/disk.png new file mode 100644 index 0000000000000000000000000000000000000000..99d532e8b1750115952f97302a92d713c0486f97 GIT binary patch literal 620 zcmV-y0+aoTP)~H+MJzd|s z^YP1Hc07G_>)Lgir!F1{Qn4GcTg%?koHo<=1qRN{}nPDolOeI^o4N5I>! zU$N=L=sg~ zDx#dOA*B0N~cqPsWI(^rbbkh)DS0_H_UN0C4l_kvWIm2#Kyy6%BCh z(yIUf003&1xdx>t$*eR2ZvXxT0001Z_R$y3Iju92q*wg58};}zm(OaAH=p|y0002M zh5O5#fxp|~jc?yi@+7$`d4Q6Hl%z;WiWG??NXR{Hx%)pMd~SE0000OQI literal 0 HcmV?d00001 diff --git a/src/icons/drive.png b/src/icons/drive.png new file mode 100644 index 0000000000000000000000000000000000000000..37b7c9b27d39acaaecf06951b024ac08afbfd4d2 GIT binary patch literal 346 zcmV-g0j2(lP)`6pHR4C7- zkv&QTK@f$%UVGNSAB4p~7X&kJu`rW(3s2w)1kd9QoMeZ&fx$)tn+OJimk zjCT$JD?{UrQ?3~v=-g&C?-zWP;E3TkpyGrhTDFaQSzpwKU?tq9Uh&CO=Y?-R7%>t` z!bl_(!*h(_r3OLS;FuM!k+?!xBDEihL=?r53TBrP2>202N!*Y~*dL6MvS5Ku!P&n9 sT@vv>?encL=G!4ixo5^&>-PTUFAyGx1U4B=kpKVy07*qoM6N<$g0$g{=l}o! literal 0 HcmV?d00001 diff --git a/src/icons/pause.svg b/src/icons/pause.svg new file mode 100644 index 0000000..537fa7f --- /dev/null +++ b/src/icons/pause.svg @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/icons/pause24.png b/src/icons/pause24.png new file mode 100644 index 0000000000000000000000000000000000000000..7e2e38dd63b138abaa117818bab099b862405092 GIT binary patch literal 635 zcmV->0)+jEP)u)O4UuFX*)xxw2Q3#3~p<|L_;e<5u~_Pap9^6`Vm|!2zAqx zC{0q_`Vri9A%sFF(?;sTO7TzT&2`Zvn7_u*IWUWN-HvH@J= z|L`5S>#o*Ie+NycCCNuBQXGRE;1cjY*i1g`dxNI(Vt3Lp5CJz^HxU58=z3zq-EQUL zT)>>4ZvSUbd;pwDudO5c`31E#rYg0Wfv# zT|0L2`4!(jt@qgF80R_gzyyW46vDm!HJ0dHn{%gMM{HtHectzru4ho29ibG*fg_>K z7!_F}CWz>D1G*Sj0!0@LFhgt**AOov0}{lTATU5RHiMvQfSuUW9+nO!;jAj*?wKOdi5c-$iIJ2Gp9 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/icons/play24.png b/src/icons/play24.png new file mode 100644 index 0000000000000000000000000000000000000000..bf72ed1591202a6e9c8b41555a268dffc0f1528c GIT binary patch literal 758 zcmV#!;#7g22P~GCi%6pj*ZKNKNBptsQ9yl~MhhCjNjN@EOgfOtV)_&Vw@MXX?M=Z#B~#voUb6Z4e_ zKvrj6vaMz?#+^rQS6DK8kN77HfUV}b7yLr%9%}X-CNqBPs@jF6)d1paZ%9!q9Q1O_ z&AkUXv^^PDm6wyl+!^j;HXMp3i4zt#)nGa0QCJZp!pR*OJl|hRX<}Mre=nA0W0e_2 zi&sfN!oFdXTZeBK4RgW2vj95<5w{!u|5dPNP*{^Y~-cPhKzP&N22S~x&We?eeO{tcM$AP~PsKf7tM zoy_jMib(_TzUb7rsyPifYXEmq0^NBPlZysUZ_%08f?NgM|C$BLm7b!rEuJGYr=$M3 zpmi~{YZ`IS^%MkJJx3-$Z=t_gZ984jyFfUqmY}s_JDE%2p0A2|Wp&mi+gN4bmY|Zh o@Y$jeG|(0jx4FL{Fy_Vh3s&UrRLgmF$^ZZW07*qoM6N<$f)CJCK>z>% literal 0 HcmV?d00001 diff --git a/src/icons/refresh.svg b/src/icons/refresh.svg new file mode 100644 index 0000000..f3f25f1 --- /dev/null +++ b/src/icons/refresh.svg @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/icons/refresh24.png b/src/icons/refresh24.png new file mode 100644 index 0000000000000000000000000000000000000000..c5054b3ecfe3aab1296d4f35c3412dfa78afdb02 GIT binary patch literal 1144 zcmV-;1c&>HP)^L1O-V% zK~zY`m6m->)m0eBKj+-v6@-gQOkfv81Oi`5B+Qk$98flJOYM)gYq)Z*tu?c(t=gJy z+WM#Uvaqc`nyV?kOy?g8wlxB*HqjX(w!9K>r-0!L?_5Cc%kSwAytn(p1$zEF=Q+>! zd(QVf&v}kw1}m;Rm1Sz*7Nyt>WCNLxTs^=oL~1RDK6_=OqdOLcnr^bN{#1rV`S*kD z0xZmICQ6+#;lpbsj$5-56gM8PYFpqW3Sf0(b*3TO87j**doCa6uf3o#G zmdyD!zFSku8_jiePXyN_VUYvCo2t0(RF+tLuF!1xY5f+`;u5I2>*9d(G7{rf6Adfh z7nM<9OXlK0FYmNo2vgCg%xsH&=PR!R6``Kav0*yKhWXajiaA5t?9M49WnMh#@rf*% zpTw#KDLj{A=hwbF2xzUeOAAsS8F*>nE=RhY_(f*S%RbKpg$ox4#~V`YcuYU$qc{<% z(4g`n1Fc%4m6|p2k9D_kV{{-m?)N<8n~rOtHIS=8(jx;uTe+UMmOVKufhoelo0sv) zl#rjdH#6e%gf7W2B7-)h*eP4Q1iuLN_q%Cx56(!^?jGVumy-fpGQZsKiY~n3hU0Al z`GKrBy{;md<8AIicKq@4taqW6!cZEI>5p{X)B>)+Xiv_XAUHsQEg45jZ*8C(+K3z_ES~l}^ z*aOQG3sN{-^a3xYX5leS_B)#*2@YQ`sq9hzH5i{0ND6oZZ;U-Y5r8qD7uWbOUem-L zZzDZ^O1g)BKl_|bG&~4vY9q?Q+M{ls2it106D`nP%zDWrdgI(FHcs1j35-irJ zi~X(t4pp74+#VkZ?{LD_t7Y43q8m=bi9LdR9ocZKT2r)eF}aD0uqeg7$#GhS9?<8R zm@c8-Ybo1)C}ztnYB=$-LaIaMnxl=N%-61#RMv(iLgcEJQpY(lj9fvg0N)&dO^~C? z@Gp-9kNK+z*y_gWOasdnFgGJ=S?ITAs)#u6Rpz + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/icons/stop24.png b/src/icons/stop24.png new file mode 100644 index 0000000000000000000000000000000000000000..8792c936cb5aae1973e1f6d7f9ea3baed530fa70 GIT binary patch literal 622 zcmV-!0+IcRP)9)WocT>1=DKL3aY$+!owJ+!hI8&a^X8r>9D$uwF78;9L77p4 z1W4>)MO%Vts0KApY$aJ)Y7XL%e#PeX+_-1ti3sz6UcQg6>eRpu!c_}P90s^Dl==^)RmzG_NuS>w)iq!_8sdbjAJA_#8Dgt*7Kc=QMgKE&}#-rMkm0O0nSIqFXM)2 z5g4Eyp+MUJ^$0(5-JrS|8NEo&cw#Gn9|6C2!gy6DSy^f}()j`hv;X(+|K=TZIzx_% z_kDs!7GveLmIGh|ed=4e1&noH*x%X?&zIw1Pp!A`D-SNzieC`D{hzD~1er^eSHJ!d zIEjtoD}hHq@K59-4<{;x>cGhSoX)2MVYSz;VQmqkvlHvZ+Q7&Jh`Y;f=cJiZcn)~O zbPc+K^{2z+18)^w941``Wd>mqh;^4h>%gXCeK%HKYYpP~37k!{rb~+v)Bpeg07*qo IM6N<$f=pQ%$^ZZW literal 0 HcmV?d00001 diff --git a/src/ide.c b/src/ide.c index a4e3fda..7b9ad40 100644 --- a/src/ide.c +++ b/src/ide.c @@ -684,7 +684,7 @@ void ide_set_signature(IDE *ide) ide->sector=1; ide->head=0; ide->cylinder=(IDE_DRIVE_IS_CDROM(ide) ? 0xEB14 : ((ide->type == IDE_HDD) ? 0 : 0xFFFF)); - if (ide->type == IDE_HDD) ide->drive = 0; +// if (ide->type == IDE_HDD) ide->drive = 0; } void resetide(void) @@ -717,6 +717,7 @@ void resetide(void) #else for (d = 0; d < 4; d++) { + ide_drives[d].drive = d; ide_drives[d].packetstatus = 0xFF; if ((cdrom_channel == d) && cdrom_enabled) @@ -1378,7 +1379,7 @@ void callbackide(int ide_board) // if (addr) output=3; ide_irq_raise(ide); #ifndef RPCEMU_IDE - readflash=1; + readflash_set(READFLASH_HDC, ide->drive); #endif return; @@ -1414,7 +1415,7 @@ void callbackide(int ide_board) } } #ifndef RPCEMU_IDE - readflash=1; + readflash_set(READFLASH_HDC, ide->drive); #endif return; @@ -1437,7 +1438,7 @@ void callbackide(int ide_board) if (ide->blockcount >= ide->blocksize) ide->blockcount = 0; #ifndef RPCEMU_IDE - readflash=1; + readflash_set(READFLASH_HDC, ide->drive); #endif return; @@ -1461,7 +1462,7 @@ void callbackide(int ide_board) else ide->atastat = READY_STAT | DSC_STAT; #ifndef RPCEMU_IDE - readflash=1; + readflash_set(READFLASH_HDC, ide->drive); #endif return; @@ -1497,7 +1498,7 @@ void callbackide(int ide_board) } } #ifndef RPCEMU_IDE - readflash=1; + readflash_set(READFLASH_HDC, ide->drive); #endif return; @@ -1525,7 +1526,7 @@ void callbackide(int ide_board) else ide->atastat = READY_STAT | DSC_STAT; #ifndef RPCEMU_IDE - readflash=1; + readflash_set(READFLASH_HDC, ide->drive); #endif return; @@ -1539,7 +1540,7 @@ void callbackide(int ide_board) // pclog("Read verify callback %i %i %i offset %08X %i left\n",ide.sector,ide.cylinder,ide.head,addr,ide.secount); ide_irq_raise(ide); #ifndef RPCEMU_IDE - readflash=1; + readflash_set(READFLASH_HDC, ide->drive); #endif return; @@ -1558,7 +1559,7 @@ void callbackide(int ide_board) ide->atastat = READY_STAT | DSC_STAT; ide_irq_raise(ide); #ifndef RPCEMU_IDE - readflash=1; + readflash_set(READFLASH_HDC, ide->drive); #endif return; @@ -1883,7 +1884,7 @@ static void atapicommand(int ide_board) #ifndef RPCEMU_IDE pclog("New ATAPI command %02X %i\n",idebufferb[0],ins); #endif -// readflash=1; +// readflash_set(READFLASH_HDD, ide->drive, 1); msf=idebufferb[1]&2; ide->cdlen=0; @@ -2092,7 +2093,7 @@ static void atapicommand(int ide_board) else atapi->readsector_raw(idebufferb,ide->cdpos); #ifndef RPCEMU_IDE - readflash=1; + readflash_set(READFLASH_HDC, ide->drive); #endif readcdmode = (rcdmode == 0xF8); ide->cdpos++; @@ -2157,7 +2158,7 @@ static void atapicommand(int ide_board) break; } #ifndef RPCEMU_IDE - readflash=1; + readflash_set(READFLASH_HDC, ide->drive); #endif ide->cdpos++; ide->cdlen--; @@ -2690,7 +2691,7 @@ static void callreadcd(IDE *ide) else atapi->readsector((uint8_t *) ide->buffer, ide->cdpos); #ifndef RPCEMU_IDE - readflash=1; + readflash_set(READFLASH_HDC, ide->drive); #endif ide->cdpos++; ide->cdlen--; diff --git a/src/mfm_at.c b/src/mfm_at.c index f2099a1..81d0bd6 100644 --- a/src/mfm_at.c +++ b/src/mfm_at.c @@ -517,7 +517,7 @@ void mfm_callback(void *p) // pclog("Read sector callback %i %i %i offset %08X %i left %i %02X\n",ide.sector,ide.cylinder,ide.head,addr,ide.secount,ide.spt,ide.atastat[ide.board]); // if (addr) output=3; mfm_irq_raise(mfm); - readflash = 1; + readflash_set(READFLASH_HDC, mfm->drive_sel); break; case CMD_WRITE: @@ -541,7 +541,7 @@ void mfm_callback(void *p) } else mfm->status = STAT_READY | STAT_DSC; - readflash = 1; + readflash_set(READFLASH_HDC, mfm->drive_sel); break; case CMD_VERIFY: @@ -550,7 +550,7 @@ void mfm_callback(void *p) mfm->status = STAT_READY | STAT_DSC; // pclog("Read verify callback %i %i %i offset %08X %i left\n",ide.sector,ide.cylinder,ide.head,addr,ide.secount); mfm_irq_raise(mfm); - readflash=1; + readflash_set(READFLASH_HDC, mfm->drive_sel); break; case CMD_FORMAT: @@ -570,7 +570,7 @@ void mfm_callback(void *p) } mfm->status = STAT_READY | STAT_DSC; mfm_irq_raise(mfm); - readflash = 1; + readflash_set(READFLASH_HDC, mfm->drive_sel); break; case CMD_DIAGNOSE: diff --git a/src/mfm_xebec.c b/src/mfm_xebec.c index 7a65a31..bf583a9 100644 --- a/src/mfm_xebec.c +++ b/src/mfm_xebec.c @@ -391,7 +391,7 @@ static void xebec_callback(void *p) xebec_complete(xebec); - readflash = 1; + readflash_set(READFLASH_HDC, xebec->drive_sel); break; default: @@ -450,7 +450,7 @@ static void xebec_callback(void *p) fseeko64(drive->hdfile, addr * 512, SEEK_SET); fread(xebec->sector_buf, 512, 1, drive->hdfile); - readflash = 1; + readflash_set(READFLASH_HDC, xebec->drive_sel); } if (xebec->irq_dma_mask & DMA_ENA) xebec->callback = XEBEC_TIME; @@ -506,7 +506,7 @@ static void xebec_callback(void *p) fseeko64(drive->hdfile, addr * 512, SEEK_SET); fread(xebec->sector_buf, 512, 1, drive->hdfile); - readflash = 1; + readflash_set(READFLASH_HDC, xebec->drive_sel); xebec->state = STATE_SEND_DATA; @@ -592,7 +592,7 @@ static void xebec_callback(void *p) fwrite(xebec->sector_buf, 512, 1, drive->hdfile); } - readflash = 1; + readflash_set(READFLASH_HDC, xebec->drive_sel); xebec_next_sector(xebec); xebec->data_pos = 0; diff --git a/src/pc.c b/src/pc.c index 1420253..474489b 100644 --- a/src/pc.c +++ b/src/pc.c @@ -586,6 +586,22 @@ void closepc() END_OF_MAIN();*/ +typedef struct config_callback_t +{ + void(*loadconfig)(); + void(*saveconfig)(); + void(*onloaded)(); +} config_callback_t; +config_callback_t config_callbacks[10]; +int num_config_callbacks = 0; + +void add_config_callback(void(*loadconfig)(), void(*saveconfig)(), void(*onloaded)()) +{ + config_callbacks[num_config_callbacks].loadconfig = loadconfig; + config_callbacks[num_config_callbacks].saveconfig = saveconfig; + config_callbacks[num_config_callbacks].onloaded = onloaded; + num_config_callbacks++; +} void loadconfig(char *fn) { @@ -734,6 +750,16 @@ void loadconfig(char *fn) } enable_sync = config_get_int(CFG_MACHINE, NULL, "enable_sync", 1); + + + for (d = 0; d < num_config_callbacks; ++d) + if (config_callbacks[d].loadconfig) + config_callbacks[d].loadconfig(); + + + for (d = 0; d < num_config_callbacks; ++d) + if (config_callbacks[d].onloaded) + config_callbacks[d].onloaded(); } void saveconfig(char *fn) @@ -837,6 +863,10 @@ void saveconfig(char *fn) config_set_int(CFG_MACHINE, NULL, "enable_sync", enable_sync); + for (d = 0; d < num_config_callbacks; ++d) + if (config_callbacks[d].saveconfig) + config_callbacks[d].saveconfig(); + pclog("config_save(%s)\n", config_file_default); if (fn) config_save(CFG_MACHINE, fn); diff --git a/src/pc.xrc b/src/pc.xrc new file mode 100644 index 0000000..b1a2d19 --- /dev/null +++ b/src/pc.xrc @@ -0,0 +1,1617 @@ + + + + icons/drive.png + icons/disk.png + icons/cd.png + + + + icons/play24.png + + + + icons/pause24.png + + + + icons/stop24.png + + + + icons/refresh24.png + + + + + + + + + + + + + + 1 + + + + 1 + + + + 1 + + + + 1 + + + + + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + + + + + 1 + + + + 1 + + + + 1 + + + + + + + 1 + + + + 1 + + + + + + + + 1 + + + + + + 1 + + + + 1 + + + + 1 + + + + 1 + + + + + + + 1 + + + + 1 + + + + 1 + + + + 1 + + + + + + + + 1 + + + + 1 + + + + + 1 + + + + + + 1 + + + + 1 + + + + + + + 1 + + + + 1 + + + + 1 + + + + 1 + + + + + 1 + + + + + + + + + + + + + + Configure PCem + 1 + + + + wxALL + 5 + + 3 + 0 + 0 + 0 + + + + wxALIGN_LEFT|wxALL + 0 + + + + + + wxALL + 0 + + + + + + wxALIGN_CENTRE|wxALL + 0 + + + + + + + + wxALIGN_LEFT|wxALL + 0 + + + + + + wxALL + 0 + + + + + + wxALIGN_CENTRE|wxALL + 0 + + + + + + + + wxALIGN_LEFT|wxALL + 0 + + + + + + wxALL + 0 + + + + + + + + + wxALIGN_LEFT|wxALL + 0 + + + + + + wxALL + 0 + + + + + + + + + wxALIGN_LEFT|wxALL + 0 + + + + + + wxALL + 0 + + + + + + + + + wxALIGN_LEFT|wxALL + 0 + + + + + + + + + + wxALIGN_LEFT|wxALL + 0 + + + + + + wxALL + 0 + + + + + + + + + wxALIGN_LEFT|wxALL + 0 + + + + + + wxALL + 0 + + + + + + wxALIGN_CENTRE|wxALL + 0 + + + + + + + + + wxALIGN_LEFT|wxALL + 0 + + + + + + wxALL + 0 + + + + + + + + + wxALIGN_LEFT|wxALL + 0 + + + + + + wxALL + 0 + + + + + + + + + wxALIGN_LEFT|wxALL + 0 + + + + + + wxALL + 0 + + + + + + + + + wxALIGN_LEFT|wxALL + 0 + + + + + + wxALL + 0 + + wxHORIZONTAL + + wxALIGN_CENTRE|wxALL + 0 + + + 50 + 10 + 200 + + + + wxALIGN_CENTER|wxALL + 0 + + + + + + + + + + + wxALIGN_LEFT|wxALL + 0 + + + + + + wxALL + 0 + + + + + + + + + + + wxALIGN_LEFT|wxALL + 0 + + + + + + + + + + wxALIGN_LEFT|wxALL + 0 + + + + + + + + + + wxALIGN_LEFT|wxALL + 0 + + + + + + + + + + wxALIGN_LEFT|wxALL + 0 + + + + + + + + + + wxALIGN_LEFT|wxALL + 0 + + + + + + wxALIGN_CENTRE|wxALL + 0 + + + + + + + + wxALIGN_LEFT|wxALL + 0 + + wxHORIZONTAL + + wxALIGN_CENTRE|wxALL + 0 + + 1 + + + + + wxALIGN_CENTRE|wxALL + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + Configure Hard Discs + 1 + + + + wxALL + 5 + + 1 + 0 + 0 + 0 + + + + + 4 + 0 + 0 + 0 + + + wxALIGN_LEFT|wxALL + 0 + + + + + + wxALL + 0 + + + + + + + wxALL + 0 + + + + + + + + wxALL + 0 + + + + + + wxALIGN_CENTRE|wxALL + 0 + + + + + + wxALIGN_CENTRE|wxALL + 0 + + + + + + wxALIGN_CENTRE|wxALL + 0 + + + + + + + + wxHORIZONTAL + + wxALIGN_CENTRE|wxALL + 0 + + + + + + wxALIGN_CENTRE|wxALL + 0 + + + + + + + + + wxHORIZONTAL + + wxALIGN_CENTRE|wxALL + 0 + + + + + + wxALIGN_CENTRE|wxALL + 0 + + + + + + + + + wxHORIZONTAL + + wxALIGN_CENTRE|wxALL + 0 + + + + + + wxALIGN_CENTRE|wxALL + 0 + + + + + + + + wxALL + 0 + + + + + + + + + + + + 4 + 0 + 0 + 0 + + + wxALIGN_LEFT|wxALL + 0 + + + + + + wxALL + 0 + + + + + + + wxALL + 0 + + + + + + + + wxALL + 0 + + + + + + wxALIGN_CENTRE|wxALL + 0 + + + + + + wxALIGN_CENTRE|wxALL + 0 + + + + + + wxALIGN_CENTRE|wxALL + 0 + + + + + + + + wxHORIZONTAL + + wxALIGN_CENTRE|wxALL + 0 + + + + + + wxALIGN_CENTRE|wxALL + 0 + + + + + + + + + wxHORIZONTAL + + wxALIGN_CENTRE|wxALL + 0 + + + + + + wxALIGN_CENTRE|wxALL + 0 + + + + + + + + + wxHORIZONTAL + + wxALIGN_CENTRE|wxALL + 0 + + + + + + wxALIGN_CENTRE|wxALL + 0 + + + + + + + + wxALL + 0 + + + + + + + + + + + + 4 + 0 + 0 + 0 + + + wxALIGN_LEFT|wxALL + 0 + + + + + + wxALL + 0 + + + + + + + wxALL + 0 + + + + + + + + wxALL + 0 + + + + + + wxALIGN_CENTRE|wxALL + 0 + + + + + + wxALIGN_CENTRE|wxALL + 0 + + + + + + wxALIGN_CENTRE|wxALL + 0 + + + + + + + + wxHORIZONTAL + + wxALIGN_CENTRE|wxALL + 0 + + + + + + wxALIGN_CENTRE|wxALL + 0 + + + + + + + + + wxHORIZONTAL + + wxALIGN_CENTRE|wxALL + 0 + + + + + + wxALIGN_CENTRE|wxALL + 0 + + + + + + + + + wxHORIZONTAL + + wxALIGN_CENTRE|wxALL + 0 + + + + + + wxALIGN_CENTRE|wxALL + 0 + + + + + + + + wxALL + 0 + + + + + + + + + + + + 4 + 0 + 0 + 0 + + + wxALIGN_LEFT|wxALL + 0 + + + + + + wxALL + 0 + + + + + + + wxALL + 0 + + + + + + + + wxALL + 0 + + + + + + wxALIGN_CENTRE|wxALL + 0 + + + + + + wxALIGN_CENTRE|wxALL + 0 + + + + + + wxALIGN_CENTRE|wxALL + 0 + + + + + + + + wxHORIZONTAL + + wxALIGN_CENTRE|wxALL + 0 + + + + + + wxALIGN_CENTRE|wxALL + 0 + + + + + + + + + wxHORIZONTAL + + wxALIGN_CENTRE|wxALL + 0 + + + + + + wxALIGN_CENTRE|wxALL + 0 + + + + + + + + + wxHORIZONTAL + + wxALIGN_CENTRE|wxALL + 0 + + + + + + wxALIGN_CENTRE|wxALL + 0 + + + + + + + + wxALL + 0 + + + + + + + + + wxALIGN_LEFT|wxALL + 0 + + wxHORIZONTAL + + wxALIGN_CENTRE|wxALL + 0 + + 1 + + + + + wxALIGN_CENTRE|wxALL + 0 + + + + + + + + + + + + + + New Hard Disc + 1 + + + + wxALL + 5 + + 2 + 0 + 0 + 0 + + + wxALL + 0 + + + + + + wxALIGN_CENTRE|wxALL + 0 + + + + + + + wxALIGN_LEFT|wxALL + 0 + + + + + + wxALL + 0 + + + + + + wxALIGN_LEFT|wxALL + 0 + + + + + + wxALL + 0 + + + + + + wxALIGN_LEFT|wxALL + 0 + + + + + + wxALL + 0 + + + + + + wxALIGN_LEFT|wxALL + 0 + + + + + + + + wxALIGN_LEFT|wxALL + 0 + + + + + + wxALL + 0 + + + + + + + wxALIGN_LEFT|wxALL + 0 + + wxHORIZONTAL + + wxALIGN_CENTRE|wxALL + 0 + + 1 + + + + + wxALIGN_CENTRE|wxALL + 0 + + + + + + + + + + + + + + Hard disc parameters + 1 + + + + wxALL + 5 + + wxVERTICAL + + wxALIGN_LEFT|wxALL + 0 + + + + + + wxALIGN_CENTRE|wxALL + 0 + + 2 + 0 + 0 + 0 + + + wxALIGN_LEFT|wxALL + 0 + + + + + + wxALL + 0 + + + + + + wxALIGN_LEFT|wxALL + 0 + + + + + + wxALL + 0 + + + + + + wxALIGN_LEFT|wxALL + 0 + + + + + + wxALL + 0 + + + + + + wxALIGN_LEFT|wxALL + 0 + + + + + + + + wxALIGN_LEFT|wxALL + 0 + + + + + + wxALL + 0 + + + + + + + wxALIGN_LEFT|wxALL + 0 + + wxHORIZONTAL + + wxALIGN_CENTRE|wxALL + 0 + + 1 + + + + + wxALIGN_CENTRE|wxALL + 0 + + + + + + + + + + + + + + + + PCem Configuration Manager + 1 + + + + wxALL + 5 + + wxHORIZONTAL + + wxALL + 0 + + + 200,300 + + + + wxEXPAND + 0 + + wxVERTICAL + + + wxALL + 0 + + + 1 + + + + + + wxEXPAND + + + + wxALL + 0 + + + + + + + wxALL + 0 + + + + + + + wxALL + 0 + + + + + + + + wxEXPAND + + + + wxALL + 0 + + + + + + + wxALL + 0 + + + + + + + + wxEXPAND + + + + wxALL + 0 + + + + + + + + + + + + + + PCem + 1 + + + wxVERTICAL + + + wxEXPAND + 5 + + wxHORIZONTAL + + + wxALL + 5 + + + + + + + wxALIGN_CENTER|wxALL + 5 + + + -1 + + + + + + + wxALL + 5 + + + 0 + + + + + wxEXPAND + 5 + + + wxALIGN_CENTER_HORIZONTAL|wxALL + 5 + + + + + + wxALIGN_CENTER_HORIZONTAL|wxALL + 5 + + + + + + + + + + + + + + 1 + + + wxVERTICAL + + + wxALL + 5 + + + -1 + + + + + wxEXPAND | wxALL + 5 + + + + + + + wxALL + 5 + + + 1 + + + + + + diff --git a/src/vid_voodoo.c b/src/vid_voodoo.c index b77a14a..0790068 100644 --- a/src/vid_voodoo.c +++ b/src/vid_voodoo.c @@ -1647,7 +1647,7 @@ static inline int fastlog(uint64_t val) return (exp << 8) | logtable[frac]; } -static inline int fls(uint16_t val) +static inline int voodoo_fls(uint16_t val) { int num = 0; @@ -2768,7 +2768,7 @@ static void voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, vood w_depth = 0xf001; else { - int exp = fls((uint16_t)((uint32_t)state->w >> 16)); + int exp = voodoo_fls((uint16_t)((uint32_t)state->w >> 16)); int mant = ((~(uint32_t)state->w >> (19 - exp))) & 0xfff; w_depth = (exp << 12) + mant + 1; if (w_depth > 0xffff) diff --git a/src/video.h b/src/video.h index dc04a81..ffca4e8 100644 --- a/src/video.h +++ b/src/video.h @@ -1,4 +1,4 @@ -#ifdef __unix +#ifdef PCEM_ALLEGRO #undef MAX_JOYSTICKS #include "allegro-main.h" diff --git a/src/wx-app.cc b/src/wx-app.cc new file mode 100644 index 0000000..003ab39 --- /dev/null +++ b/src/wx-app.cc @@ -0,0 +1,224 @@ +#include "wx-app.h" + +#include +#include +#include "wx-utils.h" +#include "wx-common.h" + +extern "C" +{ + int wx_load_config(void*); + int wx_start(void*); + int wx_stop(void*); + void wx_show(void*); + void wx_handle_command(void*, int, int); + + int start_emulation(void*); + int resume_emulation(); + int pause_emulation(); + int stop_emulation(); +} + +extern void InitXmlResource(); + +wxDEFINE_EVENT(WX_CALLBACK_EVENT, CallbackEvent); +wxDEFINE_EVENT(WX_EXIT_EVENT, wxCommandEvent); +wxDEFINE_EVENT(WX_STOP_EMULATION_EVENT, wxCommandEvent); +wxDEFINE_EVENT(WX_EXIT_COMPLETE_EVENT, wxCommandEvent); +wxDEFINE_EVENT(WX_SHOW_WINDOW_EVENT, wxCommandEvent); +wxDEFINE_EVENT(WX_POPUP_MENU_EVENT, PopupMenuEvent); + +wxBEGIN_EVENT_TABLE(Frame, wxFrame) +wxEND_EVENT_TABLE() + +wxIMPLEMENT_APP_NO_MAIN(App); + +App::App() +{ + this->frame = NULL; +} + +bool App::OnInit() +{ + wxImage::AddHandler( new wxPNGHandler ); + wxXmlResource::Get()->InitAllHandlers(); +// if (!wxXmlResource::Get()->Load("src/pc.xrc")) +// { +// std::cout << "Could not load resource file" << std::endl; +// return false; +// } + InitXmlResource(); + + frame = new Frame(this, "null frame", wxPoint(500, 500), + wxSize(100, 100)); + frame->Start(); + return true; +} + +int App::OnRun() +{ + return wxApp::OnRun(); +} + +#include + +Frame::Frame(App* app, const wxString& title, const wxPoint& pos, + const wxSize& size) : + wxFrame(NULL, wxID_ANY, title, pos, size, 0)//wxDEFAULT_FRAME_STYLE & ~(wxRESIZE_BORDER)) +{ + this->closing = false; + this->menu = wxXmlResource::Get()->LoadMenu(wxT("main_menu")); + + Bind(wxEVT_CLOSE_WINDOW, &Frame::OnClose, this); + Bind(wxEVT_MENU, &Frame::OnCommand, this); + Bind(wxEVT_TOOL, &Frame::OnCommand, this); + Bind(WX_SHOW_WINDOW_EVENT, &Frame::OnShowWindowEvent, this); + Bind(WX_POPUP_MENU_EVENT, &Frame::OnPopupMenuEvent, this); + Bind(WX_EXIT_EVENT, &Frame::OnExitEvent, this); + Bind(WX_EXIT_COMPLETE_EVENT, &Frame::OnExitCompleteEvent, this); + Bind(WX_STOP_EMULATION_EVENT, &Frame::OnStopEmulationEvent, this); + Bind(WX_CALLBACK_EVENT, &Frame::OnCallbackEvent, this); + + CenterOnScreen(); +} + +void Frame::Start() +{ + if (wx_start(this)) + ShowConfigSelection(); + else + Quit(0); +} + +void Frame::ShowConfigSelection() +{ + if (wx_load_config(this)) + start_emulation(this); + else + Quit(1); +} + +void Frame::OnCallbackEvent(CallbackEvent& event) +{ + WX_CALLBACK callback = event.GetCallback(); + callback(); +} + +void Frame::OnStopEmulationEvent(wxCommandEvent& event) +{ + if (emulation_state != EMULATION_STOPPED) + { + pause_emulation(); + int ret = wxID_OK; + + if (confirm_on_stop_emulation) + { + wxDialog dlg; + wxXmlResource::Get()->LoadDialog(&dlg, this, "ConfirmRememberDlg"); + dlg.FindWindow("IDC_CONFIRM_LABEL")->SetLabel("Stop emulation?"); + dlg.FindWindow("IDC_CONFIRM_REMEMBER")->SetLabel("Do not ask again"); + dlg.Fit(); + ret = dlg.ShowModal(); + if (ret == wxID_OK) + confirm_on_stop_emulation = !((wxCheckBox*)dlg.FindWindow("IDC_CONFIRM_REMEMBER"))->IsChecked(); + } + + if (ret == wxID_OK) + { + stop_emulation(); + ShowConfigSelection(); + } + else + resume_emulation(); + } +} + +void Frame::OnShowWindowEvent(wxCommandEvent& event) +{ + wxWindow* window = (wxWindow*)event.GetEventObject(); + int shown = window->IsShown(); + int value = event.GetInt(); + if (value < 0) + window->Show(!shown); + else + window->Show(value > 0); + if (!shown) + window->Refresh(); +} + +void Frame::OnPopupMenuEvent(PopupMenuEvent& event) +{ + wxWindow* window = event.GetWindow(); + wxMenu* menu = event.GetMenu(); + int* x = event.GetX(); + int* y = event.GetY(); + + if (x && y) + window->PopupMenu(menu, *x, *y); + else + window->PopupMenu(menu); +} + +void Frame::OnCommand(wxCommandEvent& event) +{ + wx_handle_command(this, event.GetId(), event.IsChecked()); +} + +void Frame::OnClose(wxCloseEvent& event) +{ + wx_exit(this, 0); +} + +wxMenu* Frame::GetMenu() +{ + return menu; +} + +/* Exit */ + +void Frame::Quit(bool stop_emulator) +{ + if (closing) + return; + closing = true; + if (stop_emulator) + { + if (!wx_stop(this)) + { + // cancel quit + closing = false; + return; + } + } + Destroy(); +} + +void Frame::OnExitEvent(wxCommandEvent& event) +{ + if (closing) + return; + closing = true; + CExitThread* exitThread = new CExitThread(this); + exitThread->Run(); +} + +void Frame::OnExitCompleteEvent(wxCommandEvent& event) +{ + if (event.GetInt()) + Destroy(); + else + closing = false; +} + +CExitThread::CExitThread(Frame* frame) +{ + this->frame = frame; +} + +wxThread::ExitCode CExitThread::Entry() +{ + wxCommandEvent* event = new wxCommandEvent(WX_EXIT_COMPLETE_EVENT, wxID_ANY); + event->SetInt(wx_stop(frame)); + wxQueueEvent(frame, event); + return 0; +} diff --git a/src/wx-app.h b/src/wx-app.h new file mode 100644 index 0000000..0c3b244 --- /dev/null +++ b/src/wx-app.h @@ -0,0 +1,134 @@ +#ifndef SRC_WX_APP_H_ +#define SRC_WX_APP_H_ + +#include +#ifndef WX_PRECOMP +#include +#endif + +#include "wx-utils.h" + +class CallbackEvent; +class PopupMenuEvent; + +wxDECLARE_EVENT(WX_CALLBACK_EVENT, CallbackEvent); +wxDECLARE_EVENT(WX_EXIT_EVENT, wxCommandEvent); +wxDECLARE_EVENT(WX_STOP_EMULATION_EVENT, wxCommandEvent); +wxDECLARE_EVENT(WX_EXIT_COMPLETE_EVENT, wxCommandEvent); +wxDECLARE_EVENT(WX_SHOW_WINDOW_EVENT, wxCommandEvent); +wxDECLARE_EVENT(WX_POPUP_MENU_EVENT, PopupMenuEvent); + +class CallbackEvent: public wxCommandEvent +{ +public: + CallbackEvent(WX_CALLBACK callback) : wxCommandEvent(WX_CALLBACK_EVENT) + { + this->callback = callback; + } + CallbackEvent(const CallbackEvent& event) : wxCommandEvent(event) + { + this->callback = event.GetCallback(); + } + + wxEvent* Clone() const { return new CallbackEvent(*this); } + + WX_CALLBACK GetCallback() const { return callback; } + +private: + WX_CALLBACK callback; + + +}; + +class PopupMenuEvent: public wxCommandEvent +{ +public: + PopupMenuEvent(wxWindow* window, wxMenu* menu, int* x, int* y) : wxCommandEvent(WX_POPUP_MENU_EVENT) + { + this->window = window; + this->menu = menu; + this->x = x; + this->y = y; + } + PopupMenuEvent(const PopupMenuEvent& event) : wxCommandEvent(event) + { + this->window = event.GetWindow(); + this->menu = event.GetMenu(); + this->x = event.GetX(); + this->y = event.GetY(); + } + + wxEvent* Clone() const { return new PopupMenuEvent(*this); } + + wxWindow* GetWindow() const { return window; } + wxMenu* GetMenu() const { return menu; } + int* GetX() const { return x; } + int* GetY() const { return y; } + +private: + int* x; + int* y; + wxMenu* menu; + wxWindow* window; +}; + + +class Frame; + +class App: public wxApp +{ +public: + App(); + virtual bool OnInit(); + virtual int OnRun(); + Frame* GetFrame() + { + return frame; + } +private: + Frame* frame; +}; + +class CExitThread: public wxThread +{ +public: + CExitThread(Frame* frame); + virtual ~CExitThread() {} +private: + wxThread::ExitCode Entry(); + Frame* frame; +}; + +class Frame: public wxFrame +{ +public: + Frame(App* app, const wxString& title, const wxPoint& pos, + const wxSize& size); + + virtual ~Frame() {} + + void Start(); + + wxMenu* GetMenu(); + +private: + void OnCommand(wxCommandEvent& event); + void OnExitEvent(wxCommandEvent& event); + void OnExitCompleteEvent(wxCommandEvent& event); + void OnStopEmulationEvent(wxCommandEvent& event); + void OnShowWindowEvent(wxCommandEvent& event); + void OnPopupMenuEvent(PopupMenuEvent& event); + void OnCallbackEvent(CallbackEvent& event); + void OnClose(wxCloseEvent& event); + + void ShowConfigSelection(); + wxMenu* menu; + + bool closing; + + void Quit(bool stop_emulator = 1); + + wxDECLARE_EVENT_TABLE(); +}; + +#endif /* SRC_WX_APP_H_ */ diff --git a/src/wx-common.c b/src/wx-common.c new file mode 100644 index 0000000..55ef6e6 --- /dev/null +++ b/src/wx-common.c @@ -0,0 +1,34 @@ +#include "wx-common.h" +#include "config.h" + +void wx_loadconfig() +{ + show_machine_info = config_get_int(CFG_GLOBAL, "wxWidgets", "show_machine_info", show_machine_info); + show_disc_activity = config_get_int(CFG_GLOBAL, "wxWidgets", "show_disc_activity", show_disc_activity); + show_speed_history = config_get_int(CFG_GLOBAL, "wxWidgets", "show_speed_history", show_speed_history); + show_mount_paths = config_get_int(CFG_GLOBAL, "wxWidgets", "show_mount_paths", show_mount_paths); + show_status = config_get_int(CFG_GLOBAL, "wxWidgets", "show_status", show_status); + show_machine_on_start = config_get_int(CFG_GLOBAL, "wxWidgets", "show_machine_on_start", show_machine_on_start); + + confirm_on_reset_machine = config_get_int(CFG_GLOBAL, "wxWidgets", "confirm_on_reset_machine", confirm_on_reset_machine); + confirm_on_stop_emulation = config_get_int(CFG_GLOBAL, "wxWidgets", "confirm_on_stop_emulation", confirm_on_stop_emulation); + + wx_window_x = config_get_int(CFG_GLOBAL, "wxWidgets", "window_x", wx_window_x); + wx_window_y = config_get_int(CFG_GLOBAL, "wxWidgets", "window_y", wx_window_y); +} + +void wx_saveconfig() +{ + config_set_int(CFG_GLOBAL, "wxWidgets", "show_machine_info", show_machine_info); + config_set_int(CFG_GLOBAL, "wxWidgets", "show_disc_activity", show_disc_activity); + config_set_int(CFG_GLOBAL, "wxWidgets", "show_speed_history", show_speed_history); + config_set_int(CFG_GLOBAL, "wxWidgets", "show_mount_paths", show_mount_paths); + config_set_int(CFG_GLOBAL, "wxWidgets", "show_status", show_status); + config_set_int(CFG_GLOBAL, "wxWidgets", "show_machine_on_start", show_machine_on_start); + + config_set_int(CFG_GLOBAL, "wxWidgets", "confirm_on_reset_machine", confirm_on_reset_machine); + config_set_int(CFG_GLOBAL, "wxWidgets", "confirm_on_stop_emulation", confirm_on_stop_emulation); + + config_set_int(CFG_GLOBAL, "wxWidgets", "window_x", wx_window_x); + config_set_int(CFG_GLOBAL, "wxWidgets", "window_y", wx_window_y); +} diff --git a/src/wx-common.h b/src/wx-common.h new file mode 100644 index 0000000..294a0ee --- /dev/null +++ b/src/wx-common.h @@ -0,0 +1,26 @@ +extern int show_machine_info; +extern int show_status; +extern int show_machine_on_start; +extern int confirm_on_stop_emulation; +extern int confirm_on_reset_machine; +extern int show_speed_history; +extern int show_disc_activity; +extern int show_mount_paths; +extern int wx_window_x; +extern int wx_window_y; + +typedef enum { EMULATION_STOPPED, EMULATION_PAUSED, EMULATION_RUNNING } emulation_state_t; +extern emulation_state_t emulation_state; + +#define IS_PAUSED (emulation_state == EMULATION_PAUSED) + +typedef enum { DRIVE_TYPE_HDD, DRIVE_TYPE_FDD, DRIVE_TYPE_CDROM } drive_type_t; + +typedef struct drive_info_t { + drive_type_t type; + char fn[256]; + int enabled; + int drive; + char drive_letter; + int readflash; +} drive_info_t; diff --git a/src/wx-config.c b/src/wx-config.c new file mode 100644 index 0000000..2a5658d --- /dev/null +++ b/src/wx-config.c @@ -0,0 +1,863 @@ +#include "wx-utils.h" + +#include "ibm.h" +#include "cpu.h" +#include "device.h" +#include "fdd.h" +#include "gameport.h" +#include "hdd.h" +#include "model.h" +#include "mouse.h" +#include "mem.h" +#include "nvr.h" +#include "sound.h" +#include "video.h" +#include "vid_voodoo.h" + +extern int pause; + +extern int is486; +static int romstolist[ROM_MAX], listtomodel[ROM_MAX], romstomodel[ROM_MAX], + modeltolist[ROM_MAX]; +static int settings_sound_to_list[20], settings_list_to_sound[20]; +static int settings_mouse_to_list[20], settings_list_to_mouse[20]; +static int settings_network_to_list[20], settings_list_to_network[20]; +static char *hdd_names[16]; + +int has_been_inited = 0; + +extern void deviceconfig_open(void* hwnd, device_t *device); + +static int mouse_valid(int type, int model) +{ + if (((type & MOUSE_TYPE_IF_MASK) == MOUSE_TYPE_PS2) + && !(models[model].flags & MODEL_PS2)) + return 0; + if (((type & MOUSE_TYPE_IF_MASK) == MOUSE_TYPE_AMSTRAD) + && !(models[model].flags & MODEL_AMSTRAD)) + return 0; + if (((type & MOUSE_TYPE_IF_MASK) == MOUSE_TYPE_OLIM24) + && !(models[model].flags & MODEL_OLIM24)) + return 0; + return 1; +} + +static void recalc_vid_list(void* hdlg, int model) +{ + void* h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOVID")); + int c = 0, d = 0; + int found_card = 0; + + wx_sendmessage(h, WX_CB_RESETCONTENT, 0, 0); + wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); + + while (1) + { + char *s = video_card_getname(c); + + if (!s[0]) + break; + + if (video_card_available(c) && gfx_present[video_new_to_old(c)] && + ((models[model].flags & MODEL_PCI) || !(video_card_getdevice(c)->flags & DEVICE_PCI))) + { + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)s); + if (video_new_to_old(c) == gfxcard) + { + wx_sendmessage(h, WX_CB_SETCURSEL, d, 0); + found_card = 1; + } + + d++; + } + + c++; + } + if (!found_card) + wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); + wx_enablewindow(h, models[model].fixed_gfxcard ? FALSE : TRUE); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKVOODOO")); + wx_enablewindow(h, (models[model].flags & MODEL_PCI) ? TRUE : FALSE); + h = wx_getdlgitem(hdlg, WX_ID("IDC_CONFIGUREVOODOO")); + wx_enablewindow(h, (models[model].flags & MODEL_PCI) ? TRUE : FALSE); +} + +static void recalc_snd_list(void* hdlg, int model) +{ + void* h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOSND")); + int c = 0, d = 0; + + wx_sendmessage(h, WX_CB_RESETCONTENT, 0, 0); + + while (1) + { + char *s = sound_card_getname(c); + + if (!s[0]) + break; + + settings_sound_to_list[c] = d; + + if (sound_card_available(c)) + { + device_t *sound_dev = sound_card_getdevice(c); + + if (!sound_dev || (sound_dev->flags & DEVICE_MCA) == (models[model].flags & MODEL_MCA)) + { + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) s); + settings_list_to_sound[d] = c; + d++; + } + } + + c++; + } + wx_sendmessage(h, WX_CB_SETCURSEL, settings_sound_to_list[sound_card_current], 0); +} + +static void recalc_hdd_list(void* hdlg, int model, int use_selected_hdd) +{ + void* h; + + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOHDD")); + + if (models[model].flags & MODEL_HAS_IDE) + { + wx_sendmessage(h, WX_CB_RESETCONTENT, 0, 0); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"Internal IDE"); + wx_enablewindow(h, FALSE); + wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); + } + else + { + char *s; + int valid = 0; + char old_name[16]; + int c, d; + + if (use_selected_hdd) + { + c = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + + if (c != -1 && hdd_names[c]) + strncpy(old_name, hdd_names[c], sizeof(old_name)-1); + else + strcpy(old_name, "none"); + } + else + strncpy(old_name, hdd_controller_name, sizeof(old_name)-1); + + wx_sendmessage(h, WX_CB_RESETCONTENT, 0, 0); + c = d = 0; + while (1) + { + s = hdd_controller_get_name(c); + if (s[0] == 0) + break; + if ((((hdd_controller_get_flags(c) & DEVICE_AT) && !(models[model].flags & MODEL_AT)) || + (hdd_controller_get_flags(c) & DEVICE_MCA) != (models[model].flags & MODEL_MCA)) && c) + { + c++; + continue; + } + if (!hdd_controller_available(c)) + { + c++; + continue; + } + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)s); + hdd_names[d] = hdd_controller_get_internal_name(c); + if (!strcmp(old_name, hdd_names[d])) + { + wx_sendmessage(h, WX_CB_SETCURSEL, d, 0); + valid = 1; + } + c++; + d++; + } + + if (!valid) + wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); + + wx_enablewindow(h, TRUE); + } +} + +int config_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) +{ + char temp_str[256]; + void* h; + int c, d; + int rom, gfx, mem, fpu; + int temp_cpu, temp_cpu_m, temp_model; + int temp_GAMEBLASTER, temp_GUS, temp_SSI2001, temp_voodoo, temp_sound_card_current; + int temp_dynarec; + int cpu_flags; + int temp_fda_type, temp_fdb_type; + int temp_joystick_type; + int cpu_type; + int temp_mouse_type; + int hdd_changed; + + switch (message) + { + case WX_INITDIALOG: + { + pause = 1; + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO1")); + for (c = 0; c < ROM_MAX; c++) + romstolist[c] = 0; + c = d = 0; + while (models[c].id != -1) + { + pclog("INITDIALOG : %i %i %i\n", c, models[c].id, + romspresent[models[c].id]); + if (romspresent[models[c].id]) + { + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) models[c].name); + modeltolist[c] = d; + listtomodel[d] = c; + romstolist[models[c].id] = d; + romstomodel[models[c].id] = c; + d++; + } + c++; + } + wx_sendmessage(h, WX_CB_SETCURSEL, modeltolist[model], 0); + + recalc_vid_list(hdlg, romstomodel[romset]); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOCPUM")); + c = 0; + while (models[romstomodel[romset]].cpu[c].cpus != NULL && c < 4) + { + wx_sendmessage(h, WX_CB_ADDSTRING, 0, + (LONG_PARAM) models[romstomodel[romset]].cpu[c].name); + c++; + } + wx_enablewindow(h, TRUE); + wx_sendmessage(h, WX_CB_SETCURSEL, cpu_manufacturer, 0); + if (c == 1) + wx_enablewindow(h, FALSE); + else + wx_enablewindow(h, TRUE); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO3")); + c = 0; + while (models[romstomodel[romset]].cpu[cpu_manufacturer].cpus[c].cpu_type + != -1) + { + wx_sendmessage(h, WX_CB_ADDSTRING, 0, + (LONG_PARAM) models[romstomodel[romset]].cpu[cpu_manufacturer].cpus[c].name); + c++; + } + wx_enablewindow(h, TRUE); + wx_sendmessage(h, WX_CB_SETCURSEL, cpu, 0); + + recalc_snd_list(hdlg, romstomodel[romset]); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECK3")); + wx_sendmessage(h, WX_BM_SETCHECK, GAMEBLASTER, 0); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKGUS")); + wx_sendmessage(h, WX_BM_SETCHECK, GUS, 0); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKSSI")); + wx_sendmessage(h, WX_BM_SETCHECK, SSI2001, 0); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKSYNC")); + wx_sendmessage(h, WX_BM_SETCHECK, enable_sync, 0); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKVOODOO")); + wx_sendmessage(h, WX_BM_SETCHECK, voodoo_enabled, 0); + + cpu_flags = + models[romstomodel[romset]].cpu[cpu_manufacturer].cpus[cpu].cpu_flags; + h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKDYNAREC")); + if (!(cpu_flags & CPU_SUPPORTS_DYNAREC) || (cpu_flags & CPU_REQUIRES_DYNAREC)) + wx_enablewindow(h, FALSE); + else + wx_enablewindow(h, TRUE); + wx_sendmessage(h, WX_BM_SETCHECK, + ((cpu_flags & CPU_SUPPORTS_DYNAREC) && cpu_use_dynarec) + || (cpu_flags & CPU_REQUIRES_DYNAREC), 0); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOSPD")); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "8-bit"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "Slow 16-bit"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "Fast 16-bit"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "Slow VLB/PCI"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "Mid VLB/PCI"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "Fast VLB/PCI"); + wx_sendmessage(h, WX_CB_SETCURSEL, video_speed, 0); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_MEMSPIN")); + printf("%d\n", models[model].ram_granularity); + wx_sendmessage(h, WX_UDM_SETRANGE, 0, + (models[romstomodel[romset]].min_ram << 16) + | models[romstomodel[romset]].max_ram); + wx_sendmessage(h, WX_UDM_SETINCR, 0, models[model].ram_granularity); + if (!(models[model].flags & MODEL_AT)) + wx_sendmessage(h, WX_UDM_SETPOS, 0, mem_size); + else + wx_sendmessage(h, WX_UDM_SETPOS, 0, mem_size / 1024); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_CONFIGUREMOD")); + if (model_getdevice(model)) + wx_enablewindow(h, TRUE); + else + wx_enablewindow(h, FALSE); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_CONFIGUREVID")); + if (video_card_has_config(video_old_to_new(gfxcard))) + wx_enablewindow(h, TRUE); + else + wx_enablewindow(h, FALSE); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_CONFIGURESND")); + if (sound_card_has_config(sound_card_current)) + wx_enablewindow(h, TRUE); + else + wx_enablewindow(h, FALSE); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBODRA")); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"None"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"5.25\" 360k"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"5.25\" 1.2M"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"5.25\" 1.2M Dual RPM"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"3.5\" 720k"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"3.5\" 1.44M"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"3.5\" 1.44M 3-Mode"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"3.5\" 2.88M"); + wx_sendmessage(h, WX_CB_SETCURSEL, fdd_get_type(0), 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBODRB")); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"None"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"5.25\" 360k"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"5.25\" 1.2M"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"5.25\" 1.2M Dual RPM"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"3.5\" 720k"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"3.5\" 1.44M"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"3.5\" 1.44M 3-Mode"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"3.5\" 2.88M"); + wx_sendmessage(h, WX_CB_SETCURSEL, fdd_get_type(1), 0); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_MB")); + if (models[model].flags & MODEL_AT) + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM) "MB"); + else + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM) "KB"); + + // h = wx_getdlgitem(hdlg, ID("IDC_COMBOJOY")); + // c = 0; + // while (joystick_get_name(c)) + // { + // wx_sendmessage(h, CB_ADDSTRING, 0, joystick_get_name(c)); + // c++; + // } + // wx_enablewindow(h, TRUE); + // wx_sendmessage(h, CB_SETCURSEL, joystick_type, 0); + // + // h = wx_getdlgitem(hdlg, ID("IDC_JOY1")); + // wx_enablewindow(h, (joystick_get_max_joysticks(joystick_type) >= 1) ? TRUE : FALSE); + // h = wx_getdlgitem(hdlg, ID("IDC_JOY2")); + // wx_enablewindow(h, (joystick_get_max_joysticks(joystick_type) >= 2) ? TRUE : FALSE); + // h = wx_getdlgitem(hdlg, ID("IDC_JOY3")); + // wx_enablewindow(h, (joystick_get_max_joysticks(joystick_type) >= 3) ? TRUE : FALSE); + // h = wx_getdlgitem(hdlg, ID("IDC_JOY4")); + // wx_enablewindow(h, (joystick_get_max_joysticks(joystick_type) >= 4) ? TRUE : FALSE); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOWS")); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "System default"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "0 W/S"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "1 W/S"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "2 W/S"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "3 W/S"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "4 W/S"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "5 W/S"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "6 W/S"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "7 W/S"); + wx_sendmessage(h, WX_CB_SETCURSEL, cpu_waitstates, 0); + cpu_type = + models[romstomodel[romset]].cpu[cpu_manufacturer].cpus[cpu].cpu_type; + if ((cpu_type >= CPU_286) && (cpu_type <= CPU_386DX)) + wx_enablewindow(h, TRUE); + else + wx_enablewindow(h, FALSE); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOMOUSE")); + c = d = 0; + while (1) + { + char *s = mouse_get_name(c); + int type; + + if (!s) + break; + + type = mouse_get_type(c); + + settings_mouse_to_list[c] = d; + + if (mouse_valid(type, model)) + { + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) s); + + settings_list_to_mouse[d] = c; + d++; + } + c++; + } + wx_sendmessage(h, WX_CB_SETCURSEL, settings_mouse_to_list[mouse_type], 0); + + recalc_hdd_list(hdlg, romstomodel[romset], 0); + + return TRUE; + } + break; + case WX_COMMAND: + { + if (wParam == wxID_OK) + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO1")); + temp_model = listtomodel[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; + + h = wx_getdlgitem(hdlg, WX_ID("IDC_MEMSPIN")); + int mem = wx_sendmessage(h, WX_UDM_GETPOS, 0, 0); + mem &= ~(models[temp_model].ram_granularity - 1); + if (mem < models[temp_model].min_ram) + mem = models[temp_model].min_ram; + else if (mem > models[temp_model].max_ram) + mem = models[temp_model].max_ram; + if (models[temp_model].flags & MODEL_AT) + mem *= 1024; + + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOVID")); + wx_sendmessage(h, WX_CB_GETLBTEXT, wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0), + (LONG_PARAM) temp_str); + gfx = video_new_to_old(video_card_getid(temp_str)); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOCPUM")); + temp_cpu_m = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO3")); + temp_cpu = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + fpu = (models[temp_model].cpu[temp_cpu_m].cpus[temp_cpu].cpu_type + >= CPU_i486DX) ? 1 : 0; + + h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECK3")); + temp_GAMEBLASTER = wx_sendmessage(h, WX_BM_GETCHECK, 0, 0); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKGUS")); + temp_GUS = wx_sendmessage(h, WX_BM_GETCHECK, 0, 0); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKSSI")); + temp_SSI2001 = wx_sendmessage(h, WX_BM_GETCHECK, 0, 0); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKSYNC")); + enable_sync = wx_sendmessage(h, WX_BM_GETCHECK, 0, 0); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKVOODOO")); + temp_voodoo = wx_sendmessage(h, WX_BM_GETCHECK, 0, 0); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOSND")); + temp_sound_card_current = settings_list_to_sound[wx_sendmessage(h, + WX_CB_GETCURSEL, 0, 0)]; + + h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKDYNAREC")); + temp_dynarec = wx_sendmessage(h, WX_BM_GETCHECK, 0, 0); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBODRA")); + temp_fda_type = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBODRB")); + temp_fdb_type = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + + // h = wx_getdlgitem(hdlg, ID("IDC_COMBOJOY")); + // temp_joystick_type = wx_sendmessage(h, CB_GETCURSEL, 0, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOMOUSE")); + temp_mouse_type = settings_list_to_mouse[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; + + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOHDD")); + c = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + if (hdd_names[c]) + hdd_changed = strncmp(hdd_names[c], hdd_controller_name, sizeof(hdd_controller_name)-1); + + if (temp_model != model || gfx != gfxcard || mem != mem_size || + fpu != hasfpu || temp_GAMEBLASTER != GAMEBLASTER || temp_GUS != GUS || + temp_SSI2001 != SSI2001 || temp_sound_card_current != sound_card_current || + temp_voodoo != voodoo_enabled || temp_dynarec != cpu_use_dynarec || + temp_fda_type != fdd_get_type(0) || temp_fdb_type != fdd_get_type(1) || + temp_mouse_type != mouse_type || hdd_changed) + { + if (!has_been_inited || confirm()) + { + savenvr(); + model = temp_model; + romset = model_getromset(); + gfxcard = gfx; + mem_size = mem; + cpu_manufacturer = temp_cpu_m; + cpu = temp_cpu; + GAMEBLASTER = temp_GAMEBLASTER; + GUS = temp_GUS; + SSI2001 = temp_SSI2001; + sound_card_current = temp_sound_card_current; + voodoo_enabled = temp_voodoo; + cpu_use_dynarec = temp_dynarec; + mouse_type = temp_mouse_type; + + fdd_set_type(0, temp_fda_type); + fdd_set_type(1, temp_fdb_type); + + if (hdd_names[c]) + strncpy(hdd_controller_name, hdd_names[c], sizeof(hdd_controller_name)-1); + else + strcpy(hdd_controller_name, "none"); + + + if (has_been_inited) + { + mem_resize(); + loadbios(); + resetpchard(); + } + } + else + { + wx_enddialog(hdlg, 0); + pause = 0; + return TRUE; + } + } + + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOSPD")); + video_speed = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + + cpu_manufacturer = temp_cpu_m; + cpu = temp_cpu; + cpu_set(); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOWS")); + cpu_waitstates = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + cpu_update_waitstates(); + + if (has_been_inited) + saveconfig(NULL); + + speedchanged(); + +// joystick_type = temp_joystick_type; +// gameport_update_joystick_type(); + + } + if (wParam == wxID_OK || wParam == wxID_CANCEL) + { + wx_enddialog(hdlg, 0); + pause = 0; + return TRUE; + } + else if (wParam == WX_ID("IDC_COMBO1")) + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO1")); + temp_model = listtomodel[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; + + /*Rebuild manufacturer list*/ + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOCPUM")); + temp_cpu_m = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + wx_sendmessage(h, WX_CB_RESETCONTENT, 0, 0); + c = 0; + while (models[temp_model].cpu[c].cpus != NULL && c < 4) + { + wx_sendmessage(h, WX_CB_ADDSTRING, 0, + (LONG_PARAM) models[temp_model].cpu[c].name); + c++; + } + if (temp_cpu_m >= c) + temp_cpu_m = c - 1; + wx_sendmessage(h, WX_CB_SETCURSEL, temp_cpu_m, 0); + if (c == 1) + wx_enablewindow(h, FALSE); + else + wx_enablewindow(h, TRUE); + + /*Rebuild CPU list*/ + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO3")); + temp_cpu = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + wx_sendmessage(h, WX_CB_RESETCONTENT, 0, 0); + c = 0; + while (models[temp_model].cpu[temp_cpu_m].cpus[c].cpu_type != -1) + { + wx_sendmessage(h, WX_CB_ADDSTRING, 0, + (LONG_PARAM) models[temp_model].cpu[temp_cpu_m].cpus[c].name); + c++; + } + if (temp_cpu >= c) + temp_cpu = c - 1; + wx_sendmessage(h, WX_CB_SETCURSEL, temp_cpu, 0); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKDYNAREC")); + temp_dynarec = wx_sendmessage(h, WX_BM_GETCHECK, 0, 0); + + cpu_flags = + models[temp_model].cpu[temp_cpu_m].cpus[temp_cpu].cpu_flags; + h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKDYNAREC")); + if (!(cpu_flags & CPU_SUPPORTS_DYNAREC) || (cpu_flags & CPU_REQUIRES_DYNAREC)) + wx_enablewindow(h, FALSE); + else + wx_enablewindow(h, TRUE); + wx_sendmessage(h, WX_BM_SETCHECK, + ((cpu_flags & CPU_SUPPORTS_DYNAREC) && temp_dynarec) + || (cpu_flags & CPU_REQUIRES_DYNAREC), 0); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_MB")); + if (models[temp_model].flags & MODEL_AT) + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM) "MB"); + else + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM) "KB"); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_MEMSPIN")); + mem = wx_sendmessage(h, WX_UDM_GETPOS, 0, 0); + wx_sendmessage(h, WX_UDM_SETRANGE, 0, + (models[temp_model].min_ram << 16) + | models[temp_model].max_ram); + mem &= ~(models[temp_model].ram_granularity - 1); + if (mem < models[temp_model].min_ram) + mem = models[temp_model].min_ram; + else if (mem > models[temp_model].max_ram) + mem = models[temp_model].max_ram; + wx_sendmessage(h, WX_UDM_SETPOS, 0, mem); + wx_sendmessage(h, WX_UDM_SETINCR, 0, models[temp_model].ram_granularity); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOWS")); + cpu_type = + models[temp_model].cpu[temp_cpu_m].cpus[temp_cpu].cpu_type; + if (cpu_type >= CPU_286 && cpu_type <= CPU_386DX) + wx_enablewindow(h, TRUE); + else + wx_enablewindow(h, FALSE); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_CONFIGUREMOD")); + if (model_getdevice(temp_model)) + wx_enablewindow(h, TRUE); + else + wx_enablewindow(h, FALSE); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOMOUSE")); + temp_mouse_type = settings_list_to_mouse[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; + wx_sendmessage(h, WX_CB_RESETCONTENT, 0, 0); + c = d = 0; + while (1) + { + char *s = mouse_get_name(c); + int type; + + if (!s) + break; + + type = mouse_get_type(c); + settings_mouse_to_list[c] = d; + + if (mouse_valid(type, temp_model)) + { + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) s); + + settings_list_to_mouse[d] = c; + d++; + } + + c++; + } + if (mouse_valid(temp_mouse_type, temp_model)) + wx_sendmessage(h, WX_CB_SETCURSEL, settings_mouse_to_list[temp_mouse_type], 0); + else + wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); + + recalc_vid_list(hdlg, temp_model); + + recalc_hdd_list(hdlg, temp_model, 1); + + recalc_snd_list(hdlg, temp_model); + } + else if (wParam == WX_ID("IDC_COMBOCPUM")) + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO1")); + temp_model = listtomodel[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOCPUM")); + temp_cpu_m = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + + /*Rebuild CPU list*/ + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO3")); + temp_cpu = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + wx_sendmessage(h, WX_CB_RESETCONTENT, 0, 0); + c = 0; + while (models[temp_model].cpu[temp_cpu_m].cpus[c].cpu_type != -1) + { + wx_sendmessage(h, WX_CB_ADDSTRING, 0, + (LONG_PARAM) models[temp_model].cpu[temp_cpu_m].cpus[c].name); + c++; + } + if (temp_cpu >= c) + temp_cpu = c - 1; + wx_sendmessage(h, WX_CB_SETCURSEL, temp_cpu, 0); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKDYNAREC")); + temp_dynarec = wx_sendmessage(h, WX_BM_GETCHECK, 0, 0); + + cpu_flags = + models[temp_model].cpu[temp_cpu_m].cpus[temp_cpu].cpu_flags; + h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKDYNAREC")); + if (!(cpu_flags & CPU_SUPPORTS_DYNAREC) || (cpu_flags & CPU_REQUIRES_DYNAREC)) + wx_enablewindow(h, FALSE); + else + wx_enablewindow(h, TRUE); + wx_sendmessage(h, WX_BM_SETCHECK, + ((cpu_flags & CPU_SUPPORTS_DYNAREC) && temp_dynarec) + || (cpu_flags & CPU_REQUIRES_DYNAREC), 0); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOWS")); + cpu_type = + models[temp_model].cpu[temp_cpu_m].cpus[temp_cpu].cpu_type; + if (cpu_type >= CPU_286 && cpu_type <= CPU_386DX) + wx_enablewindow(h, TRUE); + else + wx_enablewindow(h, FALSE); + + } + else if (wParam == WX_ID("IDC_COMBO3")) + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO1")); + temp_model = listtomodel[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOCPUM")); + temp_cpu_m = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO3")); + temp_cpu = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKDYNAREC")); + temp_dynarec = wx_sendmessage(h, WX_BM_GETCHECK, 0, 0); + + cpu_flags = + models[temp_model].cpu[temp_cpu_m].cpus[temp_cpu].cpu_flags; + h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKDYNAREC")); + if (!(cpu_flags & CPU_SUPPORTS_DYNAREC) || (cpu_flags & CPU_REQUIRES_DYNAREC)) + wx_enablewindow(h, FALSE); + else + wx_enablewindow(h, TRUE); + wx_sendmessage(h, WX_BM_SETCHECK, + ((cpu_flags & CPU_SUPPORTS_DYNAREC) && temp_dynarec) + || (cpu_flags & CPU_REQUIRES_DYNAREC), 0); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOWS")); + cpu_type = + models[temp_model].cpu[temp_cpu_m].cpus[temp_cpu].cpu_type; + if (cpu_type >= CPU_286 && cpu_type <= CPU_386DX) + wx_enablewindow(h, TRUE); + else + wx_enablewindow(h, FALSE); + } + else if (wParam == WX_ID("IDC_CONFIGUREMOD")) + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO1")); + temp_model = listtomodel[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; + + deviceconfig_open(hdlg, (void *) model_getdevice(temp_model)); + } + else if (wParam == WX_ID("IDC_CONFIGUREVID")) + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOVID")); + wx_sendmessage(h, WX_CB_GETLBTEXT, wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0), + (LONG_PARAM) temp_str); + + deviceconfig_open(hdlg, + (void *) video_card_getdevice(video_card_getid(temp_str))); + } + else if (wParam == WX_ID("IDC_COMBOVID")) + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOVID")); + wx_sendmessage(h, WX_CB_GETLBTEXT, wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0), + (LONG_PARAM) temp_str); + gfx = video_card_getid(temp_str); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_CONFIGUREVID")); + if (video_card_has_config(gfx)) + wx_enablewindow(h, TRUE); + else + wx_enablewindow(h, FALSE); + } + else if (wParam == WX_ID("IDC_CONFIGURESND")) + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOSND")); + temp_sound_card_current = settings_list_to_sound[wx_sendmessage(h, + WX_CB_GETCURSEL, 0, 0)]; + + deviceconfig_open(hdlg, + (void *) sound_card_getdevice(temp_sound_card_current)); + } + else if (wParam == WX_ID("IDC_COMBOSND")) + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOSND")); + temp_sound_card_current = settings_list_to_sound[wx_sendmessage(h, + WX_CB_GETCURSEL, 0, 0)]; + + h = wx_getdlgitem(hdlg, WX_ID("IDC_CONFIGURESND")); + if (sound_card_has_config(temp_sound_card_current)) + wx_enablewindow(h, TRUE); + else + wx_enablewindow(h, FALSE); + } + else if (wParam == WX_ID("IDC_CONFIGUREVOODOO")) + { + deviceconfig_open(hdlg, (void *) &voodoo_device); + } + // + // case IDC_COMBOJOY: + // if (HIWORD(wParam) == CBN_SELCHANGE) { + // h = wx_getdlgitem(hdlg, IDC_COMBOJOY); + // temp_joystick_type = wx_sendmessage(h, CB_GETCURSEL, 0, 0); + // + // h = wx_getdlgitem(hdlg, IDC_JOY1); + // wx_enablewindow(h, + // (joystick_get_max_joysticks(temp_joystick_type) >= 1) ? + // TRUE : FALSE); + // h = wx_getdlgitem(hdlg, IDC_JOY2); + // wx_enablewindow(h, + // (joystick_get_max_joysticks(temp_joystick_type) >= 2) ? + // TRUE : FALSE); + // h = wx_getdlgitem(hdlg, IDC_JOY3); + // wx_enablewindow(h, + // (joystick_get_max_joysticks(temp_joystick_type) >= 3) ? + // TRUE : FALSE); + // h = wx_getdlgitem(hdlg, IDC_JOY4); + // wx_enablewindow(h, + // (joystick_get_max_joysticks(temp_joystick_type) >= 4) ? + // TRUE : FALSE); + // } + // break; + // + // case IDC_JOY1: + // h = wx_getdlgitem(hdlg, IDC_COMBOJOY); + // temp_joystick_type = wx_sendmessage(h, CB_GETCURSEL, 0, 0); + // joystickconfig_open(hdlg, 0, temp_joystick_type); + // break; + // case IDC_JOY2: + // h = wx_getdlgitem(hdlg, IDC_COMBOJOY); + // temp_joystick_type = wx_sendmessage(h, CB_GETCURSEL, 0, 0); + // joystickconfig_open(hdlg, 1, temp_joystick_type); + // break; + // case IDC_JOY3: + // h = wx_getdlgitem(hdlg, IDC_COMBOJOY); + // temp_joystick_type = wx_sendmessage(h, CB_GETCURSEL, 0, 0); + // joystickconfig_open(hdlg, 2, temp_joystick_type); + // break; + // case IDC_JOY4: + // h = wx_getdlgitem(hdlg, IDC_COMBOJOY); + // temp_joystick_type = wx_sendmessage(h, CB_GETCURSEL, 0, 0); + // joystickconfig_open(hdlg, 3, temp_joystick_type); + // break; + return 0; + } + } +} + +void config_open(void* hwnd) +{ + wx_dialogbox(hwnd, "ConfigureDlg", config_dlgproc); +} diff --git a/src/wx-config_sel.c b/src/wx-config_sel.c new file mode 100644 index 0000000..0025bb0 --- /dev/null +++ b/src/wx-config_sel.c @@ -0,0 +1,249 @@ +#include "ibm.h" +#include "config.h" +#include "wx-utils.h" +#include "wx-sdl2.h" + +extern void config_open(void* hwnd); +extern void hdconf_open(void* hwnd); + +static void config_list_update(void* hdlg) +{ + char s[512]; + int num, c; + void* h; + + strcpy(s, pcempath); + put_backslash(s); + strcat(s, "configs/*.cfg"); + pclog("Dir %s\n", s); + + wx_dlgdirlist(hdlg, s, WX_ID("IDC_LIST"), 0, 0); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_LIST")); + num = wx_sendmessage(h, WX_LB_GETCOUNT, 0, 0); + + for (c = 0; c < num; c++) + { + char *ext; + + wx_sendmessage(h, WX_LB_GETTEXT, c, (LONG_PARAM)s); + ext = get_extension(s); + if (ext && ext[0]) + { + ext--; + *ext = 0; + } + + wx_sendmessage(h, WX_LB_DELETESTRING, c, 0); + wx_sendmessage(h, WX_LB_INSERTSTRING, c, (LONG_PARAM)s); + } +} + +static int config_selection_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) +{ + //void* h; + + switch (message) + { + case WX_INITDIALOG: + { + // pause = 1; + config_list_update(hdlg); + // h = wx_getdlgitem(hdlg, IDC_LIST); + // wx_sendmessage(h, LB_ADDSTRING, 0, (LONG_PARAM)(LPCSTR)"AAA"); + // wx_sendmessage(h, LB_ADDSTRING, 0, (LONG_PARAM)(LPCSTR)"BBB"); + return TRUE; + } + case WX_COMMAND: + { + if (wParam == wxID_OK) + { + char s[512]; + + int ret = wx_dlgdirselectex(hdlg, (LONG_PARAM)s, 512, WX_ID("IDC_LIST")); + + pclog("wx_dlgdirselectex returned %i %s\n", ret, s); + if (s[0]) + { + char cfg[512]; + + strcpy(cfg, pcempath); + put_backslash(cfg); + strcat(cfg, "configs/"); + strcat(cfg, s); + strcat(cfg, "cfg"); +// sprintf(cfg, "%s\\configs\\%scfg", pcempath, s); + pclog("Config name %s\n", cfg); + + strcpy(config_file_default, cfg); + + wx_enddialog(hdlg, 1); +// pause = 0; + return TRUE; + } + return FALSE; + } + else if (wParam == wxID_CANCEL) + { + wx_enddialog(hdlg, 0); + // pause = 0; + return TRUE; + } + else if (wParam == WX_ID("IDC_NEW")) + { + char name[64]; + +// if (!getsfile(hdlg, "Configuration (*.cfg)|*.cfg|All files (*.*)|*.*", "", s, "cfg")) + if (wx_textentrydialog(hdlg, "Enter name:", "New config", 0, 1, 64, (LONG_PARAM)name)) + { + strcpy(openfilestring, pcempath); + put_backslash(openfilestring); + strcat(openfilestring, "configs/"); + strcat(openfilestring, name); + strcat(openfilestring, ".cfg"); + + pclog("Config %s\n", openfilestring); + + config_open(hdlg); + + saveconfig(openfilestring); + + config_list_update(hdlg); + } + + return TRUE; + } + else if (wParam == WX_ID("IDC_CONFIG")) + { + char s[512]; + + int ret = wx_dlgdirselectex(hdlg, (LONG_PARAM)s, 512, WX_ID("IDC_LIST")); + + pclog("wx_dlgdirselectex returned %i %s\n", ret, s); + if (s[0]) + { + char cfg[512]; + + strcpy(cfg, pcempath); + put_backslash(cfg); + strcat(cfg, "configs/"); + strcat(cfg, s); + strcat(cfg, "cfg"); + pclog("Config name %s\n", cfg); + + loadconfig(cfg); + config_open(hdlg); + saveconfig(cfg); + } + + return TRUE; + } + else if (wParam == WX_ID("IDC_HDCONF")) + { + char s[512]; + + int ret = wx_dlgdirselectex(hdlg, (LONG_PARAM)s, 512, WX_ID("IDC_LIST")); + + pclog("wx_dlgdirselectex returned %i %s\n", ret, s); + if (s[0]) + { + char cfg[512]; + + strcpy(cfg, pcempath); + put_backslash(cfg); + strcat(cfg, "configs/"); + strcat(cfg, s); + strcat(cfg, "cfg"); + pclog("Config name %s\n", cfg); + + loadconfig(cfg); + hdconf_open(hdlg); + saveconfig(cfg); + } + + return TRUE; + } + else if (wParam == WX_ID("IDC_RENAME")) + { + char name[64]; + char old_name[64]; + void* h; + int c; + + h = wx_getdlgitem(hdlg, WX_ID("IDC_LIST")); + c = wx_sendmessage(h, WX_LB_GETCURSEL, 0, 0); + if (c >= 0) + { + wx_sendmessage(h, WX_LB_GETTEXT, c, (LONG_PARAM)old_name); + + if (wx_textentrydialog(hdlg, "Enter name:", "New name", old_name, 1, 64, (LONG_PARAM)name)) + { + char old_path[512]; + char new_path[512]; + + strcpy(old_path, pcempath); + put_backslash(old_path); + strcat(old_path, "configs/"); + strcat(old_path, old_name); + strcat(old_path, ".cfg"); + + strcpy(new_path, pcempath); + put_backslash(new_path); + strcat(new_path, "configs/"); + strcat(new_path, name); + strcat(new_path, ".cfg"); + + pclog("Rename %s to %s\n", old_path, new_path); + + rename(old_path, new_path); + + config_list_update(hdlg); + } + } + + return TRUE; + } + else if (wParam == WX_ID("IDC_DELETE")) + { + char name[64]; + void* h; + int c; + h = wx_getdlgitem(hdlg, WX_ID("IDC_LIST")); + c = wx_sendmessage(h, WX_LB_GETCURSEL, 0, 0); + if (c >= 0) + { + char s[512]; + wx_sendmessage(h, WX_LB_GETTEXT, c, (LONG_PARAM)name); + sprintf(s, "Do you want to delete \"%s\"?", name); + if (wx_messagebox(NULL, s, "PCem", WX_MB_OKCANCEL) == WX_IDOK) + { + strcpy(s, pcempath); + put_backslash(s); + strcat(s, "configs/"); + strcat(s, name); + strcat(s, ".cfg"); + + remove(s); + + config_list_update(hdlg); + } + } + } + } + break; + } + return FALSE; +} + +int config_selection_open(void* hwnd, int inited) +{ + int ret; + + has_been_inited = inited; + + ret = wx_dialogbox(hwnd, "ConfigureSelectionDlg", config_selection_dlgproc); + + has_been_inited = 1; + + return ret; +} diff --git a/src/wx-deviceconfig.cc b/src/wx-deviceconfig.cc new file mode 100644 index 0000000..3a280ce --- /dev/null +++ b/src/wx-deviceconfig.cc @@ -0,0 +1,268 @@ +#include "wx-deviceconfig.h" + +#include "wx-utils.h" +#include "wx/wxprec.h" + +#include "wx-dialogbox.h" + +#ifndef WX_PRECOMP +#include "wx/wx.h" +#endif + +#include "wx/xrc/xmlres.h" + +extern "C" +{ + #include "config.h" + void saveconfig(char*); + void resetpchard(); + int deviceconfig_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam); + device_t *config_device; + int confirm(); +} +#define IDC_CONFIG_BASE 1000 + + +int deviceconfig_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) { + switch (message) { + case WX_INITDIALOG: { + int id = IDC_CONFIG_BASE; + device_config_t *config = config_device->config; + int c; + + while (config->type != -1) { + device_config_selection_t *selection = config->selection; + void* h = 0; + int val_int; + char *val_string; + int num; + char s[80]; + + switch (config->type) { + case CONFIG_BINARY: + h = wx_getdlgitem(hdlg, id); + val_int = config_get_int(CFG_MACHINE, config_device->name, config->name, + config->default_int); + + wx_sendmessage(h, WX_BM_SETCHECK, val_int, 0); + + id++; + break; + + case CONFIG_SELECTION: + h = wx_getdlgitem(hdlg, id+1); + val_int = config_get_int(CFG_MACHINE, config_device->name, config->name, + config->default_int); + + c = 0; + while (selection->description[0]) { + wx_sendmessage(h, WX_CB_ADDSTRING, 0, + (LONG_PARAM) selection->description); + if (val_int == selection->value) + wx_sendmessage(h, WX_CB_SETCURSEL, c, 0); + selection++; + c++; + } + + id += 2; + break; + + case CONFIG_MIDI: + // midi ignored +// val_int = config_get_int(CFG_MACHINE, NULL, config->name, config->default_int); +// +// num = midi_get_num_devs(); +// for (c = 0; c < num; c++) +// { +// midi_get_dev_name(c, s); +// SendMessage(h, CB_ADDSTRING, 0, (LONG_PARAM)s); +// if (val_int == c) +// SendMessage(h, CB_SETCURSEL, c, 0); +// } +// +// id += 2; + break; + } + config++; + } + } + return TRUE; + + case WX_COMMAND: + switch (wParam) { + case wxID_OK: { + int id = IDC_CONFIG_BASE; + device_config_t *config = config_device->config; + int c; + int changed = 0; + + while (config->type != -1) { + device_config_selection_t *selection = config->selection; + void* h = 0; + int val_int; + char *val_string; + + switch (config->type) { + case CONFIG_BINARY: + h = wx_getdlgitem(hdlg, id); + val_int = config_get_int(CFG_MACHINE, config_device->name, config->name, + config->default_int); + + if (val_int != wx_sendmessage(h, WX_BM_GETCHECK, 0, 0)) + changed = 1; + + id++; + break; + + case CONFIG_SELECTION: + h = wx_getdlgitem(hdlg, id+1); + val_int = config_get_int(CFG_MACHINE, config_device->name, config->name, + config->default_int); + + c = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + + for (; c > 0; c--) + selection++; + + if (val_int != selection->value) + changed = 1; + + id += 2; + break; + + case CONFIG_MIDI: + // midi ignored +// val_int = config_get_int(CFG_MACHINE, NULL, config->name, +// config->default_int); +// +// c = SendMessage(h, CB_GETCURSEL, 0, 0); +// +// if (val_int != c) +// changed = 1; +// +// id += 2; + break; + } + config++; + } + + if (!changed) { + wx_enddialog(hdlg, 0); + return TRUE; + } + + if (has_been_inited && !confirm()) { + wx_enddialog(hdlg, 0); + return TRUE; + } + + id = IDC_CONFIG_BASE; + config = config_device->config; + + while (config->type != -1) { + device_config_selection_t *selection = config->selection; + void* h = 0; + int val_int; + char *val_string; + + switch (config->type) { + case CONFIG_BINARY: + h = wx_getdlgitem(hdlg, id); + config_set_int(CFG_MACHINE, config_device->name, config->name, + wx_sendmessage(h, WX_BM_GETCHECK, 0, 0)); + + id++; + break; + + case CONFIG_SELECTION: + h = wx_getdlgitem(hdlg, id+1); + c = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + for (; c > 0; c--) + selection++; + config_set_int(CFG_MACHINE, config_device->name, config->name, + selection->value); + + id += 2; + break; + + case CONFIG_MIDI: + // midi ignored +// c = SendMessage(h, CB_GETCURSEL, 0, 0); +// config_set_int(CFG_MACHINE, NULL, config->name, c); +// +// id += 2; + break; + } + config++; + } + + if (has_been_inited) + { + saveconfig(NULL); + resetpchard(); + } + + wx_enddialog(hdlg, 0); + return TRUE; + } + case wxID_CANCEL: + wx_enddialog(hdlg, 0); + return TRUE; + } + break; + } + return FALSE; +} + + + +void deviceconfig_open(void* hwnd, device_t *device) { + config_device = device; + + PCemDialogBox dialog((wxWindow*) hwnd, deviceconfig_dlgproc); +// dialog.SetWindowStyle(wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER); + + device_config_t *config = device->config; + + dialog.SetTitle("Device Configuration"); + + wxBoxSizer* root = new wxBoxSizer(wxVERTICAL); + dialog.SetSizer(root); + + wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL); + root->Add(sizer, 0, wxALL, 5); + + int id = IDC_CONFIG_BASE; + + while (config->type != -1) { + switch (config->type) { + case CONFIG_BINARY: + sizer->Add(new wxCheckBox(&dialog, id++, config->description), 0, wxALL); + break; + + case CONFIG_SELECTION: { + sizer->Add(new wxStaticText(&dialog, id++, config->description), 0, wxALL); + wxComboBox* cb = new wxComboBox(&dialog, id++); + cb->SetEditable(false); + sizer->Add(cb, 0, wxALL); + } break; + case CONFIG_MIDI: + // midi ignored + break; + } + + config++; + } + + wxBoxSizer* okCancelSizer = new wxBoxSizer(wxHORIZONTAL); + + okCancelSizer->Add(new wxButton(&dialog, wxID_OK)); + okCancelSizer->Add(new wxButton(&dialog, wxID_CANCEL)); + + sizer->Add(okCancelSizer); + + dialog.Fit(); + dialog.OnInit(); + dialog.ShowModal(); + dialog.Destroy(); +} diff --git a/src/wx-deviceconfig.h b/src/wx-deviceconfig.h new file mode 100644 index 0000000..5a591df --- /dev/null +++ b/src/wx-deviceconfig.h @@ -0,0 +1,10 @@ +#ifndef SRC_WX_DEVICECONFIG_H_ +#define SRC_WX_DEVICECONFIG_H_ + +extern "C" { +#include +#include "device.h" +void deviceconfig_open(void* hwnd, device_t *device); +} + +#endif /* SRC_WX_DEVICECONFIG_H_ */ diff --git a/src/wx-dialogbox.cc b/src/wx-dialogbox.cc new file mode 100644 index 0000000..7b1fa7f --- /dev/null +++ b/src/wx-dialogbox.cc @@ -0,0 +1,45 @@ +#include "wx-dialogbox.h" + +#include + +#ifndef WX_PRECOMP +#include +#endif + +#include + +BEGIN_EVENT_TABLE(PCemDialogBox, wxDialog) END_EVENT_TABLE() + +PCemDialogBox::PCemDialogBox(wxWindow* parent, int (*callback)(void* window, int message, INT_PARAM param1, LONG_PARAM param2)) : + wxDialog(parent, -1, "No title") +{ + this->callback = callback; +} + +PCemDialogBox::PCemDialogBox(wxWindow* parent, const char* name, int (*callback)(void* window, int message, INT_PARAM param1, LONG_PARAM param2)) +{ + wxXmlResource::Get()->LoadDialog(this, parent, name); + this->callback = callback; +} + +void PCemDialogBox::OnInit() +{ + if (callback) + { + callback(this, WX_INITDIALOG, 0, 0); + Bind(wxEVT_BUTTON, &PCemDialogBox::OnCommand, this); + Bind(wxEVT_TEXT, &PCemDialogBox::OnCommand, this); + Bind(wxEVT_COMBOBOX, &PCemDialogBox::OnCommand, this); + } + + wxWindow* root = FindWindow(XRCID("ROOT_PANEL")); + if (root) + root->Fit(); + Fit(); +} + +void PCemDialogBox::OnCommand(wxCommandEvent& event) +{ + callback(this, WX_COMMAND, event.GetId(), 0); +} + diff --git a/src/wx-dialogbox.h b/src/wx-dialogbox.h new file mode 100644 index 0000000..ca3ee4d --- /dev/null +++ b/src/wx-dialogbox.h @@ -0,0 +1,21 @@ +#ifndef SRC_WX_PCEMDIALOGBOX_H_ +#define SRC_WX_PCEMDIALOGBOX_H_ + +#include "wx/dialog.h" + +#include "wx-utils.h" + +class PCemDialogBox: public wxDialog { +public: + PCemDialogBox(wxWindow* parent, int(*callback)(void* window, int message, INT_PARAM param1, LONG_PARAM param2)); + PCemDialogBox(wxWindow* parent, const char* name, int(*callback)(void* window, int message, INT_PARAM param1, LONG_PARAM param2)); + virtual ~PCemDialogBox() {} + void OnInit(); +private: + void OnCommand(wxCommandEvent &event); + int(*callback)(void* window, int message, INT_PARAM param1, LONG_PARAM param2); + + DECLARE_EVENT_TABLE() +}; + +#endif /* SRC_WX_PCEMDIALOGBOX_H_ */ diff --git a/src/wx-display.h b/src/wx-display.h new file mode 100644 index 0000000..4753579 --- /dev/null +++ b/src/wx-display.h @@ -0,0 +1,36 @@ +#ifndef SRC_WX_DISPLAY_H_ +#define SRC_WX_DISPLAY_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +int display_init(); +void display_close(); +void display_start(void* hwnd); +void display_stop(); +void display_resize(int width, int height); + +#ifdef __cplusplus +} +#endif + +extern int mousecapture; + +extern int video_scale_mode; +extern int video_vsync; +extern int video_focus_dim; +extern int video_fullscreen_mode; + +extern int win_doresize; + +extern int window_doreset; +extern int renderer_doreset; +extern int window_dofullscreen; +extern int window_dowindowed; +extern int window_doremember; +extern int window_doinputgrab; +extern int window_doinputrelease; +extern int window_dotogglefullscreen; + +#endif /* SRC_WX_DISPLAY_H_ */ diff --git a/src/wx-main.cc b/src/wx-main.cc new file mode 100644 index 0000000..e5790dc --- /dev/null +++ b/src/wx-main.cc @@ -0,0 +1,15 @@ +#include "wx-app.h" + +extern "C" +{ +int pc_main(int, char**); +} + +int main(int argc, char **argv) +{ + pc_main(argc, argv); + + wxApp::SetInstance(new App()); + wxEntry(argc, argv); +} + diff --git a/src/wx-resources.cpp b/src/wx-resources.cpp new file mode 100644 index 0000000..645bb0a --- /dev/null +++ b/src/wx-resources.cpp @@ -0,0 +1,3010 @@ +// +// This file was automatically generated by wxrc, do not edit by hand. +// + +#include + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +#include +#include +#include +#include + +#if wxCHECK_VERSION(2,8,5) && wxABI_VERSION >= 20805 + #define XRC_ADD_FILE(name, data, size, mime) \ + wxMemoryFSHandler::AddFileWithMimeType(name, data, size, mime) +#else + #define XRC_ADD_FILE(name, data, size, mime) \ + wxMemoryFSHandler::AddFile(name, data, size) +#endif + +static size_t xml_res_size_0 = 346; +static unsigned char xml_res_file_0[] = { +137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,4,0,0, +0,181,250,55,234,0,0,0,4,103,65,77,65,0,0,175,200,55,5,138,233,0,0,0,25, +116,69,88,116,83,111,102,116,119,97,114,101,0,65,100,111,98,101,32,73,109, +97,103,101,82,101,97,100,121,113,201,101,60,0,0,0,236,73,68,65,84,40,207, +165,145,61,74,4,65,16,133,191,94,123,214,192,31,132,197,64,23,4,51,111, +177,48,147,120,11,79,224,9,4,207,227,13,156,100,135,185,129,193,70,3,155, +8,6,130,152,8,130,83,221,213,101,208,189,131,145,201,86,80,73,189,247,190, +162,202,25,255,215,140,125,5,30,96,88,107,173,68,2,129,128,32,8,35,210, +221,53,224,140,97,53,239,207,145,201,147,183,170,232,121,109,238,59,15, +241,241,140,119,14,1,43,67,227,141,83,174,25,30,232,220,102,53,239,23,124, +149,224,136,225,56,160,226,132,35,90,182,141,123,89,95,212,134,96,37,220, +166,94,241,201,83,231,133,111,62,24,49,18,74,194,72,36,20,195,115,140,224, +165,6,65,217,224,152,21,175,145,184,66,89,34,181,31,137,68,20,197,145,10, +102,151,17,8,248,17,69,73,220,144,72,216,31,140,145,178,96,129,78,193,217, +191,3,93,18,241,63,237,243,173,48,230,219,33,72,185,103,198,90,235,246, +254,230,47,16,30,136,4,54,25,76,145,0,0,0,0,73,69,78,68,174,66,96,130}; + +static size_t xml_res_size_1 = 620; +static unsigned char xml_res_file_1[] = { +137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0, +0,31,243,255,97,0,0,0,4,103,65,77,65,0,0,175,200,55,5,138,233,0,0,0,25, +116,69,88,116,83,111,102,116,119,97,114,101,0,65,100,111,98,101,32,73,109, +97,103,101,82,101,97,100,121,113,201,101,60,0,0,1,254,73,68,65,84,24,25, +5,193,61,139,93,85,24,6,208,181,207,236,59,67,130,146,168,96,132,68,68, +3,10,86,1,101,32,241,163,21,127,130,133,104,145,42,66,208,34,165,54,86, +86,34,162,8,99,161,216,10,118,130,98,97,149,34,22,22,193,78,197,66,180, +18,197,12,222,153,123,246,126,31,215,106,135,111,124,247,22,30,195,243, +120,2,247,145,142,38,192,222,210,44,75,147,148,42,255,236,111,252,188,61, +93,223,187,243,241,203,95,118,60,125,116,235,218,117,154,167,46,30,8,82, +177,27,177,91,203,222,210,156,57,88,180,198,241,182,28,159,204,115,191, +254,121,124,229,243,111,126,249,228,240,198,215,231,22,188,32,124,117,231, +95,21,146,184,249,225,15,170,66,107,54,189,89,150,102,55,98,187,150,81, +218,180,244,215,94,186,252,208,153,131,253,143,22,60,18,84,197,58,202,58, +2,214,138,190,199,166,55,85,177,221,149,117,132,196,247,119,239,217,223, +236,217,158,142,253,142,179,163,130,216,238,10,44,173,17,54,125,209,52, +39,107,217,158,70,37,42,84,226,143,191,78,72,90,39,125,38,18,78,71,192, +219,175,95,177,233,139,190,176,206,248,239,180,140,42,85,68,164,202,58, +166,164,116,180,154,72,188,251,217,143,90,107,150,198,166,47,26,70,197, +24,37,0,56,127,254,65,235,216,35,209,133,74,169,154,30,190,112,145,70,19, +2,81,161,170,36,81,137,170,162,53,235,58,72,233,48,39,9,208,18,160,81,69, +18,68,130,68,75,36,101,93,155,164,116,24,179,16,16,209,52,18,73,164,74, +68,18,85,83,42,162,156,174,33,165,19,179,66,120,231,149,75,0,0,0,0,224, +214,209,79,198,136,164,244,165,53,179,136,72,248,224,246,117,0,0,0,112, +243,234,145,57,135,221,8,137,174,81,21,13,112,237,210,171,0,0,0,0,106,150, +185,6,165,39,201,172,52,2,110,255,254,5,0,0,0,120,246,209,23,205,57,173, +51,146,164,87,252,182,27,245,248,51,151,207,106,141,55,159,251,20,0,0,0, +192,133,251,203,156,129,191,219,225,141,111,223,79,242,36,185,42,121,128, +146,132,148,164,72,73,138,20,137,36,72,200,61,109,185,251,63,33,124,110, +139,109,16,176,162,0,0,0,0,73,69,78,68,174,66,96,130}; + +static size_t xml_res_size_2 = 673; +static unsigned char xml_res_file_2[] = { +137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0, +0,31,243,255,97,0,0,0,4,103,65,77,65,0,0,175,200,55,5,138,233,0,0,0,25, +116,69,88,116,83,111,102,116,119,97,114,101,0,65,100,111,98,101,32,73,109, +97,103,101,82,101,97,100,121,113,201,101,60,0,0,2,51,73,68,65,84,56,203, +133,147,91,110,218,80,16,134,179,129,172,160,27,137,212,141,116,71,221, +0,50,74,251,210,42,137,4,129,230,129,72,17,133,92,154,128,66,67,49,96,32, +52,220,66,76,205,197,177,9,190,128,1,131,253,119,142,129,134,164,84,69, +250,176,229,153,249,207,156,185,108,1,216,90,231,221,251,232,91,194,71, +100,9,133,24,16,21,194,207,108,175,253,215,3,183,9,142,176,191,242,34,74, +45,29,77,117,138,182,57,131,212,31,34,158,109,129,217,150,62,219,47,4,150, +193,209,131,139,10,230,142,11,73,7,142,210,6,190,20,12,124,239,79,49,38, +39,135,96,54,230,195,124,87,34,43,1,142,25,52,27,222,207,36,239,189,75, +13,159,174,159,32,104,14,92,250,70,15,232,206,194,190,20,225,60,1,122,217, +33,28,177,111,99,47,165,162,170,46,156,78,248,49,252,103,42,234,67,120, +25,244,232,207,164,231,148,225,186,76,192,97,177,222,233,49,186,223,73, +65,199,199,75,5,187,23,10,138,18,80,235,1,169,170,73,215,153,160,63,1,100, +18,208,41,149,193,28,48,136,216,162,38,28,19,200,11,162,134,207,201,71, +18,144,225,255,38,35,146,213,113,152,168,51,135,46,35,156,108,192,164,160, +54,101,83,125,2,132,246,28,130,168,51,123,158,9,168,183,210,136,78,150, +177,75,193,31,72,228,166,97,50,99,135,120,179,164,83,233,77,16,161,162, +134,50,154,71,81,178,152,143,250,71,192,127,46,131,59,237,193,119,218,69, +250,254,111,129,226,47,11,33,94,199,254,205,128,232,163,176,38,144,207, +63,12,192,157,119,189,224,32,169,87,85,23,44,237,213,21,14,19,13,36,27, +44,131,33,142,75,22,162,229,17,114,205,231,43,120,69,188,190,31,67,144, +129,150,5,52,12,66,3,42,143,19,148,58,19,164,154,51,132,114,35,236,211, +108,4,50,38,18,36,182,94,68,175,141,54,181,70,166,30,221,13,0,190,11,92, +137,64,188,62,199,241,237,20,225,188,133,0,111,225,224,135,137,32,111,146, +176,253,220,198,245,65,82,168,93,130,2,36,40,56,86,115,17,41,207,16,22, +198,8,102,23,193,1,222,64,90,180,95,14,210,235,81,150,12,23,57,202,32,94, +155,35,82,92,156,126,36,208,46,220,89,248,41,219,155,71,121,211,50,101, +31,116,148,187,83,175,6,25,42,8,251,246,207,101,250,207,58,43,203,119,223, +166,117,254,13,152,46,30,143,29,240,166,162,0,0,0,0,73,69,78,68,174,66, +96,130}; + +static size_t xml_res_size_3 = 758; +static unsigned char xml_res_file_3[] = { +137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,24,0,0,0,24,8,6,0,0, +0,224,119,61,248,0,0,0,6,98,75,71,68,0,255,0,255,0,255,160,189,167,147, +0,0,0,9,112,72,89,115,0,0,13,215,0,0,13,215,1,66,40,155,120,0,0,0,7,116, +73,77,69,7,225,5,27,16,40,7,129,43,165,16,0,0,2,131,73,68,65,84,72,199, +173,150,75,72,85,81,20,134,191,181,207,193,30,100,20,133,72,138,40,74,88, +148,98,23,172,73,154,26,145,41,105,13,170,91,87,16,130,102,61,104,208,80, +176,73,163,232,49,8,10,132,64,203,50,172,124,21,36,233,176,129,248,200, +66,169,244,38,248,106,16,22,106,131,186,247,156,213,68,73,229,30,189,222, +252,135,251,44,190,181,215,218,255,62,107,11,203,200,215,222,144,226,154, +112,153,8,37,64,42,144,60,247,105,12,24,65,181,213,178,77,83,87,190,127, +212,139,33,145,22,179,223,54,36,89,226,84,129,158,7,44,150,151,139,72,163, +11,215,250,10,252,35,43,38,240,117,62,46,87,165,22,216,196,234,52,163,72, +160,183,208,223,188,112,209,44,134,63,186,172,74,99,12,112,128,120,65,95, +248,58,234,47,69,172,96,110,231,141,75,147,198,32,87,145,19,243,149,8,64, +86,103,93,178,173,102,48,198,157,71,110,87,88,50,123,143,248,39,12,128, +173,230,186,23,252,66,234,30,106,246,29,38,51,126,235,170,218,133,165,213, +0,226,107,111,72,81,43,28,244,114,203,205,189,7,57,180,61,25,87,149,151, +147,195,220,25,238,99,54,28,138,38,137,19,22,55,213,96,57,229,81,88,17, +35,194,201,29,25,60,223,95,74,105,98,90,100,127,47,150,101,99,149,25,69, +139,87,83,251,182,184,245,84,239,58,192,253,156,34,210,54,110,94,54,86, +85,143,25,144,140,88,78,209,183,37,129,39,185,197,92,76,207,38,206,88,94, +183,56,221,128,38,198,106,21,91,12,149,41,187,105,200,45,38,97,221,134, +72,33,73,102,45,60,25,103,44,44,137,136,114,109,129,9,133,157,177,128,29, +85,158,141,127,225,222,215,126,126,69,118,214,132,173,16,36,134,4,3,51, +83,220,248,212,197,192,204,148,247,33,67,208,70,181,13,145,163,209,130, +167,67,127,120,48,242,145,167,227,159,113,85,151,183,182,106,171,109,217, +166,201,113,244,246,74,119,65,129,87,223,70,184,53,212,195,143,208,239, +104,246,18,14,25,109,49,93,249,254,81,65,30,122,69,13,205,254,228,195,244, +119,42,187,223,80,53,248,46,90,56,64,77,127,65,96,76,254,13,152,240,32, +16,191,70,63,187,105,177,157,204,238,188,138,73,3,240,190,232,212,184,170, +57,13,56,107,0,119,81,2,221,121,21,147,139,6,78,111,209,153,215,130,92, +5,220,255,154,5,202,149,158,162,179,45,158,35,51,167,163,254,184,160,117, +49,180,107,26,113,207,245,20,4,90,61,71,38,64,111,161,191,89,109,59,93, +209,187,64,56,170,150,160,181,98,59,153,75,225,158,175,138,121,101,117, +214,37,219,88,101,224,150,160,146,182,240,217,162,16,52,208,22,18,183,185, +191,32,48,230,197,248,11,86,228,238,84,203,121,117,202,0,0,0,0,73,69,78, +68,174,66,96,130}; + +static size_t xml_res_size_4 = 635; +static unsigned char xml_res_file_4[] = { +137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,24,0,0,0,24,8,6,0,0, +0,224,119,61,248,0,0,0,6,98,75,71,68,0,255,0,255,0,255,160,189,167,147, +0,0,0,9,112,72,89,115,0,0,13,215,0,0,13,215,1,66,40,155,120,0,0,0,7,116, +73,77,69,7,225,5,27,16,39,59,41,220,197,88,0,0,2,8,73,68,65,84,72,199,181, +150,79,107,19,81,20,197,127,247,77,42,74,213,77,161,105,59,67,168,180,139, +172,252,12,110,107,193,68,67,43,65,17,164,184,85,113,225,170,8,250,17,92, +43,8,117,211,148,40,77,82,220,250,17,220,117,33,132,66,39,211,70,234,194, +74,241,79,230,205,117,209,36,152,191,198,208,57,48,139,119,223,155,115, +207,59,92,238,125,194,16,4,133,185,148,138,205,160,178,12,209,60,136,119, +186,163,62,152,61,160,130,53,219,110,62,216,31,196,33,253,130,251,133,41, +87,72,60,19,88,3,28,134,35,18,40,138,149,167,179,249,195,189,127,38,8,54, +167,179,42,178,1,92,228,255,240,29,184,235,174,214,75,127,7,77,167,37,201, +71,42,82,28,131,28,224,18,240,62,216,76,62,236,123,131,166,242,98,119,210, +49,16,1,55,91,55,17,0,191,232,122,98,195,221,110,229,226,92,192,156,159, +110,255,103,79,124,0,156,73,175,173,35,250,249,5,181,63,122,236,178,214, +166,83,249,163,32,1,32,97,248,2,233,181,229,242,213,117,38,23,215,218,235, +175,31,111,1,48,117,237,93,59,118,242,249,21,223,62,173,247,216,229,24, +231,57,240,192,4,133,185,20,194,189,254,53,150,232,92,155,115,167,95,71, +108,98,80,125,222,247,139,174,103,80,155,29,161,20,199,129,35,161,205,24, +21,89,34,38,136,232,117,3,186,24,87,2,69,23,12,48,67,108,16,215,16,47,34, +3,18,196,152,32,48,64,53,54,131,160,106,128,157,216,252,65,43,6,107,182, +1,27,3,127,136,51,81,54,205,97,241,166,191,132,70,103,217,69,191,32,250, +61,244,76,251,172,242,218,203,213,124,105,13,24,67,98,183,217,114,207,162, +217,29,55,28,155,158,207,29,29,180,219,245,193,214,204,82,164,90,62,131, +182,17,161,100,221,219,245,114,199,192,153,93,57,252,32,202,147,102,63, +31,159,92,120,220,34,239,59,50,107,133,228,13,224,109,183,93,35,224,88, +133,59,222,74,189,50,112,100,2,184,171,245,146,65,22,16,94,2,225,40,170, +21,217,104,56,54,221,77,62,240,85,209,130,95,116,61,9,109,70,37,90,22,228, +10,224,181,182,4,170,42,178,163,198,41,121,185,154,63,136,227,15,131,228, +187,196,255,21,120,89,0,0,0,0,73,69,78,68,174,66,96,130}; + +static size_t xml_res_size_5 = 622; +static unsigned char xml_res_file_5[] = { +137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,24,0,0,0,24,8,6,0,0, +0,224,119,61,248,0,0,0,6,98,75,71,68,0,255,0,255,0,255,160,189,167,147, +0,0,0,9,112,72,89,115,0,0,13,215,0,0,13,215,1,66,40,155,120,0,0,0,7,116, +73,77,69,7,225,5,27,16,40,10,255,154,217,173,0,0,1,251,73,68,65,84,72,199, +181,150,79,107,19,81,20,197,127,247,189,81,20,172,224,78,104,76,83,154, +69,65,92,249,29,4,173,249,163,11,5,91,18,161,184,85,113,225,82,169,31,193, +125,109,154,182,238,146,54,147,20,193,79,224,70,23,74,177,155,198,212,196, +184,20,234,194,66,102,230,186,104,163,113,72,106,26,157,179,155,251,134, +115,238,59,243,230,158,39,28,129,157,84,46,238,88,147,65,153,81,130,4,72, +236,96,69,91,130,105,168,6,53,79,108,37,89,89,106,14,226,144,126,197,230, +245,220,184,103,228,137,8,243,128,229,104,4,8,37,69,30,79,110,20,26,127, +21,248,148,189,155,21,213,21,224,12,199,195,119,163,204,197,221,101,183, +183,104,122,31,118,211,185,7,162,90,26,129,28,96,44,16,214,119,51,249,251, +125,119,112,216,121,41,44,58,2,2,163,220,232,238,68,0,90,55,103,99,158, +239,124,28,177,243,1,118,217,233,184,251,162,237,0,120,190,243,44,76,126, +234,226,52,167,47,95,26,138,237,199,219,15,236,111,109,135,236,242,23,128, +123,178,147,202,197,173,145,122,248,180,156,155,191,195,217,212,149,161, +4,246,170,175,249,182,248,50,92,246,29,235,37,140,99,36,59,196,81,28,5, +214,243,157,140,81,184,74,100,208,107,6,72,70,39,192,148,1,206,71,199,47, +227,134,104,17,24,160,29,161,64,219,0,245,8,63,114,221,160,186,25,25,189, +72,205,120,98,43,128,31,1,191,119,194,120,85,39,89,89,106,54,210,249,2, +7,179,255,247,239,255,230,29,116,58,67,142,138,247,125,130,70,22,99,229, +181,150,3,96,3,125,234,91,185,5,140,117,95,216,223,218,14,207,151,227,96, +79,173,183,240,43,15,46,212,138,95,16,189,253,159,172,10,4,153,75,148,87, +191,254,17,56,137,141,226,43,129,71,64,240,79,228,34,15,39,42,133,234,192, +200,252,156,206,167,3,97,181,215,174,97,109,17,163,179,19,235,197,218,192, +200,4,136,187,203,110,231,164,153,82,120,14,120,195,116,13,186,130,245, +167,195,228,3,111,21,93,28,38,93,6,101,6,97,18,136,117,151,64,235,192,166, +99,125,55,86,94,107,13,226,248,9,156,77,179,166,75,139,17,212,0,0,0,0,73, +69,78,68,174,66,96,130}; + +static size_t xml_res_size_6 = 1144; +static unsigned char xml_res_file_6[] = { +137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,24,0,0,0,24,8,6,0,0, +0,224,119,61,248,0,0,0,6,98,75,71,68,0,255,0,255,0,255,160,189,167,147, +0,0,0,9,112,72,89,115,0,0,13,215,0,0,13,215,1,66,40,155,120,0,0,0,7,116, +73,77,69,7,225,5,27,16,40,3,134,70,97,9,0,0,4,5,73,68,65,84,72,199,149, +150,125,76,213,85,24,199,63,231,220,223,21,132,139,74,76,96,23,68,4,2,95, +74,36,204,149,185,28,80,54,112,75,237,143,182,107,184,114,174,173,53,179, +172,173,218,154,110,218,250,167,245,178,176,173,63,154,171,41,190,76,231, +31,10,182,53,2,172,54,209,25,34,182,188,18,112,167,128,225,11,239,92,64, +238,203,239,233,15,188,183,251,194,5,122,254,59,231,57,207,247,123,206, +247,60,207,121,142,98,6,43,174,59,149,101,106,223,22,165,216,12,100,3,153, +143,92,61,192,45,68,106,45,134,62,123,101,163,163,59,22,134,154,110,178, +176,254,84,134,69,249,247,131,236,2,44,204,108,38,74,157,49,225,195,107, +37,142,91,179,18,20,55,30,223,42,194,81,192,198,255,179,81,65,85,182,148, +58,206,197,36,40,110,60,246,174,136,250,10,208,161,243,217,9,11,88,155, +156,74,122,92,34,94,49,233,28,27,230,210,64,47,110,159,55,234,52,10,181, +183,185,212,81,21,69,240,104,231,103,66,193,87,36,61,198,222,188,34,138, +23,165,70,109,215,47,66,205,93,23,135,58,91,25,242,78,134,145,8,106,91, +224,36,10,96,117,99,117,166,33,218,25,42,203,54,123,46,31,231,175,197,80, +83,124,109,238,65,122,31,142,97,85,154,60,219,34,210,226,18,0,24,244,78, +242,246,181,6,254,118,15,133,203,229,83,203,91,54,57,254,49,0,12,209,7, +67,193,95,74,93,202,39,5,235,80,192,197,129,94,190,104,111,230,246,248, +104,48,90,43,197,51,201,233,124,148,191,150,204,249,54,190,91,83,202,27, +205,117,116,79,4,215,36,97,145,3,192,155,170,184,238,84,150,88,124,174, +208,108,249,105,253,22,210,226,18,168,185,235,226,128,243,50,18,227,86, +19,13,43,223,23,149,81,96,75,230,226,64,47,239,180,94,8,83,209,167,204, +108,139,125,231,43,175,3,21,161,158,206,177,97,58,198,134,249,214,213,138, +57,67,218,236,206,41,36,101,94,60,233,241,137,44,153,159,196,170,5,41,60, +151,98,231,215,190,59,8,104,173,180,75,11,82,30,25,120,105,224,46,71,186, +156,248,69,102,204,203,62,207,4,133,11,23,7,199,27,82,236,120,76,63,230, +163,56,17,169,208,160,242,34,3,173,90,163,149,154,53,241,143,117,183,113, +99,116,32,56,238,247,60,228,155,142,107,161,53,144,171,65,210,35,3,63,91, +185,158,183,150,61,57,43,129,41,194,193,155,151,241,201,148,144,159,183, +55,51,226,243,132,46,201,48,34,131,54,164,216,41,91,188,4,191,8,245,247, +187,105,115,15,206,72,210,238,30,226,72,151,147,2,91,50,191,220,239,138, +46,188,226,134,227,109,2,249,129,172,56,189,174,34,152,227,109,238,65,118, +252,241,243,172,119,161,149,194,80,26,143,233,143,116,221,212,2,174,192, +104,79,206,154,32,56,64,129,45,25,71,102,193,156,164,154,6,28,1,151,70, +228,124,160,164,19,12,131,11,125,61,193,5,127,141,244,135,17,78,103,86, +173,217,157,83,200,166,212,172,232,147,137,212,106,139,161,207,2,126,1, +246,221,104,226,131,63,127,15,106,153,100,157,199,15,93,55,102,148,230, +211,21,207,178,115,233,74,222,207,123,42,210,237,243,106,169,209,87,54, +58,186,21,234,199,80,207,151,29,87,185,55,57,78,214,252,36,78,62,93,78, +121,90,54,243,116,216,3,203,19,11,82,56,92,244,2,47,166,102,225,49,77,246, +59,155,34,9,14,95,47,169,236,81,255,53,24,159,19,72,10,120,3,111,140,61, +62,17,128,49,159,23,215,248,48,94,211,196,30,111,35,61,126,74,186,135,126, +63,251,156,77,52,60,8,107,106,35,202,240,47,111,126,126,71,111,176,154, +138,234,79,150,43,101,214,132,190,73,9,22,131,93,217,171,120,53,227,113, +18,44,214,168,139,253,173,255,14,85,157,173,220,30,31,9,239,112,194,214, +171,101,219,107,162,27,78,195,137,61,130,124,29,217,112,172,90,83,180,112, +49,185,137,139,176,40,197,189,201,113,90,134,30,208,231,153,152,46,161, +222,107,41,219,126,40,102,203,44,106,56,241,178,66,170,67,229,154,163,141, +160,204,215,174,150,84,214,134,37,66,228,170,150,82,199,57,49,140,92,65, +170,0,223,28,128,77,144,163,202,240,47,143,4,143,249,171,8,216,234,198, +234,76,3,203,22,48,55,35,106,89,232,183,101,170,136,56,239,85,230,185,235, +37,149,61,177,48,254,5,68,165,141,10,108,236,250,76,0,0,0,0,73,69,78,68, +174,66,96,130}; + +static size_t xml_res_size_7 = 59686; +static unsigned char xml_res_file_7[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,85,84,70,45,56,34,63,62,10,60,33,45,45, +32,104,116,116,112,58,47,47,100,111,99,115,46,119,120,119,105,100,103,101, +116,115,46,111,114,103,47,116,114,117,110,107,47,111,118,101,114,118,105, +101,119,95,120,114,99,102,111,114,109,97,116,46,104,116,109,108,32,45,45, +62,10,60,114,101,115,111,117,114,99,101,32,120,109,108,110,115,61,34,104, +116,116,112,58,47,47,119,119,119,46,119,120,119,105,100,103,101,116,115, +46,111,114,103,47,119,120,120,114,99,34,32,118,101,114,115,105,111,110, +61,34,50,46,53,46,51,46,48,34,62,10,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,105,116,109,97,112,34,32,110,97,109,101, +61,34,66,73,84,77,65,80,95,72,65,82,68,68,73,83,75,34,62,119,120,45,114, +101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,100, +114,105,118,101,46,112,110,103,60,47,111,98,106,101,99,116,62,10,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116, +109,97,112,34,32,110,97,109,101,61,34,66,73,84,77,65,80,95,70,76,79,80, +80,89,34,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112, +36,105,99,111,110,115,95,100,105,115,107,46,112,110,103,60,47,111,98,106, +101,99,116,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,105,116,109,97,112,34,32,110,97,109,101,61,34,66,73,84,77, +65,80,95,67,68,82,79,77,34,62,119,120,45,114,101,115,111,117,114,99,101, +115,46,99,112,112,36,105,99,111,110,115,95,99,100,46,112,110,103,60,47, +111,98,106,101,99,116,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,111,111,108,66,97,114,34,32,110,97,109,101,61, +34,116,111,111,108,95,98,97,114,34,62,10,32,32,32,32,60,115,116,121,108, +101,62,119,120,84,66,95,70,76,65,84,124,119,120,84,66,95,78,79,68,73,86, +73,68,69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,116,111,111,108,34,32,110,97,109,101, +61,34,84,79,79,76,66,65,82,95,82,85,78,34,62,10,32,32,32,32,32,32,60,98, +105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46, +99,112,112,36,105,99,111,110,115,95,112,108,97,121,50,52,46,112,110,103, +60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,60,108,97,98,101,108, +62,82,117,110,60,47,108,97,98,101,108,62,10,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,116,111,111,108,34,32,110,97,109,101,61,34,84,79,79,76,66,65, +82,95,80,65,85,83,69,34,62,10,32,32,32,32,32,32,60,98,105,116,109,97,112, +62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99, +111,110,115,95,112,97,117,115,101,50,52,46,112,110,103,60,47,98,105,116, +109,97,112,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,80,97,117,115, +101,60,47,108,97,98,101,108,62,10,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,116, +111,111,108,34,32,110,97,109,101,61,34,84,79,79,76,66,65,82,95,83,84,79, +80,34,62,10,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114, +101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,115, +116,111,112,50,52,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32, +32,32,32,32,60,108,97,98,101,108,62,83,116,111,112,60,47,108,97,98,101, +108,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,116,111,111,108,34,32, +110,97,109,101,61,34,84,79,79,76,66,65,82,95,82,69,83,69,84,34,62,10,32, +32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117, +114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,114,101,102,114,101, +115,104,50,52,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32, +32,32,32,60,108,97,98,101,108,62,72,97,114,100,32,114,101,115,101,116,60, +47,108,97,98,101,108,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,105,100,115,45,114,97, +110,103,101,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,70,83,34,32, +115,116,97,114,116,61,34,49,48,48,48,34,47,62,10,32,32,60,105,100,115,45, +114,97,110,103,101,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,70,83, +95,77,79,68,69,34,32,115,116,97,114,116,61,34,49,49,48,48,34,47,62,10,32, +32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,77, +95,86,73,68,95,83,67,65,76,69,34,32,115,116,97,114,116,61,34,49,50,48,48, +34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101, +61,34,73,68,77,95,86,73,68,95,83,67,65,76,69,95,77,79,68,69,34,32,115,116, +97,114,116,61,34,49,51,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97, +110,103,101,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,82,69,78,68, +69,82,95,68,82,73,86,69,82,34,32,115,116,97,114,116,61,34,49,52,48,48,34, +47,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,77,101,110,117,66,97,114,34,32,110,97,109,101,61,34,115,116,97,116, +117,115,95,109,101,110,117,34,62,10,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32,32,32,32, +32,32,60,108,97,98,101,108,62,95,79,112,116,105,111,110,115,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101, +61,34,73,68,77,95,68,73,83,67,95,65,67,84,73,86,73,84,89,34,62,10,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,68,105,115,99,32,97,99,116,105, +118,105,116,121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60, +99,104,101,99,107,97,98,108,101,62,49,60,47,99,104,101,99,107,97,98,108, +101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77, +101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,77,65, +67,72,73,78,69,95,77,79,85,78,84,95,80,65,84,72,83,34,62,10,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,77,111,117,110,116,32,112,97,116,104, +115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,99,104,101, +99,107,97,98,108,101,62,49,60,47,99,104,101,99,107,97,98,108,101,62,10, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, +73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,72,79,87,95,83, +84,65,84,85,83,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +83,116,97,116,117,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,60,99,104,101,99,107,97,98,108,101,62,49,60,47,99,104,101,99,107,97, +98,108,101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, +83,80,69,69,68,95,72,73,83,84,79,82,89,34,62,10,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,83,112,101,101,100,32,104,105,115,116,111,114,121, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,99,104,101,99, +107,97,98,108,101,62,49,60,47,99,104,101,99,107,97,98,108,101,62,10,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,101,112,97,114,97,116, +111,114,34,47,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109, +101,61,34,73,68,77,95,83,72,79,87,95,77,65,67,72,73,78,69,95,79,78,95,83, +84,65,82,84,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83, +104,111,119,32,111,110,32,115,116,97,114,116,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,60,99,104,101,99,107,97,98,108,101,62,49,60, +47,99,104,101,99,107,97,98,108,101,62,10,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101, +110,117,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,95,67,111,110, +102,105,103,117,114,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, +117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,67,79,78,70,73, +71,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,97,99,104, +105,110,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109, +101,61,34,73,68,77,95,72,68,67,79,78,70,34,62,10,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,95,72,97,114,100,32,100,105,115,99,115,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32, +32,32,32,32,32,60,108,97,98,101,108,62,95,77,105,115,99,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61, +34,73,68,77,95,82,69,83,69,84,95,67,79,78,70,73,82,77,65,84,73,79,78,95, +68,73,65,76,79,71,83,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,95,82,101,115,101,116,32,99,111,110,102,105,114,109,97,116,105,111, +110,32,100,105,97,108,111,103,115,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,101,112,97,114,97,116,111, +114,34,47,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101, +61,34,73,68,77,95,65,66,79,85,84,34,62,10,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,95,65,98,111,117,116,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, +34,32,110,97,109,101,61,34,109,97,105,110,95,109,101,110,117,34,62,10,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77, +101,110,117,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,95,83,121, +115,116,101,109,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, +116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,70,73,76,69,95,72,82, +69,83,69,84,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95, +72,97,114,100,32,82,101,115,101,116,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, +116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,70,73,76,69,95,82,69, +83,69,84,95,67,65,68,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,95,67,116,114,108,43,65,108,116,43,68,101,108,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32,32,32,32, +32,32,60,108,97,98,101,108,62,95,68,105,115,99,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73, +68,77,95,68,73,83,67,95,65,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,67,104,97,110,103,101,32,100,114,105,118,101,32,95,65,58,46, +46,46,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101, +61,34,73,68,77,95,68,73,83,67,95,66,34,62,10,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,67,104,97,110,103,101,32,100,114,105,118,101,32,95, +66,58,46,46,46,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97, +109,101,61,34,73,68,77,95,69,74,69,67,84,95,65,34,62,10,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,95,69,106,101,99,116,32,100,114,105,118, +101,32,65,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97, +109,101,61,34,73,68,77,95,69,74,69,67,84,95,66,34,62,10,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,69,106,101,99,116,32,100,114,105,118,101, +32,66,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,101,112,97,114,97,116,111,114,34,47,62,10,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101, +110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,66,80,66, +95,68,73,83,65,66,76,69,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,68,105,115,97,98,108,101,32,66,80,66,32,99,104,101,99,107,105,110, +103,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,99,104,101, +99,107,97,98,108,101,62,49,60,47,99,104,101,99,107,97,98,108,101,62,10, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,77,101,110,117,34,32,110,97,109,101,61,34,73,68, +77,95,67,68,82,79,77,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62, +95,67,68,45,82,79,77,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, +73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,67,68,82,79,77,95, +73,77,65,71,69,95,76,79,65,68,34,62,10,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,95,76,111,97,100,32,105,109,97,103,101,46,46,46,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +101,112,97,114,97,116,111,114,34,47,62,10,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101, +109,34,32,110,97,109,101,61,34,73,68,77,95,67,68,82,79,77,95,68,73,83,65, +66,76,69,68,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95, +68,105,115,97,98,108,101,100,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, +73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,67,68,82,79,77,95, +69,77,80,84,89,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +95,69,109,112,116,121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116, +101,109,34,32,110,97,109,101,61,34,73,68,77,95,67,68,82,79,77,95,73,77, +65,71,69,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,73, +109,97,103,101,46,46,46,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,77,101,110,117,34,62,10,32,32,32,32,32,32,60,108, +97,98,101,108,62,86,105,100,101,111,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86, +73,68,95,82,69,83,73,90,69,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,82,101,115,105,122,97,98,108,101,32,119,105,110,100,111,119, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,99,104,101,99, +107,97,98,108,101,62,49,60,47,99,104,101,99,107,97,98,108,101,62,10,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, +116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,82,69,77, +69,77,66,69,82,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +82,101,109,101,109,98,101,114,32,115,105,122,101,32,38,97,109,112,59,38, +97,109,112,59,32,112,111,115,105,116,105,111,110,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,60,99,104,101,99,107,97,98,108,101,62,49, +60,47,99,104,101,99,107,97,98,108,101,62,10,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,101,112,97,114,97,116,111,114,34,47,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86, +73,68,95,70,85,76,76,83,67,82,69,69,78,95,84,79,71,71,76,69,34,62,10,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,111,103,103,108,101,32, +102,117,108,108,115,99,114,101,101,110,92,116,67,116,114,108,43,65,108, +116,43,80,97,103,101,68,111,119,110,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, +116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,70,85,76, +76,83,67,82,69,69,78,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,70,117,108,108,115,99,114,101,101,110,32,111,110,32,105,110,112, +117,116,32,103,114,97,98,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,60,99,104,101,99,107,97,98,108,101,62,49,60,47,99,104,101,99,107, +97,98,108,101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,77,101,110,117,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,83,116,114,101,116,99,104,32,109,111,100,101,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61, +34,73,68,77,95,86,73,68,95,70,83,91,48,93,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,95,78,111,110,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60, +47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109, +101,61,34,73,68,77,95,86,73,68,95,70,83,91,49,93,34,62,10,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,95,52,58,51,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60, +47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109, +101,61,34,73,68,77,95,86,73,68,95,70,83,91,50,93,34,62,10,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,95,83,113,117,97,114,101,32,112, +105,120,101,108,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101, +110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68, +95,70,83,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,95,73,110,116,101,103,101,114,32,115,99,97,108,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62, +49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,77,101,110,117,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,83,99,97,108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, +117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,83, +67,65,76,69,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,48,46,53,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77, +101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73, +68,95,83,67,65,76,69,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,49,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86, +73,68,95,83,67,65,76,69,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,49,46,53,120,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105, +111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68, +77,95,86,73,68,95,83,67,65,76,69,91,51,93,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,50,120,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100, +105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,101,112,97,114,97, +116,111,114,34,47,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,70,117,108,108,115,99,114,101,101,110,32, +109,111,100,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, +73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,70,83, +95,77,79,68,69,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,95,66,111,114,100,101,114,108,101,115,115,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49, +60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97, +109,101,61,34,73,68,77,95,86,73,68,95,70,83,95,77,79,68,69,91,49,93,34, +62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,69,120,99, +108,117,115,105,118,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109, +34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,76,79,83,84,95,70,79, +67,85,83,95,68,73,77,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,95,68,105,109,32,100,105,115,112,108,97,121,32,111,110,32,108,111, +115,116,32,102,111,99,117,115,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,60,99,104,101,99,107,97,98,108,101,62,49,60,47,99,104,101,99, +107,97,98,108,101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,77,101,110,117,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,83,99,97,108,101,32,102,105,108,116,101,114,105,110,103,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110, +97,109,101,61,34,73,68,77,95,86,73,68,95,83,67,65,76,69,95,77,79,68,69, +91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +95,78,101,97,114,101,115,116,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111, +62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, +86,73,68,95,83,67,65,76,69,95,77,79,68,69,91,49,93,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,95,76,105,110,101,97,114,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105, +111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,77,101,110,117,34,32,110,97,109,101,61,34,73,68,77,95,86,73, +68,95,82,69,78,68,69,82,95,68,82,73,86,69,82,34,62,10,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,95,82,101,110,100,101,114,32,100,114,105, +118,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, +116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,82,69,78, +68,69,82,95,68,82,73,86,69,82,91,48,93,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,65,117,116,111,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114, +97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61, +34,73,68,77,95,86,73,68,95,82,69,78,68,69,82,95,68,82,73,86,69,82,91,49, +93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,105, +114,101,99,116,51,68,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101, +110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68, +95,82,69,78,68,69,82,95,68,82,73,86,69,82,91,50,93,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,79,112,101,110,71,76,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111, +62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32, +110,97,109,101,61,34,73,68,77,95,86,73,68,95,82,69,78,68,69,82,95,68,82, +73,86,69,82,91,53,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,83,111,102,116,119,97,114,101,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97, +100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, +117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,86, +83,89,78,67,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95, +86,83,121,110,99,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +60,99,104,101,99,107,97,98,108,101,62,49,60,47,99,104,101,99,107,97,98, +108,101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,101,112,97,114,97,116,111,114,34,47, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, +83,84,65,84,85,83,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,95, +77,97,99,104,105,110,101,60,47,108,97,98,101,108,62,10,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,101,112,97,114,97,116,111,114,34,47,62,10,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101, +110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,70,73,76, +69,95,69,88,73,84,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,95, +83,116,111,112,32,101,109,117,108,97,116,105,111,110,60,47,108,97,98,101, +108,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109,101,61,34,67,111, +110,102,105,103,117,114,101,68,108,103,34,62,10,32,32,32,32,60,116,105, +116,108,101,62,67,111,110,102,105,103,117,114,101,32,80,67,101,109,60,47, +116,105,116,108,101,62,10,32,32,32,32,60,99,101,110,116,101,114,101,100, +62,49,60,47,99,101,110,116,101,114,101,100,62,10,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34, +32,110,97,109,101,61,34,82,79,79,84,95,80,65,78,69,76,34,62,10,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66, +111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47, +114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,33,45,45,32,109,97,99,104,105,110,101,32,45,45,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73, +71,78,95,76,69,70,84,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,77,97,99,104,105,110,101,58,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34, +32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,49,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +67,66,95,68,82,79,80,68,79,87,78,32,124,32,119,120,67,66,95,82,69,65,68, +79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110, +97,109,101,61,34,73,68,67,95,67,79,78,70,73,71,85,82,69,77,79,68,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,67,111,110,102,105,103,117,114,101,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,33,45,45,32,118,105,100,101,111,32, +45,45,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,105,100,101,111,58,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34, +32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,86,73,68,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,67,66,95,68,82,79,80,68,79,87,78,32,124,32,119,120,67,66,95,82, +69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,71,85,82,69,86,73,68, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,111,110,102,105,103,117,114,101,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,33,45,45,32,118,105,100,101,111, +32,115,112,101,101,100,32,45,45,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,86,105,100,101,111,32,115,112,101,101,100,58,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,73,68,67,95,67,79,77,66,79,83,80,68,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95, +68,82,79,80,68,79,87,78,32,124,32,119,120,67,66,95,82,69,65,68,79,78,76, +89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,33,45,45,32,99,112,117, +32,116,121,112,101,32,45,45,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,80,85, +32,116,121,112,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67, +79,77,66,79,67,80,85,77,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87, +78,32,124,32,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,33,45,45,32,99,112,117,32,116,121,112,101,32, +45,45,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,80,85,58,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97, +109,101,61,34,73,68,67,95,67,79,77,66,79,51,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95, +68,82,79,80,68,79,87,78,32,124,32,119,120,67,66,95,82,69,65,68,79,78,76, +89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,33,45,45,32,100,121, +110,97,109,105,99,32,114,101,99,111,109,112,105,108,101,114,32,45,45,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73, +71,78,95,76,69,70,84,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104, +101,99,107,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,72,69,67, +75,68,89,78,65,82,69,67,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,68,121,110,97,109,105,99,32,82,101,99, +111,109,112,105,108,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,112,97,99,101,114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,33,45,45,32,119,97,105, +116,115,116,97,116,101,115,32,45,45,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,87,97,105,116,115,116,97,116,101,115,58,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101, +61,34,73,68,67,95,67,79,77,66,79,87,83,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82, +79,80,68,79,87,78,32,124,32,119,120,67,66,95,82,69,65,68,79,78,76,89,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,33,45,45,32,115,111,117,110, +100,32,99,97,114,100,32,45,45,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,111, +117,110,100,32,99,97,114,100,58,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, +67,79,77,66,79,83,78,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87, +78,32,124,32,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,67,79, +78,70,73,71,85,82,69,83,78,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,67,111,110,102,105,103,117,114,101, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,33, +45,45,32,72,68,68,32,45,45,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,68,68, +58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111, +120,34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,72,68,68,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,68,82,79,80,68,79,87,78,32,124,32,119,120,67,66,95, +82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,112,97,99,101,114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +33,45,45,32,70,68,68,49,32,45,45,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,70,68,68,49,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67, +111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,79, +77,66,79,68,82,65,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,32, +124,32,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,112,97,99,101,114,34,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,33,45,45,32,70,68,68,50,32,45,45,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69, +70,84,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,70,68,68,50,58,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, +67,79,77,66,79,68,82,66,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87, +78,32,124,32,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,33,45,45,32,109,101,109,111,114,121,32,45,45, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,76,69,70,84,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83, +116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,77,101,109,111,114,121,58,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105, +101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105, +101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,112,105,110, +67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,77,69,77,83,80,73, +78,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,83,80,95,72,79,82,73,90,79,78,84,65,76, +124,119,120,83,80,95,65,82,82,79,87,95,75,69,89,83,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +118,97,108,117,101,62,53,48,60,47,118,97,108,117,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,105,110,62,49,48, +60,47,109,105,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,109,97,120,62,50,48,48,60,47,109,97,120,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,84,69,88,84,95, +77,66,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,77,66,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,33,45,45,32,109,111,117,115,101,32, +45,45,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,111,117,115,101,58,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34, +32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,77,79,85,83,69,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,68,82,79,80,68,79,87,78,32,124,32,119,120,67,66,95, +82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,112,97,99,101,114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +33,45,45,32,84,79,68,79,58,32,106,111,121,115,116,105,99,107,32,45,45,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,33,45,45,32,99,109,115,32,47, +32,103,97,109,101,32,98,108,97,115,116,101,114,32,45,45,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,76, +69,70,84,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107, +66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,72,69,67,75,51,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,77,83,32,47,32,71,97,109,101,32,66,108,97,115,116,101,114,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,112,97,99,101,114,34,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,33,45,45,32,71,114,97,118,105,115,32,85,108,116,114, +97,115,111,117,110,100,32,45,45,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97, +109,101,61,34,73,68,67,95,67,72,69,67,75,71,85,83,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,71,114,97,118, +105,115,32,85,108,116,114,97,115,111,117,110,100,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,112,97,99,101,114,34,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,33, +45,45,32,73,110,110,111,118,97,116,105,111,110,32,83,83,73,45,50,48,48, +49,32,45,45,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, +67,72,69,67,75,83,83,73,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,73,110,110,111,118,97,116,105,111,110, +32,83,83,73,45,50,48,48,49,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,112,97,99,101,114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,33,45,45,32,69,110,97, +98,108,101,32,116,105,109,101,32,115,121,110,99,32,45,45,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,76, +69,70,84,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107, +66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,72,69,67,75,83,89, +78,67,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,83,121,110,99,104,114,111,110,105,115,101,32,116,105,109, +101,32,116,111,32,104,111,115,116,32,99,108,111,99,107,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,112,97,99,101,114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,33,45,45,32,86,111,111,100,111,111,32,71,114,97,112,104,105,99,115,32, +45,45,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67, +72,69,67,75,86,79,79,68,79,79,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,86,111,111,100,111,111,32,71,114, +97,112,104,105,99,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,71,85,82,69,86,79,79, +68,79,79,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,67,111,110,102,105,103,117,114,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69, +70,84,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114, +105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114, +105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101, +102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101, +61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,97,110, +99,101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,112,97,99,101,114,34,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97, +99,101,114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60, +105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,80, +65,78,69,76,34,32,115,116,97,114,116,61,34,49,48,34,47,62,10,32,32,60,105, +100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,72,68, +68,34,32,115,116,97,114,116,61,34,49,48,48,34,47,62,10,32,32,60,105,100, +115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,67,68,82, +79,77,34,32,115,116,97,114,116,61,34,50,48,48,34,47,62,10,32,32,60,105, +100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,69,68, +73,84,95,70,78,34,32,115,116,97,114,116,61,34,51,48,48,34,47,62,10,32,32, +60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95, +70,73,76,69,34,32,115,116,97,114,116,61,34,52,48,48,34,47,62,10,32,32,60, +105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,69, +74,69,67,84,34,32,115,116,97,114,116,61,34,53,48,48,34,47,62,10,32,32,60, +105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,78, +69,87,34,32,115,116,97,114,116,61,34,54,48,48,34,47,62,10,32,32,60,105, +100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,69,68, +73,84,95,83,80,84,34,32,115,116,97,114,116,61,34,55,48,48,34,47,62,10,32, +32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67, +95,69,68,73,84,95,72,80,67,34,32,115,116,97,114,116,61,34,56,48,48,34,47, +62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34, +73,68,67,95,69,68,73,84,95,67,89,76,34,32,115,116,97,114,116,61,34,57,48, +48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109, +101,61,34,73,68,67,95,84,69,88,84,95,83,73,90,69,34,32,115,116,97,114,116, +61,34,49,48,48,48,34,47,62,10,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109,101,61, +34,72,100,67,111,110,102,68,108,103,34,62,10,32,32,32,32,60,116,105,116, +108,101,62,67,111,110,102,105,103,117,114,101,32,72,97,114,100,32,68,105, +115,99,115,60,47,116,105,116,108,101,62,10,32,32,32,32,60,99,101,110,116, +101,114,101,100,62,49,60,47,99,101,110,116,101,114,101,100,62,10,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97, +110,101,108,34,32,110,97,109,101,61,34,82,79,79,84,95,80,65,78,69,76,34, +62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60, +47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111, +119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,73,68, +67,95,80,65,78,69,76,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60, +47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47, +118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,67,58,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68, +91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,82,66,95,71,82,79,85,80,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,97,114,100,32,100,114, +105,118,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,82,97,100,105,111,66,117,116,116,111,110,34,32,110, +97,109,101,61,34,73,68,67,95,67,68,82,79,77,91,48,93,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,68,45,82,79,77,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97, +109,101,61,34,73,68,67,95,69,68,73,84,95,70,78,91,48,93,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,84,69,95,82,69,65,68,79,78,76,89,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,73,68,67,95,70,73,76,69,91,48,93,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,46,46,46,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67, +95,78,69,87,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,101,119,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,73,68,67,95,69,74,69,67,84,91,48,93,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,69,106,101,99,116,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110, +116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,58,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, +116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,83,80, +84,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,82, +69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111, +120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79, +82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,72,58,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97, +109,101,61,34,73,68,67,95,69,68,73,84,95,72,80,67,91,48,93,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,84,69,95,82,69,65,68,79,78,76,89,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60, +47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95, +69,68,73,84,95,67,89,76,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,84,69,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,73,68,67,95,84,69,88,84,95,83,73,90,69,91, +48,93,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,73,68,67,95,80,65,78,69,76,91,49,93,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114, +111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83, +116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,58,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,73,68,67,95,72,68,68,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,82, +66,95,71,82,79,85,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +72,97,114,100,32,100,114,105,118,101,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,67,68,82, +79,77,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,67,68,45,82,79,77,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84, +101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,69,68, +73,84,95,70,78,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,82, +69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67, +95,70,73,76,69,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,46,46,46,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,73,68,67,95,78,69,87,91,49,93,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,78,101,119,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67, +95,69,74,69,67,84,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,69,106,101,99,116, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65, +76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,83,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34, +73,68,67,95,69,68,73,84,95,83,80,84,91,49,93,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,84,69,95,82,69,65,68,79,78,76,89,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101, +110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101, +110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,58,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, +116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,72,80, +67,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,82, +69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111, +120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79, +82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,67,58,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97, +109,101,61,34,73,68,67,95,69,68,73,84,95,67,89,76,91,49,93,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,84,69,95,82,69,65,68,79,78,76,89,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68, +67,95,84,69,88,84,95,83,73,90,69,91,49,93,34,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,73, +68,67,95,80,65,78,69,76,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60, +47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47, +118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,69,58,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68, +91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,82,66,95,71,82,79,85,80,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,97,114,100,32,100,114, +105,118,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,82,97,100,105,111,66,117,116,116,111,110,34,32,110, +97,109,101,61,34,73,68,67,95,67,68,82,79,77,91,50,93,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,68,45,82,79,77,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97, +109,101,61,34,73,68,67,95,69,68,73,84,95,70,78,91,50,93,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,84,69,95,82,69,65,68,79,78,76,89,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,73,68,67,95,70,73,76,69,91,50,93,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,46,46,46,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67, +95,78,69,87,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,101,119,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,73,68,67,95,69,74,69,67,84,91,50,93,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,69,106,101,99,116,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110, +116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,58,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, +116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,83,80, +84,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,82, +69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111, +120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79, +82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,72,58,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97, +109,101,61,34,73,68,67,95,69,68,73,84,95,72,80,67,91,50,93,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,84,69,95,82,69,65,68,79,78,76,89,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60, +47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95, +69,68,73,84,95,67,89,76,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,84,69,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,73,68,67,95,84,69,88,84,95,83,73,90,69,91, +50,93,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,73,68,67,95,80,65,78,69,76,91,51,93,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114, +111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83, +116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,58,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,73,68,67,95,72,68,68,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,82, +66,95,71,82,79,85,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +72,97,114,100,32,100,114,105,118,101,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,67,68,82, +79,77,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,67,68,45,82,79,77,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84, +101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,69,68, +73,84,95,70,78,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,82, +69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67, +95,70,73,76,69,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,46,46,46,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,73,68,67,95,78,69,87,91,51,93,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,78,101,119,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67, +95,69,74,69,67,84,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,69,106,101,99,116, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65, +76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,83,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34, +73,68,67,95,69,68,73,84,95,83,80,84,91,51,93,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,84,69,95,82,69,65,68,79,78,76,89,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101, +110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101, +110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,58,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, +116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,72,80, +67,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,82, +69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111, +120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79, +82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,67,58,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97, +109,101,61,34,73,68,67,95,69,68,73,84,95,67,89,76,91,51,93,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,84,69,95,82,69,65,68,79,78,76,89,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68, +67,95,84,69,88,84,95,83,73,90,69,91,51,93,34,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,76,69,70,84,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66, +111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78, +84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120, +73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117, +108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,79,75,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116, +111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,68,105,97, +108,111,103,34,32,110,97,109,101,61,34,72,100,78,101,119,68,108,103,34, +62,10,32,32,32,32,60,116,105,116,108,101,62,78,101,119,32,72,97,114,100, +32,68,105,115,99,60,47,116,105,116,108,101,62,10,32,32,32,32,60,99,101, +110,116,101,114,101,100,62,49,60,47,99,101,110,116,101,114,101,100,62,10, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +80,97,110,101,108,34,32,110,97,109,101,61,34,82,79,79,84,95,80,65,78,69, +76,34,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60, +47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111, +119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,73,68,67,95,69,68,73,84,67,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,82,69,65,68, +79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110, +97,109,101,61,34,73,68,67,95,67,70,73,76,69,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,46,46,46,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,101,99,116,111,114,115, +58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,49,34,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +76,69,70,84,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,72,101,97,100,115,58,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97, +109,101,61,34,73,68,67,95,69,68,73,84,50,34,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84, +124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,67,121,108,105,110,100,101,114,115,58,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97, +109,101,61,34,73,68,67,95,69,68,73,84,51,34,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84, +124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,73,68,67,95,84,69,88,84,49,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,105, +122,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99, +101,114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,121,112,101,58,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34, +32,110,97,109,101,61,34,73,68,67,95,72,68,84,89,80,69,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +67,66,95,68,82,79,80,68,79,87,78,32,124,32,119,120,67,66,95,82,69,65,68, +79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116, +62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108, +116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,75,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119, +120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,97,110,99,101,108, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109,101,61,34,72,100, +83,105,122,101,68,108,103,34,62,10,32,32,32,32,60,116,105,116,108,101,62, +72,97,114,100,32,100,105,115,99,32,112,97,114,97,109,101,116,101,114,115, +60,47,116,105,116,108,101,62,10,32,32,32,32,60,99,101,110,116,101,114,101, +100,62,49,60,47,99,101,110,116,101,114,101,100,62,10,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108, +34,32,110,97,109,101,61,34,82,79,79,84,95,80,65,78,69,76,34,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,114,105,101,110,116,62,119,120,86,69,82,84,73,67,65,76,60, +47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,110,105, +116,105,97,108,32,115,101,116,116,105,110,103,115,32,97,114,101,32,98,97, +115,101,100,32,111,110,32,102,105,108,101,32,115,105,122,101,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50, +60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +76,69,70,84,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,101, +99,116,111,114,115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,69, +68,73,84,49,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69,70, +84,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,97,100, +115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116, +67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,50,34, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,67,121,108,105,110,100,101,114, +115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116, +67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,51,34, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,84,69,88,84, +49,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,83,105,122,101,58,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101, +114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,84,121,112,101,58,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,73,68,67,95,72,68,84,89,80,69,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,67,66,95,68,82,79,80,68,79,87,78,32,124,32,119,120,67,66,95,82, +69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47, +111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102, +97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,67,111,110,102,105,103,117,114,101,83,101,108,101,99,116,105, +111,110,68,108,103,34,62,10,32,32,32,32,60,116,105,116,108,101,62,80,67, +101,109,32,67,111,110,102,105,103,117,114,97,116,105,111,110,32,77,97,110, +97,103,101,114,60,47,116,105,116,108,101,62,10,32,32,32,32,60,99,101,110, +116,101,114,101,100,62,49,60,47,99,101,110,116,101,114,101,100,62,10,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80, +97,110,101,108,34,32,110,97,109,101,61,34,82,79,79,84,95,80,65,78,69,76, +34,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79,82, +73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +76,105,115,116,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,76,73, +83,84,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,76,66,95,83,73,78,71,76,69,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,50,48,48,44,51,48,48,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,86,69, +82,84,73,67,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,76, +111,97,100,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47, +100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95, +78,69,87,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,78,101,119,46,46,46,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,73,68,67,95,82,69,78,65,77,69,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,110,97,109, +101,46,46,46,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116, +111,110,34,32,110,97,109,101,61,34,73,68,67,95,68,69,76,69,84,69,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,68,101,108,101,116,101,46,46,46,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,71,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,67,111,110,102,105,103,117,114,101,46,46,46,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,73,68,67,95,72,68,67,79,78,70,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,68,68,46,46,46, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, +68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,81,117,105,116,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,68,105,97,108,111,103,34,32,110,97,109,101,61,34,67,111,110,102, +105,114,109,82,101,109,101,109,98,101,114,68,108,103,34,62,10,32,32,32, +32,60,116,105,116,108,101,62,80,67,101,109,60,47,116,105,116,108,101,62, +10,32,32,32,32,60,99,101,110,116,101,114,101,100,62,49,60,47,99,101,110, +116,101,114,101,100,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,82, +79,79,84,95,80,65,78,69,76,34,62,10,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120, +86,69,82,84,73,67,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111, +120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47, +111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, +105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,66,105,116,109,97,112,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,32,115, +116,111,99,107,95,105,100,61,34,119,120,65,82,84,95,81,85,69,83,84,73,79, +78,34,32,115,116,111,99,107,95,99,108,105,101,110,116,61,34,119,120,65, +82,84,95,67,77,78,95,68,73,65,76,79,71,34,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,73,68,67,95,67,79,78,70,73,82,77,95,76,65,66,69,76,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,68, +67,95,67,79,78,70,73,82,77,95,76,65,66,69,76,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62, +45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, +67,79,78,70,73,82,77,95,82,69,77,69,77,66,69,82,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,68,67,95,67,79,78,70,73, +82,77,95,82,69,77,69,77,66,69,82,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99, +104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,100,68,105,97,108,111,103,66,117,116,116,111,110,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,98,117,116,116,111,110,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,72,79,82,73,90,79,78,84,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,95,79,75,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,98,117,116,116,111,110,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,72,79,82,73,90,79,78,84,65,76,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,67,97,110,99,101,108, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +68,105,97,108,111,103,34,32,110,97,109,101,61,34,65,98,111,117,116,68,108, +103,34,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65, +85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,60,47,115,116,121,108,101, +62,10,32,32,32,32,60,116,105,116,108,101,47,62,10,32,32,32,32,60,99,101, +110,116,101,114,101,100,62,49,60,47,99,101,110,116,101,114,101,100,62,10, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +80,97,110,101,108,34,32,110,97,109,101,61,34,82,79,79,84,95,80,65,78,69, +76,34,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,60,111,114,105,101,110,116,62,119,120,86,69,82,84,73,67,65,76, +60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48, +60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,67,101, +109,32,118,49,50,92,110,104,116,116,112,115,58,47,47,112,99,101,109,45, +101,109,117,108,97,116,111,114,46,99,111,46,117,107,47,92,110,92,110,84, +104,105,115,32,112,114,111,103,114,97,109,32,105,115,32,108,105,99,101, +110,115,101,100,32,117,110,100,101,114,32,116,104,101,32,71,78,85,32,71, +101,110,101,114,97,108,32,80,117,98,108,105,99,32,76,105,99,101,110,115, +101,32,118,101,114,115,105,111,110,32,50,46,92,110,83,101,101,32,67,79, +80,89,73,78,71,32,102,111,114,32,109,111,114,101,32,100,101,116,97,105, +108,115,46,92,110,92,110,84,111,111,108,98,97,114,45,105,99,111,110,115, +32,109,97,100,101,32,98,121,32,82,111,117,110,100,105,99,111,110,115,32, +40,104,116,116,112,115,58,47,47,114,111,117,110,100,105,99,111,110,115, +46,99,111,109,47,41,32,102,114,111,109,32,119,119,119,46,102,108,97,116, +105,99,111,110,46,99,111,109,92,110,83,116,97,116,117,115,45,105,99,111, +110,115,32,109,97,100,101,32,98,121,32,77,97,114,107,32,74,97,109,101,115, +32,40,104,116,116,112,58,47,47,119,119,119,46,102,97,109,102,97,109,102, +97,109,46,99,111,109,47,108,97,98,47,105,99,111,110,115,47,115,105,108, +107,47,41,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48, +60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,32,124,32,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,76,105,110,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,76,73,95,72,79,82,73,90,79,78,84,65,76, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95, +79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,95,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115, +111,117,114,99,101,62,10}; + +void InitXmlResource() +{ + + // Check for memory FS. If not present, load the handler: + { + wxMemoryFSHandler::AddFile(wxT("XRC_resource/dummy_file"), wxT("dummy one")); + wxFileSystem fsys; + wxFSFile *f = fsys.OpenFile(wxT("memory:XRC_resource/dummy_file")); + wxMemoryFSHandler::RemoveFile(wxT("XRC_resource/dummy_file")); + if (f) delete f; + else wxFileSystem::AddHandler(new wxMemoryFSHandler); + } + + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_drive.png"), xml_res_file_0, xml_res_size_0, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_disk.png"), xml_res_file_1, xml_res_size_1, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_cd.png"), xml_res_file_2, xml_res_size_2, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_play24.png"), xml_res_file_3, xml_res_size_3, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_pause24.png"), xml_res_file_4, xml_res_size_4, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_stop24.png"), xml_res_file_5, xml_res_size_5, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_refresh24.png"), xml_res_file_6, xml_res_size_6, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$pc.xrc"), xml_res_file_7, xml_res_size_7, wxT("text/xml")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/wx-resources.cpp$pc.xrc")); +} diff --git a/src/wx-sdl2-display.c b/src/wx-sdl2-display.c new file mode 100644 index 0000000..b0fe236 --- /dev/null +++ b/src/wx-sdl2-display.c @@ -0,0 +1,755 @@ +#include +#include "wx-sdl2-video.h" +#include "wx-utils.h" +#include "ibm.h" +#include "video.h" +#include "wx-display.h" +#include "plat-keyboard.h" + +#ifdef __WINDOWS__ +#define BITMAP WINDOWS_BITMAP +#include +#include +#undef BITMAP + +HHOOK hKeyboardHook; +int modkeystate[255]; + +#endif + +SDL_mutex* rendererMutex; +SDL_cond* rendererCond; +SDL_Thread* renderthread = NULL; + +SDL_Window* window = NULL; + +int rendering = 0; + +int mousecapture = 0; + +extern int pause; +extern int video_scale; + +void* ghwnd; +void* menu; + +SDL_Rect remembered_rect; +int remembered_mouse_x = 0; +int remembered_mouse_y = 0; + +int win_doresize = 0; +int winsizex = 640, winsizey = 480; + +void renderer_start(); +void renderer_stop(int timeout); + +int trigger_fullscreen = 0; +int trigger_togglewindow = 0; +int trigger_inputrelease = 0; + +extern void device_force_redraw(); +extern void mouse_wheel_update(int); +extern void toggle_fullscreen(); + +void display_resize(int width, int height) +{ + /* Video scaling-code is borrowed from 86Box */ + switch(video_scale) + { + case 0: + winsizex = width >> 1; + winsizey = height >> 1; + break; + case 2: + winsizex = (width * 3) >> 1; + winsizey = (height * 3) >> 1; + break; + case 3: + winsizex = width << 1; + winsizey = height << 1; + break; + case 1: + default: + winsizex = width; + winsizey = height; + break; + } + + SDL_Rect rect; + rect.x = rect.y = 0; + rect.w = winsizex; + rect.h = winsizey; + sdl_scale(video_fullscreen_scale, rect, &rect, winsizex, winsizey); + winsizex = rect.w; + winsizey = rect.h; + + win_doresize = 1; +} + +void releasemouse() +{ + if (mousecapture) + { + SDL_SetWindowGrab(window, SDL_FALSE); + SDL_SetRelativeMouseMode(SDL_FALSE); + mousecapture = 0; + } +} + +int display_init() +{ + if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) < 0) + { + printf("SDL could not initialize! Error: %s\n", SDL_GetError()); + return 0; + } + + SDL_version ver; + SDL_GetVersion(&ver); + printf("SDL %i.%i.%i initialized.\n", ver.major, ver.minor, ver.patch); + return 1; +} + +void display_close() +{ + SDL_Quit(); +} + +void display_start(void* hwnd) +{ + ghwnd = hwnd; + menu = wx_getmenu(hwnd); + atexit(releasemouse); + rendererMutex = SDL_CreateMutex(); + rendererCond = SDL_CreateCond(); + renderer_start(); +} + +void display_stop() +{ + renderer_stop(10 * 1000); + + SDL_DestroyMutex(rendererMutex); + SDL_DestroyCond(rendererCond); +#if SDL_VERSION_ATLEAST(2, 0, 2) + SDL_DetachThread(renderthread); +#endif + releasemouse(); +} + +int is_fullscreen() +{ + int flags = SDL_GetWindowFlags(window); + return (flags&SDL_WINDOW_FULLSCREEN) || (flags&SDL_WINDOW_FULLSCREEN_DESKTOP); +} + +void sdl_set_window_title(const char* title) { + if (window) + SDL_SetWindowTitle(window, title); +} + +int get_border_size(int* top, int* left, int* bottom, int* right) +{ +#if SDL_VERSION_ATLEAST(2, 0, 5) + return SDL_GetWindowBordersSize(window, top, left, bottom, right); +#else + if (top) *top = 0; + if (left) *left = 0; + if (bottom) *bottom = 0; + if (right) *right = 0; + return 0; +#endif +} + +static const struct { + SDL_Scancode sdl; + int system; +} SDLScancodeToSystemScancode[] = { + { SDL_SCANCODE_A, 0x1e }, + { SDL_SCANCODE_B, 0x30 }, + { SDL_SCANCODE_C, 0x2e }, + { SDL_SCANCODE_D, 0x20 }, + { SDL_SCANCODE_E, 0x12 }, + { SDL_SCANCODE_F, 0x21 }, + { SDL_SCANCODE_G, 0x22 }, + { SDL_SCANCODE_H, 0x23 }, + { SDL_SCANCODE_I, 0x17 }, + { SDL_SCANCODE_J, 0x24 }, + { SDL_SCANCODE_K, 0x25 }, + { SDL_SCANCODE_L, 0x26 }, + { SDL_SCANCODE_M, 0x32 }, + { SDL_SCANCODE_N, 0x31 }, + { SDL_SCANCODE_O, 0x18 }, + { SDL_SCANCODE_P, 0x19 }, + { SDL_SCANCODE_Q, 0x10 }, + { SDL_SCANCODE_R, 0x13 }, + { SDL_SCANCODE_S, 0x1f }, + { SDL_SCANCODE_T, 0x14 }, + { SDL_SCANCODE_U, 0x16 }, + { SDL_SCANCODE_V, 0x2f }, + { SDL_SCANCODE_W, 0x11 }, + { SDL_SCANCODE_X, 0x2d }, + { SDL_SCANCODE_Y, 0x15 }, + { SDL_SCANCODE_Z, 0x2c }, + { SDL_SCANCODE_0, 0x0B }, + { SDL_SCANCODE_1, 0x02 }, + { SDL_SCANCODE_2, 0x03 }, + { SDL_SCANCODE_3, 0x04 }, + { SDL_SCANCODE_4, 0x05 }, + { SDL_SCANCODE_5, 0x06 }, + { SDL_SCANCODE_6, 0x07 }, + { SDL_SCANCODE_7, 0x08 }, + { SDL_SCANCODE_8, 0x09 }, + { SDL_SCANCODE_9, 0x0A }, + { SDL_SCANCODE_GRAVE, 0x29 }, + { SDL_SCANCODE_MINUS, 0x0c }, + { SDL_SCANCODE_EQUALS, 0x0d }, + { SDL_SCANCODE_NONUSBACKSLASH, 0x56 }, + { SDL_SCANCODE_BACKSLASH, 0x2b }, + { SDL_SCANCODE_BACKSPACE, 0x0e }, + { SDL_SCANCODE_SPACE, 0x39 }, + { SDL_SCANCODE_TAB, 0x0f }, + { SDL_SCANCODE_CAPSLOCK, 0x3a }, + { SDL_SCANCODE_LSHIFT, 0x2a }, + { SDL_SCANCODE_LCTRL, 0x1d }, + { SDL_SCANCODE_LGUI, 0xdb }, + { SDL_SCANCODE_LALT, 0x38 }, + { SDL_SCANCODE_RSHIFT, 0x36 }, + { SDL_SCANCODE_RCTRL, 0x9d }, + { SDL_SCANCODE_RGUI, 0xdc }, + { SDL_SCANCODE_RALT, 0xb8 }, + { SDL_SCANCODE_SYSREQ, 0x54 }, + { SDL_SCANCODE_APPLICATION, 0xdd }, + { SDL_SCANCODE_RETURN, 0x1c }, + { SDL_SCANCODE_ESCAPE, 0x01 }, + { SDL_SCANCODE_F1, 0x3B }, + { SDL_SCANCODE_F2, 0x3C }, + { SDL_SCANCODE_F3, 0x3D }, + { SDL_SCANCODE_F4, 0x3e }, + { SDL_SCANCODE_F5, 0x3f }, + { SDL_SCANCODE_F6, 0x40 }, + { SDL_SCANCODE_F7, 0x41 }, + { SDL_SCANCODE_F8, 0x42 }, + { SDL_SCANCODE_F9, 0x43 }, + { SDL_SCANCODE_F10, 0x44 }, + { SDL_SCANCODE_F11, 0x57 }, + { SDL_SCANCODE_F12, 0x58 }, + { SDL_SCANCODE_SCROLLLOCK, 0x46 }, + { SDL_SCANCODE_LEFTBRACKET, 0x1a }, + { SDL_SCANCODE_RIGHTBRACKET, 0x1b }, + { SDL_SCANCODE_INSERT, 0xd2 }, + { SDL_SCANCODE_HOME, 0xc7 }, + { SDL_SCANCODE_PAGEUP, 0xc9 }, + { SDL_SCANCODE_DELETE, 0xd3 }, + { SDL_SCANCODE_END, 0xcf }, + { SDL_SCANCODE_PAGEDOWN, 0xd1 }, + { SDL_SCANCODE_UP, 0xc8 }, + { SDL_SCANCODE_LEFT, 0xcb }, + { SDL_SCANCODE_DOWN, 0xd0 }, + { SDL_SCANCODE_RIGHT, 0xcd }, + { SDL_SCANCODE_NUMLOCKCLEAR, 0x45 }, + { SDL_SCANCODE_KP_DIVIDE, 0xb5 }, + { SDL_SCANCODE_KP_MULTIPLY, 0x37 }, + { SDL_SCANCODE_KP_MINUS, 0x4a }, + { SDL_SCANCODE_KP_PLUS, 0x4e }, + { SDL_SCANCODE_KP_ENTER, 0x9c }, + { SDL_SCANCODE_KP_PERIOD, 0x53 }, + { SDL_SCANCODE_KP_0, 0x52 }, + { SDL_SCANCODE_KP_1, 0x4f }, + { SDL_SCANCODE_KP_2, 0x50 }, + { SDL_SCANCODE_KP_3, 0x51 }, + { SDL_SCANCODE_KP_4, 0x48 }, + { SDL_SCANCODE_KP_5, 0x4c }, + { SDL_SCANCODE_KP_6, 0x4d }, + { SDL_SCANCODE_KP_7, 0x47 }, + { SDL_SCANCODE_KP_8, 0x48 }, + { SDL_SCANCODE_KP_9, 0x49 }, + { SDL_SCANCODE_SEMICOLON, 0x27 }, + { SDL_SCANCODE_APOSTROPHE, 0x28 }, + { SDL_SCANCODE_COMMA, 0x33 }, + { SDL_SCANCODE_PERIOD, 0x34 }, + { SDL_SCANCODE_SLASH, 0x35 }, + { SDL_SCANCODE_PRINTSCREEN, 0xb7 } +}; + +int sdl_scancode(SDL_Scancode scancode) +{ + int i; + for (i = 0; i < SDL_arraysize(SDLScancodeToSystemScancode); ++i) { + if (SDLScancodeToSystemScancode[i].sdl == scancode) { + return SDLScancodeToSystemScancode[i].system; + } + } + return -1; +} + +SDL_Event event; +SDL_Rect rect; +int border_x, border_y = 0; + +uint64_t render_time = 0; +int render_fps = 0; +uint32_t render_frame_time = 0; +uint32_t render_frames = 0; + +void window_setup() +{ + SDL_SetHint(SDL_HINT_GRAB_KEYBOARD, "1"); +#if SDL_VERSION_ATLEAST(2, 0, 5) + SDL_SetHint(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, "1"); +#endif + + if (start_in_fullscreen) + { + start_in_fullscreen = 0; + window_dofullscreen = 1; + window_doinputgrab = 1; + } + + if (window_remember) + { + rect.x = window_x; + rect.y = window_y; + rect.w = window_w; + rect.h = window_h; + } + else + { + rect.x = SDL_WINDOWPOS_CENTERED; + rect.y = SDL_WINDOWPOS_CENTERED; + rect.w = 640; + rect.h = 480; + } +} + +#ifdef __WINDOWS__ +int sdl_winhook(int code) +{ + switch(code) + { + case VK_LMENU: + return SDL_SCANCODE_LALT; + case VK_LCONTROL: + return SDL_SCANCODE_LCTRL; + case VK_LWIN: + return SDL_SCANCODE_LGUI; + case VK_LSHIFT: + return SDL_SCANCODE_LSHIFT; + case VK_RMENU: + return SDL_SCANCODE_RALT; + case VK_RCONTROL: + return SDL_SCANCODE_RCTRL; + case VK_RWIN: + return SDL_SCANCODE_RGUI; + case VK_RSHIFT: + return SDL_SCANCODE_RSHIFT; + } + + return -1; +} + +LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) +{ + KBDLLHOOKSTRUCT* p = (KBDLLHOOKSTRUCT*)lParam; + + int c = p->vkCode; + + int steal = 0; + int s = sdl_winhook(c); + if (s != -1) + { + int key_state = !(p->flags & LLKHF_UP); + if (abs(modkeystate[c]) != key_state) + { + /* if mousecapture is 0, key_state should be negative */ + if (!mousecapture) + key_state = -key_state; + /* if key_state is 0 and modkeystate[c] is negative, + an sdl_event should not generated */ + if (key_state > 0 || modkeystate[c] > 0) + { + steal = 1; + SDL_Event event; + event.key.keysym.scancode = s; + + event.type = key_state ? SDL_KEYDOWN : SDL_KEYUP; + SDL_PushEvent(&event); + } + modkeystate[c] = key_state; + } + if (steal) + return 1; + } + + return CallNextHookEx( hKeyboardHook, nCode, wParam, lParam ); +} +#endif + +int window_create() +{ + window = SDL_CreateWindow("PCem Display", + rect.x, rect.y, rect.w, rect.h, + vid_resize ? SDL_WINDOW_RESIZABLE : 0); + if (!window) + { + char message[200]; + sprintf(message, + "SDL window could not be created! Error: %s\n", + SDL_GetError()); + wx_messagebox(ghwnd, message, "SDL Error", WX_MB_OK); + return 0; + } + +#ifdef __WINDOWS__ + memset(modkeystate, 0, sizeof(modkeystate)); + hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, GetModuleHandle(NULL), 0); +#endif + + render_time = 0; + render_fps = 0; + render_frame_time = SDL_GetTicks(); + render_frames = 0; + return 1; +} + +void window_close() +{ +#ifdef __WINDOWS__ + UnhookWindowsHookEx( hKeyboardHook ); +#endif + + sdl_renderer_close(); + + if (window) { + SDL_GetWindowPosition(window, &rect.x, &rect.y); + SDL_GetWindowSize(window, &rect.w, &rect.h); + get_border_size(&border_y, &border_x, 0, 0); + rect.x -= border_x; + rect.y -= border_y; + + SDL_DestroyWindow(window); + } + window = NULL; +} + +int render() +{ + uint64_t start_time = timer_read(); + uint64_t end_time; + + if (window_doreset) + { + pclog("window_doreset\n"); + window_doreset = 0; + renderer_doreset = 0; + return 0; + } + if (renderer_doreset) + { + pclog("renderer_doreset\n"); + renderer_doreset = 0; + sdl_renderer_close(); + sdl_renderer_init(window); + + device_force_redraw(); + video_wait_for_blit(); + } + while(SDL_PollEvent(&event)) + { + switch (event.type) { + case SDL_MOUSEBUTTONUP: + if (!mousecapture) + { + if (event.button.button == SDL_BUTTON_LEFT && !pause) + { + window_doinputgrab = 1; + if (video_fullscreen) { + window_dofullscreen = 1; + } + } else if (event.button.button == SDL_BUTTON_RIGHT) + { + wx_popupmenu(ghwnd, menu, 0, 0); + } + } + break; + case SDL_MOUSEWHEEL: + if (mousecapture) mouse_wheel_update(event.wheel.y); + break; + case SDL_WINDOWEVENT: + if (event.window.event == SDL_WINDOWEVENT_CLOSE) { + wx_stop_emulation(ghwnd); + } + if (event.window.event == SDL_WINDOWEVENT_FOCUS_LOST) + { + if (is_fullscreen()) + window_dowindowed = 1; + window_doinputrelease = 1; + } + + if (window_remember) { + int flags = SDL_GetWindowFlags(window); + if (!(flags&SDL_WINDOW_FULLSCREEN) && !(flags&SDL_WINDOW_FULLSCREEN_DESKTOP)) { + if (event.window.event == SDL_WINDOWEVENT_MOVED) { + get_border_size(&border_x, &border_y, 0, 0); + window_x = event.window.data1-border_x; + window_y = event.window.data2-border_y; + } else if (event.window.event == SDL_WINDOWEVENT_RESIZED) { + window_w = event.window.data1; + window_h = event.window.data2; + } + //save_window_pos = 1; + } + } + + break; + case SDL_KEYDOWN: + { +#ifdef __WINDOWS__ + /* international keyboard workaround */ + if (event.key.keysym.scancode == SDL_SCANCODE_RALT && + (event.key.keysym.mod&KMOD_LCTRL) && + event.key.timestamp == rawinputkey[sdl_scancode(SDL_SCANCODE_LCTRL)]) + rawinputkey[sdl_scancode(SDL_SCANCODE_LCTRL)] = 0; +#endif + int key_idx = sdl_scancode(event.key.keysym.scancode); + if (key_idx != -1) + rawinputkey[key_idx] = 1; + break; + } + case SDL_KEYUP: + { + int key_idx = sdl_scancode(event.key.keysym.scancode); + if (key_idx != -1) + rawinputkey[key_idx] = 0; + break; + } + } + } + if (rawinputkey[sdl_scancode(SDL_SCANCODE_PAGEDOWN)] && + (rawinputkey[sdl_scancode(SDL_SCANCODE_LCTRL)] || rawinputkey[sdl_scancode(SDL_SCANCODE_RCTRL)]) && + (rawinputkey[sdl_scancode(SDL_SCANCODE_LALT)] || rawinputkey[sdl_scancode(SDL_SCANCODE_RALT)])) + trigger_fullscreen = 1; + else if (trigger_fullscreen) + { + trigger_fullscreen = 0; + toggle_fullscreen(); + } +// if (event.key.keysym.scancode == SDL_SCANCODE_PAGEUP && +// (rawinputkey[sdl_scancode(SDL_SCANCODE_LCTRL)] || rawinputkey[sdl_scancode(SDL_SCANCODE_RCTRL)]) && +// (rawinputkey[sdl_scancode(SDL_SCANCODE_LALT)] || rawinputkey[sdl_scancode(SDL_SCANCODE_RALT)])) +// trigger_togglewindow = 1; +// else if (trigger_togglewindow) +// { +// trigger_togglewindow = 0; +// wx_togglewindow(ghwnd); +// } + else if (event.key.keysym.scancode == SDL_SCANCODE_END && + (rawinputkey[sdl_scancode(SDL_SCANCODE_LCTRL)] || rawinputkey[sdl_scancode(SDL_SCANCODE_RCTRL)])) + trigger_inputrelease = 1; + else if (trigger_inputrelease) + { + trigger_inputrelease = 0; + if (!is_fullscreen()) + window_doinputrelease = 1; + } + if (window_doremember) { + window_doremember = 0; + SDL_GetWindowPosition(window, &window_x, &window_y); + SDL_GetWindowSize(window, &window_w, &window_h); + get_border_size(&border_y, &border_x, 0, 0); + window_x -= border_x; + window_y -= border_y; + saveconfig(NULL); + } + + if (window_dotogglefullscreen) + { + window_dotogglefullscreen = 0; + if (SDL_GetWindowGrab(window) || is_fullscreen()) + { + window_doinputrelease = 1; + if (is_fullscreen()) + window_dowindowed = 1; + } + else + { + window_doinputgrab = 1; + window_dofullscreen = 1; + } + } + + if (window_dofullscreen) + { + window_dofullscreen = 0; + video_wait_for_blit(); + SDL_RaiseWindow(window); +#if SDL_VERSION_ATLEAST(2, 0, 4) + SDL_GetGlobalMouseState(&remembered_mouse_x, &remembered_mouse_y); +#endif + SDL_GetWindowPosition(window, &remembered_rect.x, &remembered_rect.y); + get_border_size(&border_y, &border_x, 0, 0); + remembered_rect.x -= border_x; + remembered_rect.y -= border_y; + SDL_GetWindowSize(window, &remembered_rect.w, &remembered_rect.h); + SDL_SetWindowFullscreen(window, video_fullscreen_mode == 0 ? SDL_WINDOW_FULLSCREEN_DESKTOP : SDL_WINDOW_FULLSCREEN); + } + if (window_doinputgrab) { + window_doinputgrab = 0; + mousecapture = 1; + SDL_GetRelativeMouseState(0, 0); + SDL_SetWindowGrab(window, SDL_TRUE); + SDL_SetRelativeMouseMode(SDL_TRUE); + } + + if (window_doinputrelease) { + window_doinputrelease = 0; + mousecapture = 0; + SDL_SetWindowGrab(window, SDL_FALSE); + SDL_SetRelativeMouseMode(SDL_FALSE); + } + if (window_dowindowed) + { + window_dowindowed = 0; + SDL_SetWindowFullscreen(window, 0); + SDL_SetWindowSize(window, remembered_rect.w, remembered_rect.h); + SDL_SetWindowPosition(window, remembered_rect.x, remembered_rect.y); +#if SDL_VERSION_ATLEAST(2, 0, 4) + SDL_WarpMouseGlobal(remembered_mouse_x, remembered_mouse_y); +#endif + } + + if (win_doresize) + { + win_doresize = 0; + if (!vid_resize || (flags&SDL_WINDOW_FULLSCREEN)) { + SDL_GetWindowSize(window, &rect.w, &rect.h); + if (rect.w != winsizex || rect.h != winsizey) { + SDL_GetWindowPosition(window, &rect.x, &rect.y); + SDL_SetWindowSize(window, winsizex, winsizey); + SDL_SetWindowPosition(window, rect.x, rect.y); + device_force_redraw(); + } + } + } + + if (sdl_renderer_update(window)) sdl_renderer_present(window); + + end_time = timer_read(); + render_time += end_time - start_time; + + ++render_frames; + uint32_t ticks = SDL_GetTicks(); + if (ticks-render_frame_time >= 1000) { + render_fps = render_frames/((ticks-render_frame_time)/1000.0); + render_frames = 0; + render_frame_time = ticks; + } + + return 1; +} + +int renderer_thread(void* params) +{ + int internal_rendering; + + SDL_LockMutex(rendererMutex); + SDL_CondSignal(rendererCond); + SDL_UnlockMutex(rendererMutex); + + window_setup(); + + rendering = 1; + while (rendering) { + + if (!window_create()) + rendering = 0; + + renderer_doreset = 1; + internal_rendering = 1; + while (rendering && internal_rendering) + { + if (!render()) + internal_rendering = 0; + + SDL_Delay(1); + } + window_close(); + } + + SDL_LockMutex(rendererMutex); + SDL_CondSignal(rendererCond); + SDL_UnlockMutex(rendererMutex); + + return SDL_TRUE; +} + +void* timer = 0; + +void render_timer() +{ +#ifdef PCEM_RENDER_TIMER_LOOP + /* For some reason this while-loop works on OSX, which also fixes missing events. No idea why though. */ + renderer_thread(0); +#else + if (rendering && !render()) + { + window_close(); + window_create(); + renderer_doreset = 1; + } +#endif +} + +void render_start_timer() +{ +#ifdef PCEM_RENDER_TIMER_LOOP + timer = wx_createtimer(render_timer); + wx_starttimer(timer, 500, 1); +#else + window_setup(); + if (window_create()) + { + rendering = 1; + renderer_doreset = 1; + wx_starttimer(timer, 1, 0); + } +#endif +} + +void renderer_start() +{ + if (!rendering) + { +#ifdef PCEM_RENDER_WITH_TIMER + render_start_timer(); +#else + SDL_LockMutex(rendererMutex); + renderthread = SDL_CreateThread(renderer_thread, "SDL2 Thread", NULL); + SDL_CondWait(rendererCond, rendererMutex); + SDL_UnlockMutex(rendererMutex); +#endif + } +} + +void renderer_stop(int timeout) +{ +#if defined(PCEM_RENDER_WITH_TIMER) && !defined(PCEM_RENDER_TIMER_LOOP) + rendering = 0; + window_close(); + wx_destroytimer(timer); +#else + if (rendering) + { + SDL_LockMutex(rendererMutex); + rendering = 0; + if (timeout) + SDL_CondWaitTimeout(rendererCond, rendererMutex, timeout); + else + SDL_CondWait(rendererCond, rendererMutex); + SDL_UnlockMutex(rendererMutex); + renderthread = NULL; + } + if (timer) + wx_destroytimer(timer); +#endif +} diff --git a/src/wx-sdl2-hdconf.c b/src/wx-sdl2-hdconf.c new file mode 100644 index 0000000..f462cb1 --- /dev/null +++ b/src/wx-sdl2-hdconf.c @@ -0,0 +1,956 @@ +#include "wx-utils.h" +#include "wx-sdl2.h" + +#include "ibm.h" +#include "ide.h" +#include "hdd.h" + +static struct +{ + int cylinders; + int heads; +} hd_types[] = +{ + {306, 4}, {615, 4}, {615, 6}, {940, 8}, + {940, 6}, {615, 4}, {462, 8}, {733, 5}, + {900, 15}, {820, 3}, {855, 5}, {855, 7}, + {306, 8}, {733, 7}, {0, 0}, {612, 4}, + {977, 5}, {977, 7}, {1024, 7}, {733, 5}, + {733, 7}, {733, 5}, {306, 4}, {925, 7}, + {925, 9}, {754, 7}, {754, 11}, {699, 7}, + {823, 10}, {918, 7}, {1024, 11}, {1024, 15}, + {1024, 5}, {612, 2}, {1024, 9}, {1024, 8}, + {615, 8}, {987, 3}, {462, 7}, {820, 6}, + {977, 5}, {981, 5}, {830, 7}, {830, 10}, + {917, 15}, {1224, 15} +}; + +static int hd_changed = 0; + +static char hd_new_name[512]; +static int hd_new_spt, hd_new_hpc, hd_new_cyl; +static int hd_new_type; +static int new_cdrom_channel; + +extern int pause; + +static void check_hd_type(off64_t sz) +{ + int c; + + hd_new_type = 0; + + if (hdd_controller_current_is_mfm()) + { + for (c = 0; c < 46; c++) + { + if ((hd_types[c].cylinders * hd_types[c].heads * 17 * 512) == sz) + { + hd_new_spt = 17; + hd_new_hpc = hd_types[c].heads; + hd_new_cyl = hd_types[c].cylinders; + hd_new_type = c+1; + return; + } + } + hd_new_spt = 63; + hd_new_hpc = 16; + hd_new_cyl = ((sz / 512) / 16) / 63; + } + else + { + if ((sz % 17) == 0 && sz <= 133693440) + { + hd_new_spt = 17; + + if (sz <= 26738688) + hd_new_hpc = 4; + else if (sz <= 53477376) + hd_new_hpc = 6; + else if (sz <= 71303168) + hd_new_hpc = 8; + else + hd_new_hpc = 15; + + hd_new_cyl = (int)((sz / 512) / hd_new_hpc) / 17; + } + else + { + hd_new_spt = 63; + hd_new_hpc = 16; + hd_new_cyl = ((sz / 512) / 16) / 63; + } + } +} + +#define ID_IS(s) wParam == wx_xrcid(s) +#define ID_RANGE(a, b) wParam >= wx_xrcid(a) && wParam <= wx_xrcid(b) + +static void update_hdd_cdrom(void* hdlg) +{ + void* h; + + h = wx_getdlgitem(hdlg, WX_ID("IDC_HDD[0]")); + wx_sendmessage(h, WX_BM_SETCHECK, (new_cdrom_channel == 0) ? 0 : 1, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_CDROM[0]")); + wx_sendmessage(h, WX_BM_SETCHECK, (new_cdrom_channel == 0) ? 1 : 0, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_HDD[1]")); + wx_sendmessage(h, WX_BM_SETCHECK, (new_cdrom_channel == 1) ? 0 : 1, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_CDROM[1]")); + wx_sendmessage(h, WX_BM_SETCHECK, (new_cdrom_channel == 1) ? 1 : 0, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_HDD[2]")); + wx_sendmessage(h, WX_BM_SETCHECK, (new_cdrom_channel == 2) ? 0 : 1, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_CDROM[2]")); + wx_sendmessage(h, WX_BM_SETCHECK, (new_cdrom_channel == 2) ? 1 : 0, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_HDD[3]")); + wx_sendmessage(h, WX_BM_SETCHECK, (new_cdrom_channel == 3) ? 0 : 1, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_CDROM[3]")); + wx_sendmessage(h, WX_BM_SETCHECK, (new_cdrom_channel == 3) ? 1 : 0, 0); +} + +static int hdnew_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) +{ + char s[260]; + void* h; + int c; + PcemHDC hd[4]; + FILE *f; + uint8_t buf[512]; + int hd_type; + + switch (message) + { + case WX_INITDIALOG: + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT1")); + sprintf(s, "%i", 63); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT2")); + sprintf(s, "%i", 16); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT3")); + sprintf(s, "%i", 511); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDITC")); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)""); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT1")); + sprintf(s, "Size : %imb", (((511*16*63)*512)/1024)/1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + +// hd_type = 0; + h = wx_getdlgitem(hdlg, WX_ID("IDC_HDTYPE")); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"Custom type"); + for (c = 1; c <= 46; c++) + { + sprintf(s, "Type %02i : cylinders=%i, heads=%i, size=%iMB", c, hd_types[c-1].cylinders, hd_types[c-1].heads, (hd_types[c-1].cylinders * hd_types[c-1].heads * 17 * 512) / (1024 * 1024)); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)s); + } + wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); + + return TRUE; + case WX_COMMAND: + if (wParam == wxID_OK) { + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDITC")); + wx_sendmessage(h, WX_WM_GETTEXT, 511, (LONG_PARAM)hd_new_name); + if (!hd_new_name[0]) + { + wx_messagebox(NULL,"Please enter a valid filename","PCem error",WX_MB_OK); + return TRUE; + } + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT1")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd_new_spt); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT2")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd_new_hpc); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT3")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd_new_cyl); + + if (hd_new_spt > 63) + { + wx_messagebox(NULL, "Drive has too many sectors (maximum is 63)", "PCem error", WX_MB_OK); + return TRUE; + } + if (hd_new_hpc > 16) + { + wx_messagebox(NULL, "Drive has too many heads (maximum is 16)", "PCem error", WX_MB_OK); + return TRUE; + } + if (hd_new_cyl > 16383) + { + wx_messagebox(NULL, "Drive has too many cylinders (maximum is 16383)", "PCem error", WX_MB_OK); + return TRUE; + } + + f = fopen64(hd_new_name, "wb"); + if (!f) + { + wx_messagebox(NULL, "Can't open file for write", "PCem error", WX_MB_OK); + return TRUE; + } + memset(buf, 0, 512); + for (c = 0; c < (hd_new_cyl * hd_new_hpc * hd_new_spt); c++) + fwrite(buf, 512, 1, f); + fclose(f); + + wx_messagebox(NULL, "Remember to partition and format the new drive", "PCem", WX_MB_OK); + + wx_enddialog(hdlg, 1); + return TRUE; + } else if (wParam == wxID_CANCEL) { + wx_enddialog(hdlg, 0); + return TRUE; + } else if (ID_IS("IDC_CFILE")) { + if (!getsfile(hdlg, "Hard disc image (*.img)|*.img|All files (*.*)|*.*", "", NULL, "img")) + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDITC")); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM) openfilestring); + } + return TRUE; + } else if (ID_IS("IDC_EDIT1") || ID_IS("IDC_EDIT2") || ID_IS("IDC_EDIT3")) { + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT1")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + pclog("EDIT1: %s\n", s); + sscanf(s, "%i", &hd[0].spt); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT2")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + pclog("EDIT2: %s\n", s); + sscanf(s, "%i", &hd[0].hpc); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT3")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + pclog("EDIT3: %s\n", s); + sscanf(s, "%i", &hd[0].tracks); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT1")); + sprintf(s, "Size : %imb", (int)(((((uint64_t)hd[0].tracks*(uint64_t)hd[0].hpc)*(uint64_t)hd[0].spt)*512)/1024)/1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + + hd_type = 0; + for (c = 1; c <= 46; c++) + { + pclog("Compare %i,%i %i,%i %i,%i\n", hd[0].spt,17, hd[0].hpc,hd_types[c-1].heads, hd[0].tracks,hd_types[c-1].cylinders); + if (hd[0].spt == 17 && hd[0].hpc == hd_types[c-1].heads && hd[0].tracks == hd_types[c-1].cylinders) + { + hd_type = c; + break; + } + } + h = wx_getdlgitem(hdlg, WX_ID("IDC_HDTYPE")); + wx_sendmessage(h, WX_CB_SETCURSEL, hd_type, 0); + + return TRUE; + } else if (ID_IS("IDC_HDTYPE")) { + h = wx_getdlgitem(hdlg, WX_ID("IDC_HDTYPE")); + hd_type = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + if (hd_type) + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT3")); + sprintf(s, "%i", hd_types[hd_type-1].cylinders); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT2")); + sprintf(s, "%i", hd_types[hd_type-1].heads); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT1")); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)"17"); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT1")); + sprintf(s, "Size : %imb", (int)(((uint64_t)hd_types[hd_type-1].cylinders*hd_types[hd_type-1].heads*17*512)/1024)/1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + } + return TRUE; + } + break; + + } + return FALSE; +} + +static int hdsize_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) +{ + char s[260]; + void* h; + PcemHDC hd[2]; + int c; + + switch (message) + { + case WX_INITDIALOG: + h = wx_getdlgitem(hdlg, WX_ID("IDC_HDTYPE")); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"Custom type"); + for (c = 1; c <= 46; c++) + { + sprintf(s, "Type %02i : cylinders=%i, heads=%i, size=%iMB", c, hd_types[c-1].cylinders, hd_types[c-1].heads, (hd_types[c-1].cylinders * hd_types[c-1].heads * 17 * 512) / (1024 * 1024)); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)s); + } + wx_sendmessage(h, WX_CB_SETCURSEL, hd_new_type, 0); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT1")); + sprintf(s, "%i", hd_new_spt); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT2")); + sprintf(s, "%i", hd_new_hpc); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT3")); + sprintf(s, "%i", hd_new_cyl); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT1")); + sprintf(s, "Size : %imb", (int)((((uint64_t)hd_new_spt*(uint64_t)hd_new_hpc*(uint64_t)hd_new_cyl)*512)/1024)/1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + + return TRUE; + case WX_COMMAND: + if (wParam == wxID_OK) { + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT1")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd_new_spt); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT2")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd_new_hpc); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT3")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd_new_cyl); + + if (hd_new_spt > 63) + { + wx_messagebox(NULL,"Drive has too many sectors (maximum is 63)","PCem error",WX_MB_OK); + return TRUE; + } + if (hd_new_hpc > 16) + { + wx_messagebox(NULL,"Drive has too many heads (maximum is 16)","PCem error",WX_MB_OK); + return TRUE; + } + if (hd_new_cyl > 16383) + { + wx_messagebox(NULL,"Drive has too many cylinders (maximum is 16383)","PCem error",WX_MB_OK); + return TRUE; + } + + wx_enddialog(hdlg,1); + return TRUE; + } else if (wParam == wxID_CANCEL) { + wx_enddialog(hdlg,0); + return TRUE; + } else if (ID_IS("IDC_EDIT1") || ID_IS("IDC_EDIT2") || ID_IS("IDC_EDIT3")) { + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT1")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[0].spt); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT2")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[0].hpc); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT3")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[0].tracks); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT1")); + sprintf(s, "Size : %imb", (int)(((((uint64_t)hd[0].tracks*(uint64_t)hd[0].hpc)*(uint64_t)hd[0].spt)*512)/1024)/1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + return TRUE; + } + + } + return FALSE; +} + +static int hdconf_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) +{ + char s[260]; + void* h; + PcemHDC hd[4]; + FILE *f; + off64_t sz; + switch (message) + { + case WX_INITDIALOG: + pause = 1; + hd[0] = hdc[0]; + hd[1] = hdc[1]; + hd[2] = hdc[2]; + hd[3] = hdc[3]; + hd_changed = 0; + + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[0]")); + sprintf(s, "%i", hdc[0].spt); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[0]")); + sprintf(s, "%i", hdc[0].hpc); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[0]")); + sprintf(s, "%i", hdc[0].tracks); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[0]")); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)ide_fn[0]); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[1]")); + sprintf(s, "%i", hdc[1].spt); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[1]")); + sprintf(s, "%i", hdc[1].hpc); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[1]")); + sprintf(s, "%i", hdc[1].tracks); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h= wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[1]")); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)ide_fn[1]); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[2]")); + sprintf(s, "%i", hdc[2].spt); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[2]")); + sprintf(s, "%i", hdc[2].hpc); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[2]")); + sprintf(s, "%i", hdc[2].tracks); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h= wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[2]")); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)ide_fn[2]); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[3]")); + sprintf(s, "%i", hdc[3].spt); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[3]")); + sprintf(s, "%i", hdc[3].hpc); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[3]")); + sprintf(s, "%i", hdc[3].tracks); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h= wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[3]")); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)ide_fn[3]); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[0]")); + sprintf(s, "Size : %imb", (int)(((((uint64_t)hd[0].tracks*(uint64_t)hd[0].hpc)*(uint64_t)hd[0].spt)*512)/1024)/1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[1]")); + sprintf(s, "Size : %imb", (int)(((((uint64_t)hd[1].tracks*(uint64_t)hd[1].hpc)*(uint64_t)hd[1].spt)*512)/1024)/1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[2]")); + sprintf(s, "Size : %imb", (int)(((((uint64_t)hd[2].tracks*(uint64_t)hd[2].hpc)*(uint64_t)hd[2].spt)*512)/1024)/1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[3]")); + sprintf(s, "Size : %imb", (int)(((((uint64_t)hd[3].tracks*(uint64_t)hd[3].hpc)*(uint64_t)hd[3].spt)*512)/1024)/1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + + new_cdrom_channel = cdrom_channel; + + update_hdd_cdrom(hdlg); + + if (hdd_controller_current_is_mfm()) { + wx_enablewindow(wx_getdlgitem(hdlg, WX_ID("IDC_PANEL[2]")), 0); + wx_enablewindow(wx_getdlgitem(hdlg, WX_ID("IDC_PANEL[3]")), 0); + wx_enablewindow(wx_getdlgitem(hdlg, WX_ID("IDC_HDD[0]")), 0); + wx_enablewindow(wx_getdlgitem(hdlg, WX_ID("IDC_HDD[1]")), 0); + wx_enablewindow(wx_getdlgitem(hdlg, WX_ID("IDC_CDROM[0]")), 0); + wx_enablewindow(wx_getdlgitem(hdlg, WX_ID("IDC_CDROM[1]")), 0); + } + return TRUE; + + case WX_COMMAND: + if (wParam == wxID_OK) + { + if (hd_changed || cdrom_channel != new_cdrom_channel) + { + if (!has_been_inited || confirm()) + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[0]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[0].spt); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[0]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[0].hpc); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[0]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[0].tracks); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[0]")); + wx_sendmessage(h, WX_WM_GETTEXT, 511, (LONG_PARAM)ide_fn[0]); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[1]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[1].spt); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[1]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[1].hpc); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[1]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[1].tracks); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[1]")); + wx_sendmessage(h, WX_WM_GETTEXT, 511, (LONG_PARAM)ide_fn[1]); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[2]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[2].spt); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[2]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[2].hpc); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[2]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[2].tracks); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[2]")); + wx_sendmessage(h, WX_WM_GETTEXT, 511, (LONG_PARAM)ide_fn[2]); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[3]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[3].spt); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[3]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[3].hpc); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[3]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[3].tracks); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[3]")); + wx_sendmessage(h, WX_WM_GETTEXT, 511, (LONG_PARAM)ide_fn[3]); + + hdc[0] = hd[0]; + hdc[1] = hd[1]; + hdc[2] = hd[2]; + hdc[3] = hd[3]; + + cdrom_channel = new_cdrom_channel; + + if (has_been_inited) + { + saveconfig(NULL); + + resetpchard(); + } + } + } + } + if (wParam == wxID_OK || wParam == wxID_CANCEL) + { + wx_enddialog(hdlg, 0); + pause = 0; + return TRUE; + } else if (ID_IS("IDC_EJECT[0]")) + { + hd[0].spt = 0; + hd[0].hpc = 0; + hd[0].tracks = 0; + ide_fn[0][0] = 0; + wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_SPT[0]"), "0"); + wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_HPC[0]"), "0"); + wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_CYL[0]"), "0"); + wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_FN[0]"), ""); + hd_changed = 1; + return TRUE; + } else if (ID_IS("IDC_EJECT[1]")) + { + hd[1].spt = 0; + hd[1].hpc = 0; + hd[1].tracks = 0; + ide_fn[1][0] = 0; + wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_SPT[1]"), "0"); + wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_HPC[1]"), "0"); + wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_CYL[1]"), "0"); + wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_FN[1]"), ""); + hd_changed = 1; + return TRUE; + } else if (ID_IS("IDC_EJECT[2]")) + { + hd[2].spt = 0; + hd[2].hpc = 0; + hd[2].tracks = 0; + ide_fn[2][0] = 0; + wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_SPT[2]"), "0"); + wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_HPC[2]"), "0"); + wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_CYL[2]"), "0"); + wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_FN[2]"), ""); + hd_changed = 1; + return TRUE; + } else if (ID_IS("IDC_EJECT[3]")) + { + hd[3].spt = 0; + hd[3].hpc = 0; + hd[3].tracks = 0; + ide_fn[3][0] = 0; + wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_SPT[3]"), "0"); + wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_HPC[3]"), "0"); + wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_CYL[3]"), "0"); + wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_FN[3]"), ""); + hd_changed = 1; + return TRUE; + } + else if (ID_IS("IDC_NEW[0]")) + { + if (wx_dialogbox(hdlg, "HdNewDlg", hdnew_dlgproc) == 1) + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[0]")); + sprintf(s, "%i", hd_new_spt); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[0]")); + sprintf(s, "%i", hd_new_hpc); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[0]")); + sprintf(s, "%i", hd_new_cyl); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[0]")); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)hd_new_name); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[0]")); + sprintf(s, "Size : %imb", (int)(((((uint64_t)hd_new_cyl*(uint64_t)hd_new_hpc)*(uint64_t)hd_new_spt)*512)/1024)/1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + + hd_changed = 1; + } + return TRUE; + } + else if (ID_IS("IDC_FILE[0]")) + { + if (!getfile(hdlg, "Hard disc image (*.img)|*.img|All files (*.*)|*.*", "")) + { + f = fopen64(openfilestring, "rb"); + if (!f) + { + wx_messagebox(NULL,"Can't open file for read","PCem error",WX_MB_OK); + return TRUE; + } + fseeko64(f, -1, SEEK_END); + sz = ftello64(f) + 1; + fclose(f); + check_hd_type(sz); + + if (wx_dialogbox(hdlg, "HdSizeDlg", hdsize_dlgproc) == 1) + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[0]")); + sprintf(s, "%i", hd_new_spt); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[0]")); + sprintf(s, "%i", hd_new_hpc); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[0]")); + sprintf(s, "%i", hd_new_cyl); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[0]")); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)openfilestring); + + h= wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[0]")); + sprintf(s, "Size : %imb", (int)(((((uint64_t)hd_new_cyl*(uint64_t)hd_new_hpc)*(uint64_t)hd_new_spt)*512)/1024)/1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + + hd_changed = 1; + } + } + return TRUE; + + } + else if (ID_IS("IDC_NEW[1]")) + { + if (wx_dialogbox(hdlg, "HdNewDlg", hdnew_dlgproc) == 1) + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[1]")); + sprintf(s, "%i", hd_new_spt); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[1]")); + sprintf(s, "%i", hd_new_hpc); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[1]")); + sprintf(s, "%i", hd_new_cyl); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[1]")); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)hd_new_name); + + h= wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[1]")); + sprintf(s, "Size : %imb", (int)(((((uint64_t)hd_new_cyl*(uint64_t)hd_new_hpc)*(uint64_t)hd_new_spt)*512)/1024)/1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + + hd_changed = 1; + } + return TRUE; + } + else if (ID_IS("IDC_FILE[1]")) + { + if (!getfile(hdlg, "Hard disc image (*.img)|*.img|All files (*.*)|*.*", "")) + { + f = fopen64(openfilestring, "rb"); + if (!f) + { + wx_messagebox(NULL,"Can't open file for read","PCem error",WX_MB_OK); + return TRUE; + } + fseeko64(f, -1, SEEK_END); + sz = ftello64(f) + 1; + fclose(f); + check_hd_type(sz); + + if (wx_dialogbox(hdlg, "HdSizeDlg", hdsize_dlgproc) == 1) + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[1]")); + sprintf(s, "%i", hd_new_spt); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[1]")); + sprintf(s, "%i", hd_new_hpc); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[1]")); + sprintf(s, "%i", hd_new_cyl); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[1]")); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)openfilestring); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[1]")); + sprintf(s, "Size : %imb", (int)(((((uint64_t)hd_new_cyl*(uint64_t)hd_new_hpc)*(uint64_t)hd_new_spt)*512)/1024)/1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + + hd_changed = 1; + } + } + return TRUE; + } + else if (ID_IS("IDC_NEW[2]")) + { + if (wx_dialogbox(hdlg, "HdNewDlg", hdnew_dlgproc) == 1) + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[2]")); + sprintf(s, "%i", hd_new_spt); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[2]")); + sprintf(s, "%i", hd_new_hpc); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[2]")); + sprintf(s, "%i", hd_new_cyl); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[2]")); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)hd_new_name); + + h= wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[2]")); + sprintf(s, "Size : %imb", (int)(((((uint64_t)hd_new_cyl*(uint64_t)hd_new_hpc)*(uint64_t)hd_new_spt)*512)/1024)/1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + + hd_changed = 1; + } + return TRUE; + } + else if (ID_IS("IDC_FILE[2]")) + { + if (!getfile(hdlg, "Hard disc image (*.img)|*.img|All files (*.*)|*.*", "")) + { + f = fopen64(openfilestring, "rb"); + if (!f) + { + wx_messagebox(NULL,"Can't open file for read","PCem error",WX_MB_OK); + return TRUE; + } + fseeko64(f, -1, SEEK_END); + sz = ftello64(f) + 1; + fclose(f); + check_hd_type(sz); + + if (wx_dialogbox(hdlg, "HdSizeDlg", hdsize_dlgproc) == 1) + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[2]")); + sprintf(s, "%i", hd_new_spt); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[2]")); + sprintf(s, "%i", hd_new_hpc); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[2]")); + sprintf(s, "%i", hd_new_cyl); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[2]")); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)openfilestring); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[2]")); + sprintf(s, "Size : %imb", (int)(((((uint64_t)hd_new_cyl*(uint64_t)hd_new_hpc)*(uint64_t)hd_new_spt)*512)/1024)/1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + + hd_changed = 1; + } + } + return TRUE; + } + else if (ID_IS("IDC_NEW[3]")) + { + if (wx_dialogbox(hdlg, "HdNewDlg", hdnew_dlgproc) == 1) + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[3]")); + sprintf(s, "%i", hd_new_spt); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[3]")); + sprintf(s, "%i", hd_new_hpc); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[3]")); + sprintf(s, "%i", hd_new_cyl); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[3]")); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)hd_new_name); + + h= wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[3]")); + sprintf(s, "Size : %imb", (int)(((((uint64_t)hd_new_cyl*(uint64_t)hd_new_hpc)*(uint64_t)hd_new_spt)*512)/1024)/1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + + hd_changed = 1; + } + return TRUE; + } + else if (ID_IS("IDC_FILE[3]")) + { + if (!getfile(hdlg, "Hard disc image (*.img)|*.img|All files (*.*)|*.*", "")) + { + f = fopen64(openfilestring, "rb"); + if (!f) + { + wx_messagebox(NULL,"Can't open file for read","PCem error",WX_MB_OK); + return TRUE; + } + fseeko64(f, -1, SEEK_END); + sz = ftello64(f) + 1; + fclose(f); + check_hd_type(sz); + + if (wx_dialogbox(hdlg, "HdSizeDlg", hdsize_dlgproc) == 1) + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[3]")); + sprintf(s, "%i", hd_new_spt); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[3]")); + sprintf(s, "%i", hd_new_hpc); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[3]")); + sprintf(s, "%i", hd_new_cyl); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[3]")); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)openfilestring); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[3]")); + sprintf(s, "Size : %imb", (int)(((((uint64_t)hd_new_cyl*(uint64_t)hd_new_hpc)*(uint64_t)hd_new_spt)*512)/1024)/1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + + hd_changed = 1; + } + } + return TRUE; + } + else if (ID_IS("IDC_EDIT_SPT[0]") || ID_IS("IDC_EDIT_HPC[0]") || ID_IS("IDC_EDIT_CYL[0]")) + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[0]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[0].spt); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[0]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[0].hpc); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[0]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[0].tracks); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[0]")); + sprintf(s, "Size : %imb", ((((hd[0].tracks*hd[0].hpc)*hd[0].spt)*512)/1024)/1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + return TRUE; + } + else if (ID_IS("IDC_EDIT_SPT[1]") || ID_IS("IDC_EDIT_HPC[1]") || ID_IS("IDC_EDIT_CYL[1]")) + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[1]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[1].spt); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[1]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[1].hpc); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[1]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[1].tracks); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[1]")); + sprintf(s, "Size : %imb", ((((hd[1].tracks*hd[1].hpc)*hd[1].spt)*512)/1024)/1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + return TRUE; + } + else if (ID_IS("IDC_EDIT_SPT[2]") || ID_IS("IDC_EDIT_HPC[2]") || ID_IS("IDC_EDIT_CYL[2]")) + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[2]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[2].spt); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[2]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[2].hpc); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[2]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[2].tracks); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[2]")); + sprintf(s, "Size : %imb", ((((hd[2].tracks*hd[2].hpc)*hd[2].spt)*512)/1024)/1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + return TRUE; + } + else if (ID_IS("IDC_EDIT_SPT[3]") || ID_IS("IDC_EDIT_HPC[3]") || ID_IS("IDC_EDIT_CYL[3]")) + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[3]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[3].spt); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[3]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[3].hpc); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[3]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[3].tracks); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[3]")); + sprintf(s, "Size : %imb", ((((hd[3].tracks*hd[3].hpc)*hd[3].spt)*512)/1024)/1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + return TRUE; + } + else if (ID_IS("IDC_HDD[0]")) + { + if (new_cdrom_channel == 0) + new_cdrom_channel = -1; + update_hdd_cdrom(hdlg); + return TRUE; + } + else if (ID_IS("IDC_HDD[1]")) + { + if (new_cdrom_channel == 1) + new_cdrom_channel = -1; + update_hdd_cdrom(hdlg); + return TRUE; + } + else if (ID_IS("IDC_HDD[2]")) + { + if (new_cdrom_channel == 2) + new_cdrom_channel = -1; + update_hdd_cdrom(hdlg); + return TRUE; + } + else if (ID_IS("IDC_HDD[3]")) + { + if (new_cdrom_channel == 3) + new_cdrom_channel = -1; + update_hdd_cdrom(hdlg); + return TRUE; + + } + else if (ID_IS("IDC_CDROM[0]")) + { + new_cdrom_channel = 0; + update_hdd_cdrom(hdlg); + return TRUE; + } + else if (ID_IS("IDC_CDROM[1]")) + { + new_cdrom_channel = 1; + update_hdd_cdrom(hdlg); + return TRUE; + } + else if (ID_IS("IDC_CDROM[2]")) + { + new_cdrom_channel = 2; + update_hdd_cdrom(hdlg); + return TRUE; + } + else if (ID_IS("IDC_CDROM[3]")) + { + new_cdrom_channel = 3; + update_hdd_cdrom(hdlg); + return TRUE; + } + + } + return FALSE; +} + +void hdconf_open(void* hwnd) +{ + wx_dialogbox(hwnd, "HdConfDlg", hdconf_dlgproc); +} diff --git a/src/wx-sdl2-joystick.c b/src/wx-sdl2-joystick.c new file mode 100644 index 0000000..9aed5d7 --- /dev/null +++ b/src/wx-sdl2-joystick.c @@ -0,0 +1,15 @@ +#include "plat-joystick.h" + +int joysticks_present; +joystick_t joystick_state[MAX_JOYSTICKS]; + +void joystick_init() +{ + joysticks_present = 0; +} +void joystick_close() +{ +} +void joystick_poll() +{ +} diff --git a/src/wx-sdl2-keyboard.c b/src/wx-sdl2-keyboard.c new file mode 100644 index 0000000..df2cffe --- /dev/null +++ b/src/wx-sdl2-keyboard.c @@ -0,0 +1,23 @@ +#include "plat-keyboard.h" +#include + +int pcem_key[272]; +int rawinputkey[272]; + +void keyboard_init() +{ + memset(pcem_key, 0, sizeof(pcem_key)); +} + +void keyboard_close() +{ +} + +void keyboard_poll_host() +{ + int c; + + for (c = 0; c < 272; ++c) + pcem_key[c] = rawinputkey[c]; +} + diff --git a/src/wx-sdl2-midi.c b/src/wx-sdl2-midi.c new file mode 100644 index 0000000..9ad75b0 --- /dev/null +++ b/src/wx-sdl2-midi.c @@ -0,0 +1,14 @@ +#include +#include "plat-midi.h" + +void midi_init() +{ +} + +void midi_close() +{ +} + +void midi_write(uint8_t val) +{ +} diff --git a/src/wx-sdl2-mouse.c b/src/wx-sdl2-mouse.c new file mode 100644 index 0000000..1f61758 --- /dev/null +++ b/src/wx-sdl2-mouse.c @@ -0,0 +1,59 @@ +#include +#include "plat-mouse.h" + +int mouse_buttons; +static int mouse_x = 0, mouse_y = 0, mouse_z = 0; + +int mouse[3]; + +void mouse_init() +{ + memset(mouse, 0, sizeof(mouse)); +} + +void mouse_close() +{ +} + +void mouse_wheel_update(int dir) +{ + mouse[2] += dir; +} + +void mouse_poll_host() +{ + if (mousecapture) + { + uint32_t mb = SDL_GetRelativeMouseState(&mouse[0], &mouse[1]); + mouse_buttons = 0; + if (mb & SDL_BUTTON(SDL_BUTTON_LEFT)) + { + mouse_buttons |= 1; + } + if (mb & SDL_BUTTON(SDL_BUTTON_RIGHT)) + { + mouse_buttons |= 2; + } + if (mb & SDL_BUTTON(SDL_BUTTON_MIDDLE)) + { + mouse_buttons |= 4; + } + mouse_x += mouse[0]; + mouse_y += mouse[1]; + mouse_z += mouse[2]; + mouse[2] = 0; + } + else + { + mouse_x = mouse_y = mouse_z = mouse_buttons = 0; + } +} + +void mouse_get_mickeys(int *x, int *y, int *z) +{ + *x = mouse_x; + *y = mouse_y; + *z = mouse_z; + mouse_x = mouse_y = mouse_z = 0; +} + diff --git a/src/wx-sdl2-status.c b/src/wx-sdl2-status.c new file mode 100644 index 0000000..78bacfb --- /dev/null +++ b/src/wx-sdl2-status.c @@ -0,0 +1,162 @@ +#include "wx-sdl2.h" +#include "wx-sdl2-video.h" +#include "ibm.h" +#include "device.h" +#include "video.h" +#include "x86_ops.h" +#include "mem.h" +#include "codegen.h" +#include "cpu.h" +#include "model.h" +#include "fdd.h" +#include "hdd.h" +#include "ide.h" +#include "cdrom-image.h" +#include "wx-common.h" + +drive_info_t drive_info[10]; + +int status_is_open = 0; + +extern int sreadlnum, swritelnum, segareads, segawrites, scycles_lost; +extern int render_fps, fps; + +extern uint64_t main_time; +extern uint64_t render_time; +static uint64_t status_time; + +drive_info_t* get_machine_info(char* s, int* num_drive_info) { + int drive, i; + int pos = 0; + sprintf(s, + "Model: %s\n" + "CPU: %s", + model_getname(), + models[model].cpu[cpu_manufacturer].cpus[cpu].name); + if (emulation_state == EMULATION_RUNNING) + sprintf(s+strlen(s), "\nEmulation speed: %d%%", fps); + else if (emulation_state == EMULATION_PAUSED) + strcat(s, "\nEmulation is paused."); + else + strcat(s, "\nEmulation is not running."); + + for (i = 0; i < 2; ++i) + { + drive = 'A'+i; + if (fdd_get_type(i) > 0) + { + strcpy(drive_info[pos].fn, discfns[i]); + drive_info[pos].enabled = strlen(drive_info[pos].fn) > 0; + drive_info[pos].drive = i; + drive_info[pos].drive_letter = drive; + drive_info[pos].type = DRIVE_TYPE_FDD; + drive_info[pos].readflash = readflash_get(READFLASH_FDC, i); + readflash_clear(READFLASH_FDC, i); + pos++; + } + } + int num_hdds = hdd_controller_current_is_mfm() ? 2 : 4; + for (i = 0; i < num_hdds; ++i) + { + drive = 'C'+i; + if (cdrom_enabled && !hdd_controller_current_is_mfm() && i == cdrom_channel) + { + if (cdrom_drive < 0) + continue; + if (cdrom_drive == CDROM_IMAGE) + { + if (!strlen(image_path)) + continue; + strcpy(drive_info[pos].fn, image_path); + } + else + strcpy(drive_info[pos].fn, ""); + drive_info[pos].enabled = strlen(drive_info[pos].fn) > 0; + drive_info[pos].drive = i; + drive_info[pos].drive_letter = drive; + drive_info[pos].type = DRIVE_TYPE_CDROM; + drive_info[pos].readflash = readflash_get(READFLASH_HDC, i); + readflash_clear(READFLASH_HDC, i); + pos++; + } else if (strlen(ide_fn[i]) > 0) + { + strcpy(drive_info[pos].fn, ide_fn[i]); + drive_info[pos].enabled = 1; + drive_info[pos].drive = i; + drive_info[pos].drive_letter = drive; + drive_info[pos].type = DRIVE_TYPE_HDD; + drive_info[pos].readflash = readflash_get(READFLASH_HDC, i); + readflash_clear(READFLASH_HDC, i); + pos++; + } + } + *num_drive_info = pos; + return drive_info; +} + +int get_status(char* machine, char* device) +{ +// if (!status_is_open) { +// return 0; +// } +// char device_s[4096]; + uint64_t new_time = timer_read(); + uint64_t status_diff = new_time - status_time; + status_time = new_time; + sprintf(machine, + "CPU speed : %f MIPS\n" + "FPU speed : %f MFLOPS\n\n" + + /* "Cache misses (read) : %i/sec\n" + "Cache misses (write) : %i/sec\n\n"*/ + + "Video throughput (read) : %i bytes/sec\n" + "Video throughput (write) : %i bytes/sec\n\n" + "Effective clockspeed : %iHz\n\n" + "Timer 0 frequency : %fHz\n\n" + "CPU time : %f%% (%f%%)\n" + "Render time : %f%% (%f%%)\n" + "Renderer: %s\n" + "Render FPS: %d\n" + "\n" + + "New blocks : %i\nOld blocks : %i\nRecompiled speed : %f MIPS\nAverage size : %f\n" + "Flushes : %i\nEvicted : %i\nReused : %i\nRemoved : %i\nReal speed : %f MIPS" + // "\nFully recompiled ins %% : %f%%" + ,mips, + flops, + /*#ifndef DYNAREC + sreadlnum, + swritelnum, + #endif*/ + segareads, + segawrites, + clockrate - scycles_lost, + pit_timer0_freq(), + ((double)main_time * 100.0) / status_diff, + ((double)main_time * 100.0) / timer_freq, + ((double)render_time * 100.0) / status_diff, + ((double)render_time * 100.0) / timer_freq, + current_render_driver_name, + render_fps + + , cpu_new_blocks_latched, cpu_recomp_blocks_latched, (double)cpu_recomp_ins_latched / 1000000.0, (double)cpu_recomp_ins_latched/cpu_recomp_blocks_latched, + cpu_recomp_flushes_latched, cpu_recomp_evicted_latched, + cpu_recomp_reuse_latched, cpu_recomp_removed_latched, + + ((double)cpu_recomp_ins_latched / 1000000.0) / ((double)main_time / timer_freq) + // ((double)cpu_recomp_full_ins_latched / (double)cpu_recomp_ins_latched) * 100.0 + // cpu_reps_latched, cpu_notreps_latched + ); + main_time = 0; + render_time = 0; + /*#ifndef DYNAREC + device_add_status_info(device_s, 4096); + #endif*/ + +// device_s[0] = 0; + device[0] = 0; + device_add_status_info(device, 4096); + + return 1; +} diff --git a/src/wx-sdl2-video.c b/src/wx-sdl2-video.c new file mode 100644 index 0000000..ec5eefa --- /dev/null +++ b/src/wx-sdl2-video.c @@ -0,0 +1,344 @@ +#include "wx-sdl2-video.h" + +#include +#include +#include +#include "wx-sdl2.h" +#include "video.h" + +void video_blit_complete(); + +static BITMAP *buffer32_vscale; +BITMAP *screen; +SDL_Texture* texture = NULL; +SDL_Renderer* renderer = NULL; +SDL_Rect old_screen_rect; +SDL_Rect screen_rect; +SDL_Rect updated_rect; +SDL_Rect window_rect; +SDL_Rect blit_rect; +SDL_Rect texture_rect; +int updated = 0; + +SDL_mutex* blitMutex = NULL; + +static void sdl_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h); +static void sdl_blit_memtoscreen_8(int x, int y, int w, int h); + +int video_scale_mode = 1; +int video_vsync = 0; +int video_focus_dim = 0; +int video_fullscreen_mode = 0; + +static sdl_render_driver sdl_render_drivers[] = { + { RENDERER_AUTO, "auto", "Auto" }, + { RENDERER_DIRECT3D, "direct3d", "Direct3D" }, + { RENDERER_OPENGL, "opengl", "OpenGL" }, + { RENDERER_OPENGLES2, "opengles2", "OpenGL ES 2" }, + { RENDERER_OPENGLES, "opengles", "OpenGL ES" }, + { RENDERER_SOFTWARE, "software", "Software" } +}; + +sdl_render_driver requested_render_driver; + +char current_render_driver_name[50]; + +void hline(BITMAP *b, int x1, int y, int x2, int col) +{ + if (y < 0 || y >= buffer32->h) + return; + + for (; x1 < x2; x1++) + ((uint32_t *)b->line[y])[x1] = col; +} + +void blit(BITMAP *src, BITMAP *dst, int x1, int y1, int x2, int y2, int xs, int ys) +{ +} + +void stretch_blit(BITMAP *src, BITMAP *dst, int x1, int y1, int xs1, int ys1, int x2, int y2, int xs2, int ys2) +{ +} + +void rectfill(BITMAP *b, int x1, int y1, int x2, int y2, uint32_t col) +{ +} + +void set_palette(PALETTE p) +{ +} + +void destroy_bitmap(BITMAP *b) +{ +} + +BITMAP *create_bitmap(int x, int y) +{ + BITMAP *b = malloc(sizeof(BITMAP) + (y * sizeof(uint8_t *))); + int c; + b->dat = malloc(x * y * 4); + for (c = 0; c < y; c++) + { + b->line[c] = b->dat + (c * x * 4); + } + b->w = x; + b->h = y; + return b; +} + +sdl_render_driver* sdl_get_render_drivers(int* num) +{ + if (num) + *num = SDL_arraysize(sdl_render_drivers); + return sdl_render_drivers; +} + +sdl_render_driver sdl_get_render_driver_by_name(const char* name, int def) +{ + int i; + for (i = 0; i < SDL_arraysize(sdl_render_drivers); ++i) + { + if (!strcmp(sdl_render_drivers[i].sdl_id, name)) + { + return sdl_render_drivers[i]; + } + } + return sdl_render_drivers[def]; +} + +sdl_render_driver* sdl_get_render_driver_by_name_ptr(const char* name) +{ + int i; + for (i = 0; i < SDL_arraysize(sdl_render_drivers); ++i) + { + if (!strcmp(sdl_render_drivers[i].sdl_id, name)) + { + return &sdl_render_drivers[i]; + } + } + return 0; +} + +sdl_render_driver sdl_get_render_driver_by_id(int id, int def) +{ + int i; + for (i = 0; i < SDL_arraysize(sdl_render_drivers); ++i) + { + if (sdl_render_drivers[i].id == id) + { + return sdl_render_drivers[i]; + } + } + return sdl_render_drivers[def]; +} + + +void sdl_scale(int scale, SDL_Rect src, SDL_Rect* dst, int w, int h) +{ + double t, b, l, r; + int ratio_w, ratio_h; + switch (scale) + { + case FULLSCR_SCALE_43: + t = 0; + b = src.h; + l = (src.w / 2) - ((src.h * 4) / (3 * 2)); + r = (src.w / 2) + ((src.h * 4) / (3 * 2)); + if (l < 0) + { + l = 0; + r = src.w; + t = (src.h / 2) + - ((src.w * 3) / (4 * 2)); + b = (src.h / 2) + + ((src.w * 3) / (4 * 2)); + } + break; + case FULLSCR_SCALE_SQ: + t = 0; + b = src.h; + l = (src.w / 2) - ((src.h * w) / (h * 2)); + r = (src.w / 2) + ((src.h * w) / (h * 2)); + if (l < 0) + { + l = 0; + r = src.w; + t = (src.h / 2) + - ((src.w * h) / (w * 2)); + b = (src.h / 2) + + ((src.w * h) / (w * 2)); + } + break; + case FULLSCR_SCALE_INT: + ratio_w = src.w / w; + ratio_h = src.h / h; + if (ratio_h < ratio_w) + ratio_w = ratio_h; + l = (src.w / 2) - ((w * ratio_w) / 2); + r = (src.w / 2) + ((w * ratio_w) / 2); + t = (src.h / 2) - ((h * ratio_w) / 2); + b = (src.h / 2) + ((h * ratio_w) / 2); + break; + case FULLSCR_SCALE_FULL: + default: + l = 0; + t = 0; + r = src.w; + b = src.h; + break; + } + + dst->x = l; + dst->y = t; + dst->w = r - l; + dst->h = b - t; +} + +static void set_updated_size(int x, int y, int w, int h) +{ + if (updated) + { + updated_rect.x = x < updated_rect.x ? x : updated_rect.x; + updated_rect.y = y < updated_rect.y ? y : updated_rect.y; + updated_rect.w = w > updated_rect.w ? w : updated_rect.w; + updated_rect.h = h > updated_rect.h ? h : updated_rect.h; + } + else + { + updated_rect.x = x; + updated_rect.y = y; + updated_rect.w = w; + updated_rect.h = h; + updated = 1; + } +} + +static void sdl_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) +{ + if (y1 == y2) + { + video_blit_complete(); + return; /*Nothing to do*/ + } + + int xx, yy; + SDL_Rect rect; + SDL_LockMutex(blitMutex); + for (yy = y1; yy < y2; yy++) + { + if ((y + yy) >= 0 && (y + yy) < buffer32->h) + memcpy(screen->dat + (yy * screen->w * 4), + &(((uint32_t *) buffer32->line[y + yy])[x]), w * 4); + } + set_updated_size(0, y1, w, y2 - y1); +// set_updated_size(0, 0, w, h); + blit_rect.w = w; + blit_rect.h = h; + SDL_UnlockMutex(blitMutex); + video_blit_complete(); +} + +int sdl_is_fullscreen(SDL_Window* window) { + int flags = SDL_GetWindowFlags(window); + return (flags&SDL_WINDOW_FULLSCREEN) || (flags&SDL_WINDOW_FULLSCREEN_DESKTOP); +} + +int sdl_video_init() +{ + blitMutex = SDL_CreateMutex(); + updated = 0; + + video_blit_memtoscreen_func = sdl_blit_memtoscreen; + requested_render_driver = sdl_get_render_driver_by_id(RENDERER_AUTO, RENDERER_AUTO); + + buffer32_vscale = create_bitmap(2048, 2048); + screen = create_bitmap(2048, 2048); + + return SDL_TRUE; +} + +void sdl_video_close() +{ + destroy_bitmap(buffer32_vscale); + destroy_bitmap(screen); + SDL_DestroyMutex(blitMutex); +} + +int sdl_renderer_init(SDL_Window* window) +{ + SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, video_scale_mode ? "1" : "0"); + const char* driver = requested_render_driver.sdl_id; + if (!driver) driver = "0"; + SDL_SetHint(SDL_HINT_RENDER_DRIVER, driver); + + int flags = SDL_RENDERER_ACCELERATED; + if (video_vsync) { + flags |= SDL_RENDERER_PRESENTVSYNC; + } + renderer = SDL_CreateRenderer(window, -1, flags); + + SDL_RendererInfo rendererInfo; + SDL_GetRendererInfo(renderer, &rendererInfo); + sdl_render_driver* d = sdl_get_render_driver_by_name_ptr(rendererInfo.name); + if (!d) + strcpy(current_render_driver_name, "Unknown"); + else + strcpy(current_render_driver_name, d->name); + + texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, + SDL_TEXTUREACCESS_STREAMING, + screen->w, screen->h); + + return SDL_TRUE; +} + +void sdl_renderer_close() +{ + if (texture) + { + SDL_DestroyTexture(texture); + texture = NULL; + } + if (renderer) + { + SDL_DestroyRenderer(renderer); + renderer = NULL; + } +} + +int sdl_renderer_update(SDL_Window* window) +{ + int render = 0; + SDL_LockMutex(blitMutex); + if (updated) + { + updated = 0; + SDL_UpdateTexture(texture, &updated_rect, + &((uint32_t*) screen->dat)[updated_rect.y + * screen->w + updated_rect.x], + screen->w * 4); + texture_rect.w = blit_rect.w; + texture_rect.h = blit_rect.h; + render = 1; + } + SDL_UnlockMutex(blitMutex); + return render; +} + +void sdl_renderer_present(SDL_Window* window) +{ + SDL_Rect wr; + int l, t, r, b; + SDL_GetWindowSize(window, &wr.w, &wr.h); + sdl_scale(video_fullscreen_scale, wr, &wr, texture_rect.w, texture_rect.h); + SDL_RenderClear(renderer); + SDL_RenderCopy(renderer, texture, &texture_rect, &wr); + if (video_focus_dim && !(SDL_GetWindowFlags(window)&SDL_WINDOW_INPUT_FOCUS)) { + SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND); + SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0x80); + SDL_RenderFillRect(renderer, NULL); + SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0xff); + SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_NONE); + } + SDL_RenderPresent(renderer); +} diff --git a/src/wx-sdl2-video.h b/src/wx-sdl2-video.h new file mode 100644 index 0000000..635b0fc --- /dev/null +++ b/src/wx-sdl2-video.h @@ -0,0 +1,38 @@ +#include + +#define RENDERER_AUTO 0 +#define RENDERER_DIRECT3D 1 +#define RENDERER_OPENGL 2 +#define RENDERER_OPENGLES2 3 +#define RENDERER_OPENGLES 4 +#define RENDERER_SOFTWARE 5 + +typedef struct sdl_render_driver { + int id; + const char* sdl_id; + const char* name; +} sdl_render_driver; + +#ifdef __cplusplus +extern "C" { +#endif +int sdl_video_init(); +void sdl_video_close(); +int sdl_renderer_init(SDL_Window* window); +void sdl_renderer_close(); +int sdl_renderer_update(SDL_Window* window); +void sdl_renderer_present(SDL_Window* window); +void sdl_scale(int scale, SDL_Rect src, SDL_Rect* dst, int w, int h); +int sdl_is_fullscreen(SDL_Window* window); + +sdl_render_driver* sdl_get_render_drivers(int* num_renderers); +sdl_render_driver sdl_get_render_driver_by_id(int id, int def); +sdl_render_driver sdl_get_render_driver_by_name(const char* name, int def); +sdl_render_driver* sdl_get_render_driver_by_name_ptr(const char* name); + +#ifdef __cplusplus +} +#endif + +extern sdl_render_driver requested_render_driver; +extern char current_render_driver_name[50]; diff --git a/src/wx-sdl2.c b/src/wx-sdl2.c new file mode 100644 index 0000000..22d4e63 --- /dev/null +++ b/src/wx-sdl2.c @@ -0,0 +1,889 @@ +#include "wx-sdl2.h" + +#include +#include + +#ifdef __WINDOWS__ +#define BITMAP WINDOWS_BITMAP +#include +#include +#undef BITMAP +#endif + + +#include +#include +#include +#include +#include "ibm.h" +#include "cdrom-ioctl.h" +#include "cdrom-image.h" +#include "config.h" +#include "video.h" +#include "cpu.h" +#include "ide.h" +#include "model.h" +#include "mouse.h" +#include "nvr.h" +#include "sound.h" +#include "thread.h" +#include "disc.h" +#include "disc_img.h" +#include "mem.h" + +#include "wx-sdl2-video.h" +#include "wx-utils.h" +#include "wx-common.h" +#include "wx-display.h" + +#define ID_IS(s) wParam == wx_xrcid(s) +#define ID_RANGE(a, b) wParam >= wx_xrcid(a) && wParam <= wx_xrcid(b) + +#define IDM_CDROM_REAL 1500 + +uint64_t timer_freq; + + +int gfx_present[GFX_MAX]; + +SDL_mutex* ghMutex; +SDL_mutex* mainMutex; +SDL_cond* mainCond; + +SDL_Thread* mainthreadh = NULL; + +SDL_TimerID onesectimer; + +int running = 0; + +int drawits = 0; + +int romspresent[ROM_MAX]; +int quited = 0; + +SDL_Rect oldclip; + +void* ghwnd = 0; + +void* menu; + +emulation_state_t emulation_state = EMULATION_STOPPED; +int pause = 0; + +int window_doreset = 0; +int renderer_doreset = 0; +int window_dofullscreen = 0; +int window_dowindowed = 0; +int window_doremember = 0; +int window_doinputgrab = 0; +int window_doinputrelease = 0; +int window_dotogglefullscreen = 0; + +int video_scale = 1; + +int video_width = 640; +int video_height = 480; + +char menuitem[60]; + +extern void add_config_callback(void(*loadconfig)(), void(*saveconfig)(), void(*onloaded)()); + +extern int config_selection_open(void* hwnd, int inited); + +extern void sdl_set_window_title(const char* title); + +void warning(const char *format, ...) +{ + char buf[1024]; + va_list ap; + + va_start(ap, format); + vsprintf(buf, format, ap); + va_end(ap); + + wx_messagebox(ghwnd, buf, "PCem", WX_MB_OK); +} + +void updatewindowsize(int x, int y) +{ + video_width = x; + video_height = y; + + display_resize(x, y); +} + +void startblit() +{ + SDL_LockMutex(ghMutex); +} + +void endblit() +{ + SDL_UnlockMutex(ghMutex); +} + +void enter_fullscreen() +{ + window_dofullscreen = window_doinputgrab = 1; +} + +void leave_fullscreen() +{ + window_dowindowed = window_doinputrelease = 1; +} + +void toggle_fullscreen() +{ + window_dotogglefullscreen = 1; +} + +uint64_t main_time; + +int mainthread(void* param) +{ + int i; + + SDL_SetThreadPriority(SDL_THREAD_PRIORITY_HIGH); + + int t = 0; + int frames = 0; + uint32_t old_time, new_time; + + drawits = 0; + old_time = SDL_GetTicks(); + running = 1; + while (running) + { + new_time = SDL_GetTicks(); + drawits += new_time - old_time; + old_time = new_time; + + if (drawits > 0 && !pause) + { + uint64_t start_time = timer_read(); + uint64_t end_time; + drawits -= 10; + if (drawits > 50) + drawits = 0; + runpc(); + frames++; + if (frames >= 200 && nvr_dosave) + { + frames = 0; + nvr_dosave = 0; + savenvr(); + } + end_time = timer_read(); + main_time += end_time - start_time; + } + else + SDL_Delay(1); + } + + SDL_LockMutex(mainMutex); + SDL_CondSignal(mainCond); + SDL_UnlockMutex(mainMutex); + + return TRUE; +} + +void get_executable_name(char *s, int size) +{ + char* path = SDL_GetBasePath(); + strcpy(s, path); +} + +void set_window_title(const char *s) +{ + sdl_set_window_title(s); +} + +uint64_t timer_read() +{ + return SDL_GetPerformanceCounter(); +} + +Uint32 timer_onesec(Uint32 interval, void* param) +{ + onesec(); + return interval; +} + +void sdl_loadconfig() +{ + video_fullscreen = config_get_int(CFG_GLOBAL, "SDL2", "fullscreen", video_fullscreen); + video_fullscreen_mode = config_get_int(CFG_GLOBAL, "SDL2", "fullscreen_mode", video_fullscreen_mode); + video_scale = config_get_int(CFG_GLOBAL, "SDL2", "scale", video_scale); + video_scale_mode = config_get_int(CFG_GLOBAL, "SDL2", "scale_mode", video_scale_mode); + video_vsync = config_get_int(CFG_GLOBAL, "SDL2", "vsync", video_vsync); + video_focus_dim = config_get_int(CFG_GLOBAL, "SDL2", "focus_dim", video_focus_dim); + requested_render_driver = sdl_get_render_driver_by_name(config_get_string(CFG_GLOBAL, "SDL2", "render_driver", ""), RENDERER_SOFTWARE); +} + +void sdl_saveconfig() +{ + config_set_int(CFG_GLOBAL, "SDL2", "fullscreen", video_fullscreen); + config_set_int(CFG_GLOBAL, "SDL2", "fullscreen_mode", video_fullscreen_mode); + config_set_int(CFG_GLOBAL, "SDL2", "scale", video_scale); + config_set_int(CFG_GLOBAL, "SDL2", "scale_mode", video_scale_mode); + config_set_int(CFG_GLOBAL, "SDL2", "vsync", video_vsync); + config_set_int(CFG_GLOBAL, "SDL2", "focus_dim", video_focus_dim); + config_set_string(CFG_GLOBAL, "SDL2", "render_driver", (char*)requested_render_driver.sdl_id); +} + +void update_cdrom_menu(void* hmenu) +{ + if (!cdrom_enabled) + wx_checkmenuitem(menu, WX_ID("IDM_CDROM_DISABLED"), WX_MB_CHECKED); + else + { + if (cdrom_drive == CDROM_IMAGE) + wx_checkmenuitem(menu, WX_ID("IDM_CDROM_IMAGE"), WX_MB_CHECKED); + else if (cdrom_drive > 0) + wx_checkmenuitem(menu, IDM_CDROM_REAL+cdrom_drive, WX_MB_CHECKED); + else + wx_checkmenuitem(menu, WX_ID("IDM_CDROM_EMPTY"), WX_MB_CHECKED); + } +} + +void wx_initmenu() +{ + char s[32]; + menu = wx_getmenu(ghwnd); + + void* cdrom_submenu = wx_getsubmenu(menu, WX_ID("IDM_CDROM")); + +#ifdef __WINDOWS__ + int c; + /* Loop through each Windows drive letter and test to see if + it's a CDROM */ + for (c='A';c<='Z';c++) + { + sprintf(s,"%c:\\",c); + if (GetDriveType(s)==DRIVE_CDROM) + { + sprintf(s, "Host CD/DVD Drive (%c:)", c); + wx_appendmenu(cdrom_submenu, IDM_CDROM_REAL+(c-'A'), s, wxITEM_RADIO); + } + } +#elif __linux__ + wx_appendmenu(cdrom_submenu, IDM_CDROM_REAL, "Host CD/DVD Drive (/dev/cdrom)", wxITEM_RADIO); +#endif + +} + +void wx_setupmenu() +{ + int c; + update_cdrom_menu(menu); + if (vid_resize) + wx_checkmenuitem(menu, WX_ID("IDM_VID_RESIZE"), WX_MB_CHECKED); + sprintf(menuitem, "IDM_VID_FS[%d]", video_fullscreen_scale); + wx_checkmenuitem(menu, WX_ID(menuitem), WX_MB_CHECKED); + wx_checkmenuitem(menu, WX_ID("IDM_VID_FULLSCREEN"), video_fullscreen); + wx_checkmenuitem(menu, WX_ID("IDM_VID_REMEMBER"), + window_remember ? WX_MB_CHECKED : WX_MB_UNCHECKED); + wx_checkmenuitem(menu, WX_ID("IDM_BPB_DISABLE"), bpb_disable ? WX_MB_CHECKED : WX_MB_UNCHECKED); + + sprintf(menuitem, "IDM_VID_SCALE_MODE[%d]", video_scale_mode); + wx_checkmenuitem(menu, WX_ID(menuitem), WX_MB_CHECKED); + sprintf(menuitem, "IDM_VID_SCALE[%d]", video_scale); + wx_checkmenuitem(menu, WX_ID(menuitem), WX_MB_CHECKED); + sprintf(menuitem, "IDM_VID_FS_MODE[%d]", video_fullscreen_mode); + wx_checkmenuitem(menu, WX_ID(menuitem), WX_MB_CHECKED); + wx_checkmenuitem(menu, WX_ID("IDM_VID_VSYNC"), video_vsync); + wx_checkmenuitem(menu, WX_ID("IDM_VID_LOST_FOCUS_DIM"), video_focus_dim); + + int num_renderers; + sdl_render_driver* drivers = sdl_get_render_drivers(&num_renderers); + for (c = 1; c < num_renderers; ++c) + { + sprintf(menuitem, "IDM_VID_RENDER_DRIVER[%d]", drivers[c].id); + wx_enablemenuitem(menu, WX_ID(menuitem), 0); + } + SDL_RendererInfo renderInfo; + for (c = 0; c < SDL_GetNumRenderDrivers(); ++c) + { + SDL_GetRenderDriverInfo(c, &renderInfo); + sdl_render_driver* driver = sdl_get_render_driver_by_name_ptr(renderInfo.name); + + if (driver) + { + pclog("Renderer: %s (%d)\n", renderInfo.name, driver->id); + sprintf(menuitem, "IDM_VID_RENDER_DRIVER[%d]", driver->id); + wx_enablemenuitem(menu, WX_ID(menuitem), 1); + } + } + sprintf(menuitem, "IDM_VID_RENDER_DRIVER[%d]", requested_render_driver.id); + wx_checkmenuitem(menu, WX_ID(menuitem), WX_MB_CHECKED); +} + +void sdl_onconfigloaded() +{ + if (ghwnd) + wx_callback(ghwnd, wx_setupmenu); +} + +extern void wx_loadconfig(); +extern void wx_saveconfig(); + +int pc_main(int argc, char** argv) +{ +#ifndef __APPLE__ + display_init(); +#endif + sdl_video_init(); + + add_config_callback(sdl_loadconfig, sdl_saveconfig, sdl_onconfigloaded); + add_config_callback(wx_loadconfig, wx_saveconfig, 0); + + getpath(); + + sound_init(); + + initpc(argc, argv); + resetpchard(); + + return TRUE; +} + +int wx_load_config(void* hwnd) +{ + if (!config_override) + { + if (!config_selection_open(NULL, 0)) + return FALSE; + } + + return TRUE; +} + +int wx_start(void* hwnd) +{ + int c, d; + ghwnd = hwnd; + +#ifdef __APPLE__ + /* OSX requires SDL to be initialized after wxWidgets. */ + display_init(); +#endif + + readflash = 0; + + wx_initmenu(); + wx_setupmenu(); + + d = romset; + for (c = 0; c < ROM_MAX; c++) + { + romset = c; + romspresent[c] = loadbios(); + pclog("romset %i - %i\n", c, romspresent[c]); + } + + for (c = 0; c < ROM_MAX; c++) + { + if (romspresent[c]) + break; + } + if (c == ROM_MAX) + { + wx_messagebox(hwnd, + "No ROMs present!\nYou must have at least one romset to use PCem.", + "PCem fatal error", WX_MB_OK); + return 0; + } + + romset = d; + c = loadbios(); + + if (!c) + { + if (romset != -1) + wx_messagebox(hwnd, + "Configured romset not available.\nDefaulting to available romset.", + "PCem error", WX_MB_OK); + for (c = 0; c < ROM_MAX; c++) + { + if (romspresent[c]) + { + romset = c; + model = model_getmodel(romset); + saveconfig(NULL); + resetpchard(); + break; + } + } + } + + for (c = 0; c < GFX_MAX; c++) + gfx_present[c] = video_card_available(video_old_to_new(c)); + + if (!video_card_available(video_old_to_new(gfxcard))) + { + if (romset != -1) + wx_messagebox(hwnd, + "Configured video BIOS not available.\nDefaulting to available romset.", + "PCem error", WX_MB_OK); + for (c = GFX_MAX - 1; c >= 0; c--) + { + if (gfx_present[c]) + { + gfxcard = c; + saveconfig(NULL); + resetpchard(); + break; + } + } + } + + return TRUE; +} + +int resume_emulation() +{ + if (emulation_state == EMULATION_PAUSED) + { + emulation_state = EMULATION_RUNNING; + pause = 0; + return TRUE; + } + return FALSE; +} + +int start_emulation(void* params) +{ + if (resume_emulation()) + return TRUE; + pclog("Starting emulation...\n"); + loadconfig(NULL); + + emulation_state = EMULATION_RUNNING; + pause = 0; + + ghMutex = SDL_CreateMutex(); + mainMutex = SDL_CreateMutex(); + mainCond = SDL_CreateCond(); + + loadbios(); + resetpchard(); + + display_start(params); + mainthreadh = SDL_CreateThread(mainthread, "Main Thread", NULL); + + onesectimer = SDL_AddTimer(1000, timer_onesec, NULL); + + updatewindowsize(640, 480); + + timer_freq = timer_read(); + + if (show_machine_on_start) + wx_show_status(ghwnd); + + return TRUE; +} + +int pause_emulation() +{ + pclog("Emulation paused.\n"); + emulation_state = EMULATION_PAUSED; + pause = 1; + return TRUE; +} + +int stop_emulation() +{ + emulation_state = EMULATION_STOPPED; + pclog("Stopping emulation...\n"); + SDL_LockMutex(mainMutex); + running = 0; + SDL_CondWaitTimeout(mainCond, mainMutex, 10 * 1000); + SDL_UnlockMutex(mainMutex); + + SDL_DestroyCond(mainCond); + SDL_DestroyMutex(mainMutex); + + startblit(); + display_stop(); + +#if SDL_VERSION_ATLEAST(2, 0, 2) + SDL_DetachThread(mainthreadh); +#endif + mainthreadh = NULL; + SDL_RemoveTimer(onesectimer); + savenvr(); + saveconfig(NULL); + + endblit(); + SDL_DestroyMutex(ghMutex); + + pclog("Emulation stopped.\n"); + + wx_close_status(ghwnd); + + return TRUE; +} + +void reset_emulation() +{ + pause_emulation(); + SDL_Delay(100); + resetpchard(); + resume_emulation(); +} + +int wx_stop() +{ + pclog("Shutting down...\n"); + closepc(); + display_close(); + sdl_video_close(); + + printf("Shut down successfully!\n"); + return TRUE; +} + +char openfilestring[260]; +int getfile(void* hwnd, char *f, char *fn) +{ + int ret = wx_filedialog(hwnd, "Open", fn, f, 0, 1, openfilestring); +#ifdef __APPLE__ + /* wxWidgets on OSX may mess up the SDL-window somehow, so just in case we reset it here */ + window_doreset = 1; +#endif + return ret; +} + +int getsfile(void* hwnd, char *f, char *fn, char *dir, char *ext) +{ + int ret = wx_filedialog(hwnd, "Save", dir, f, ext, 0, openfilestring); +#ifdef __APPLE__ + window_doreset = 1; +#endif + return ret; +} + +void atapi_close(void) +{ + switch (cdrom_drive) + { + case CDROM_IMAGE: + image_close(); + break; + default: + ioctl_close(); + break; + } +} + +int wx_handle_command(void* hwnd, int wParam, int checked) +{ + SDL_Rect rect; + void* hmenu; + char temp_image_path[1024]; + int new_cdrom_drive; + hmenu = wx_getmenu(hwnd); + + if (ID_IS("IDM_STATUS")) + { + wx_show_status(hwnd); + } + else if (ID_IS("IDM_FILE_RESET")) + { + pause = 1; + SDL_Delay(100); + savenvr(); + resetpc(); + pause = 0; + } + else if (ID_IS("IDM_FILE_HRESET")) + { + pause = 1; + SDL_Delay(100); + savenvr(); + resetpchard(); + pause = 0; + } + else if (ID_IS("IDM_FILE_RESET_CAD")) + { + pause = 1; + SDL_Delay(100); + savenvr(); + resetpc_cad(); + pause = 0; + } + else if (ID_IS("IDM_FILE_EXIT")) + { +// wx_exit(hwnd, 0); + wx_stop_emulation(hwnd); + } + else if (ID_IS("IDM_DISC_A")) + { + if (!getfile(hwnd, + "Disc image (*.img;*.ima;*.fdi)|*.img;*.ima;*.fdi|All files (*.*)|*.*", + discfns[0])) + { + disc_close(0); + disc_load(0, openfilestring); + saveconfig(NULL); + } + } + else if (ID_IS("IDM_DISC_B")) + { + if (!getfile(hwnd, + "Disc image (*.img;*.ima;*.fdi)|*.img;*.ima;*.fdi|All files (*.*)|*.*", + discfns[1])) + { + disc_close(1); + disc_load(1, openfilestring); + saveconfig(NULL); + } + } + else if (ID_IS("IDM_EJECT_A")) + { + disc_close(0); + saveconfig(NULL); + } + else if (ID_IS("IDM_EJECT_B")) + { + disc_close(1); + saveconfig(NULL); + } + else if (ID_IS("IDM_BPB_DISABLE")) + { + bpb_disable = checked; + wx_checkmenuitem(hmenu, WX_ID("IDM_BPB_DISABLE"), bpb_disable ? WX_MB_CHECKED : WX_MB_UNCHECKED); + saveconfig(NULL); + } + else if (ID_IS("IDM_MACHINE_TOGGLE")) + { + if (emulation_state != EMULATION_STOPPED) + wx_togglewindow(hwnd); + } + else if (ID_IS("IDM_VID_RESIZE")) + { + vid_resize = checked; + window_doreset = 1; + saveconfig(NULL); + } + else if (ID_IS("IDM_VID_REMEMBER")) + { + window_remember = checked; + wx_checkmenuitem(hmenu, WX_ID("IDM_VID_REMEMBER"), + window_remember ? WX_MB_CHECKED : WX_MB_UNCHECKED); + window_doremember = 1; + saveconfig(NULL); + } + else if (ID_IS("IDM_VID_FULLSCREEN")) + { + if (video_fullscreen_first) + { + video_fullscreen_first = 0; + wx_messagebox(hwnd, + "Use CTRL + ALT + PAGE DOWN to return to windowed mode", + "PCem", WX_MB_OK); + } + video_fullscreen = checked; + saveconfig(NULL); + } + else if (ID_IS("IDM_VID_FULLSCREEN_TOGGLE")) + { + toggle_fullscreen(); + } + else if (ID_RANGE("IDM_VID_FS[start]", "IDM_VID_FS[end]")) + { + video_fullscreen_scale = wParam - wx_xrcid("IDM_VID_FS[start]"); + saveconfig(NULL); + } + else if (ID_RANGE("IDM_VID_SCALE_MODE[start]", "IDM_VID_SCALE_MODE[end]")) + { + video_scale_mode = wParam - wx_xrcid("IDM_VID_SCALE_MODE[start]"); + renderer_doreset = 1; + saveconfig(NULL); + } + else if (ID_RANGE("IDM_VID_SCALE[start]", "IDM_VID_SCALE[end]")) + { + video_scale = wParam - wx_xrcid("IDM_VID_SCALE[start]"); + display_resize(video_width, video_height); + saveconfig(NULL); + } + else if (ID_RANGE("IDM_VID_FS_MODE[start]", "IDM_VID_FS_MODE[end]")) + { + video_fullscreen_mode = wParam - wx_xrcid("IDM_VID_FS_MODE[start]"); + saveconfig(NULL); + } + else if (ID_RANGE("IDM_VID_RENDER_DRIVER[start]", "IDM_VID_RENDER_DRIVER[end]")) + { + requested_render_driver = sdl_get_render_driver_by_id(wParam - wx_xrcid("IDM_VID_RENDER_DRIVER[start]"), RENDERER_AUTO); + window_doreset = 1; + saveconfig(NULL); + } + else if (ID_IS("IDM_VID_VSYNC")) + { + video_vsync = checked; + renderer_doreset = 1; + saveconfig(NULL); + } + else if (ID_IS("IDM_VID_LOST_FOCUS_DIM")) + { + video_focus_dim = checked; + saveconfig(NULL); + } + else if (ID_IS("IDM_CDROM_DISABLED")) + { + if (cdrom_enabled) + { + if (!confirm()) + { + update_cdrom_menu(hmenu); + return 0; + } + } + if (!cdrom_enabled) + { + /* Switching from disabled to disabled. Do nothing. */ + update_cdrom_menu(hmenu); + return 0; + } + atapi->exit(); + atapi_close(); + ioctl_set_drive(0); + old_cdrom_drive = cdrom_drive; + cdrom_drive = 0; + if (cdrom_enabled) + { + pause = 1; + SDL_Delay(100); + cdrom_enabled = 0; + saveconfig(NULL); + resetpchard(); + pause = 0; + } + update_cdrom_menu(hmenu); + } + else if (ID_IS("IDM_CDROM_EMPTY")) + { + if (!cdrom_enabled) + { + if (!confirm()) + { + update_cdrom_menu(hmenu); + return 0; + } + } + if ((cdrom_drive == 0) && cdrom_enabled) + { + update_cdrom_menu(hmenu); + /* Switch from empty to empty. Do nothing. */ + return 0; + } + atapi->exit(); + atapi_close(); + ioctl_set_drive(0); + if (cdrom_enabled) + { + /* Signal disc change to the emulated machine. */ + atapi_insert_cdrom(); + } + old_cdrom_drive = cdrom_drive; + cdrom_drive = 0; + saveconfig(NULL); + if (!cdrom_enabled) + { + pause = 1; + SDL_Delay(100); + cdrom_enabled = 1; + saveconfig(NULL); + resetpchard(); + pause = 0; + } + update_cdrom_menu(hmenu); + } + else if (ID_IS("IDM_CDROM_IMAGE") || ID_IS("IDM_CDROM_IMAGE_LOAD")) + { + if (!getfile(hwnd, + "CD-ROM image (*.iso;*.cue)|*.iso;*.cue|All files (*.*)|*.*", + image_path)) + { + if (!cdrom_enabled) + { + if (!confirm()) + { + update_cdrom_menu(hmenu); + return 0; + } + } + old_cdrom_drive = cdrom_drive; + strcpy(temp_image_path, openfilestring); + if ((strcmp(image_path, temp_image_path) == 0) + && (cdrom_drive == CDROM_IMAGE) + && cdrom_enabled) + { + /* Switching from ISO to the same ISO. Do nothing. */ + update_cdrom_menu(hmenu); + return 0; + } + atapi->exit(); + atapi_close(); + image_open(temp_image_path); + if (cdrom_enabled) + { + /* Signal disc change to the emulated machine. */ + atapi_insert_cdrom(); + } + cdrom_drive = CDROM_IMAGE; + saveconfig(NULL); + if (!cdrom_enabled) + { + pause = 1; + SDL_Delay(100); + cdrom_enabled = 1; + saveconfig(NULL); + resetpchard(); + pause = 0; + } + update_cdrom_menu(hmenu); + } else + update_cdrom_menu(hmenu); + } + else if (wParam >= IDM_CDROM_REAL && wParam < IDM_CDROM_REAL+100) + { + if (!cdrom_enabled) + { + if (!confirm()) + { + update_cdrom_menu(hmenu); + return 0; + } + } + new_cdrom_drive = wParam-IDM_CDROM_REAL+1; + if ((cdrom_drive == new_cdrom_drive) && cdrom_enabled) + { + /* Switching to the same drive. Do nothing. */ + update_cdrom_menu(hmenu); + return 0; + } + old_cdrom_drive = cdrom_drive; + atapi->exit(); + atapi_close(); + ioctl_set_drive(new_cdrom_drive); + if (cdrom_enabled) + { + /* Signal disc change to the emulated machine. */ + atapi_insert_cdrom(); + } + cdrom_drive = new_cdrom_drive; + saveconfig(NULL); + if (!cdrom_enabled) + { + pause = 1; + SDL_Delay(100); + cdrom_enabled = 1; + saveconfig(NULL); + resetpchard(); + pause = 0; + } + update_cdrom_menu(hmenu); + } + return 0; +} diff --git a/src/wx-sdl2.h b/src/wx-sdl2.h new file mode 100644 index 0000000..6857f5f --- /dev/null +++ b/src/wx-sdl2.h @@ -0,0 +1,16 @@ +#ifdef __cplusplus +extern "C" { +#endif + +void leave_fullscreen(); +int getfile(void* hwnd, char *f, char *fn); +int getsfile(void* hwnd, char *f, char *fn, char *dir, char *ext); + +#ifdef __cplusplus +} +#endif + +extern char openfilestring[260]; + +extern int pause; + diff --git a/src/wx-status.cc b/src/wx-status.cc new file mode 100644 index 0000000..16b9968 --- /dev/null +++ b/src/wx-status.cc @@ -0,0 +1,351 @@ +#include "wx-status.h" +#include "wx-common.h" +#include "wx-utils.h" +#include +#include +#include + +extern "C" { + int get_status(char*, char*); + int fps; + int updatestatus; + drive_info_t* get_machine_info(char*, int*); +} + +int show_machine_on_start = 0; +int confirm_on_stop_emulation = 1; +int confirm_on_reset_machine = 1; +int show_status = 0; +int show_speed_history = 0; +int show_disc_activity = 1; +int show_machine_info = 1; +int show_mount_paths = 0; + +#define ACTIVITY_TEXT wxT("Activity") + +#define MAX(a, b) (a > b ? a : b) + +#define render_disc_activity(x, y) do { \ +if (show_disc_activity) \ +{ \ + int w = 8; \ + int h = 8; \ + if (info.readflash) { \ + dc.SetBrush(wxBrush(wxColour(0,255,0))); \ + } else { \ + dc.SetBrush(wxBrush(wxColour(0,100,0))); \ + } \ + dc.DrawRectangle(x+bitmap.GetWidth()-w, y, w, h); \ +}} while (0) + +StatusTimer::StatusTimer(StatusPane* pane) +{ + this->pane = pane; +} + +void StatusTimer::Notify() +{ + pane->Refresh(); +} + +void StatusTimer::Start() +{ + wxTimer::Start(10); +} + +BEGIN_EVENT_TABLE(StatusPane, wxPanel) EVT_PAINT(StatusPane::PaintEvent) +END_EVENT_TABLE() + +BEGIN_EVENT_TABLE(StatusFrame, wxFrame) END_EVENT_TABLE() + +StatusPane::StatusPane(wxFrame* parent) : + wxPanel(parent) +{ +#ifndef __WXOSX_MAC__ + SetDoubleBuffered(true); +#endif + machineInfoText[0] = statusMachineText[0] = statusDeviceText[0] = 0; + lastSpeedUpdate = 0; + memset(speedHistory, -1, sizeof(speedHistory)); + + bitmapFDD[0] = wxXmlResource::Get()->LoadBitmap("BITMAP_FLOPPY"); + bitmapFDD[1] = bitmapFDD[0].ConvertToDisabled(); + bitmapHDD[0] = wxXmlResource::Get()->LoadBitmap("BITMAP_HARDDISK"); + bitmapHDD[1] = bitmapHDD[0].ConvertToDisabled(); + bitmapCDROM[0] = wxXmlResource::Get()->LoadBitmap("BITMAP_CDROM"); + bitmapCDROM[1] = bitmapCDROM[0].ConvertToDisabled(); +} + +StatusPane::~StatusPane() { +} + +void StatusPane::PaintEvent(wxPaintEvent& evt) +{ + wxPaintDC dc(this); + Render(dc); +} + +void StatusPane::PaintNow() +{ + wxClientDC dc(this); + Render(dc); +} + +void StatusPane::Render(wxDC& dc) +{ + wxSize cSize = GetParent()->GetClientSize(); + + int width = 0; + int height = 0; + wxLongLong millis = wxGetUTCTimeMillis(); + + dc.SetBackground(wxSystemSettings::GetColour(wxSYS_COLOUR_FRAMEBK)); + dc.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT)); + dc.Clear(); + + // draw model/cpu etc + if (show_machine_info) { + int num_info; + drive_info_t* drive_info = get_machine_info(machineInfoText, &num_info); + wxSize size = dc.GetMultiLineTextExtent(machineInfoText); + dc.DrawText(machineInfoText, 5, height+5); + + width = MAX(width, width+5+size.x); + height = MAX(height, height+5+size.y); + + int x = cSize.x-5; + + for (int i = 0; i < num_info; ++i) + { + drive_info_t info = show_mount_paths ? drive_info[i] : drive_info[num_info-i-1]; + wxBitmap bitmap; + if (info.type == DRIVE_TYPE_FDD) + bitmap = info.enabled ? bitmapFDD[0] : bitmapFDD[1]; + else if (info.type == DRIVE_TYPE_CDROM) + bitmap = info.enabled ? bitmapCDROM[0] : bitmapCDROM[1]; + else + bitmap = info.enabled ? bitmapHDD[0] : bitmapHDD[1]; + if (show_mount_paths) + { + x = 5; + dc.DrawBitmap(bitmap, x, height+5); + render_disc_activity(x, height+5); + x += bitmap.GetWidth()+5; + + std::ostringstream ss; + ss << info.drive_letter << ":" << " " << info.fn; + std::string s = ss.str(); + size = dc.GetTextExtent(s); + dc.DrawText(s, x, height+5+(bitmap.GetHeight()-size.y)/2); + width = MAX(width, x+size.x); + height = MAX(height, height+5+MAX(bitmap.GetHeight(), size.y)); + } else { + x -= bitmap.GetWidth(); + dc.DrawBitmap(bitmap, x, 5); + render_disc_activity(x, 5); + x -= 5; + height = MAX(height, 5+bitmap.GetHeight()); + } + } + } + + if (emulation_state != EMULATION_STOPPED) + { + // draw status text + if (show_status) { + if (updatestatus) { + updatestatus = 0; + get_status(statusMachineText, statusDeviceText); + } + if (statusMachineText) { + int statusX = 5; + int statusY = height+5; + wxSize size = dc.GetMultiLineTextExtent(statusMachineText); + dc.DrawText(statusMachineText, statusX, statusY); + width = MAX(width, statusX+size.GetWidth()); + height = MAX(height, statusY+size.GetHeight()); + if (statusDeviceText) { + wxSize dSize = dc.GetMultiLineTextExtent(statusDeviceText); + dc.DrawText(statusDeviceText, statusX+ceil((size.GetWidth()+50)/100.0)*100, statusY); + width = MAX(width, statusX+ceil((size.GetWidth()+50)/100.0)*100+ceil((dSize.GetWidth()+50)/100.0)*100); + height = MAX(height, statusY+dSize.GetHeight()); + } + } + } + + if (emulation_state == EMULATION_RUNNING && (millis-lastSpeedUpdate > 500)) { + lastSpeedUpdate = millis; + memmove(speedHistory+1, speedHistory, SPEED_HISTORY_LENGTH-2); + speedHistory[0] = fps; + } + // draw speed history + if (show_speed_history) { + int speedGraphBorder = 5; + int speedGraphX = 5; + int speedGraphY = height+5; + int speedGraphWidth = MAX(2*SPEED_HISTORY_LENGTH, width-5); + double lineLength = (double)(speedGraphWidth-2)/(SPEED_HISTORY_LENGTH-1); + int speedGraphHeight = 125; + dc.SetBrush(wxBrush(wxColour(255, 255, 255))); + dc.DrawRectangle(speedGraphX, speedGraphY, speedGraphWidth, speedGraphHeight+speedGraphBorder*2); + dc.SetPen(wxPen(wxColour(200, 200, 200))); + dc.DrawLine(speedGraphX, speedGraphY+speedGraphBorder+speedGraphHeight-0, speedGraphX+speedGraphWidth, speedGraphY+speedGraphHeight+speedGraphBorder-0); // 0 + dc.DrawLine(speedGraphX, speedGraphY+speedGraphBorder+speedGraphHeight-50, speedGraphX+speedGraphWidth, speedGraphY+speedGraphHeight+speedGraphBorder-50); // 50 + dc.DrawLine(speedGraphX, speedGraphY+speedGraphBorder+speedGraphHeight-100, speedGraphX+speedGraphWidth, speedGraphY+speedGraphHeight+speedGraphBorder-100); // 100 + dc.DrawLine(speedGraphX, speedGraphY+speedGraphBorder+speedGraphHeight-125, speedGraphX+speedGraphWidth, speedGraphY+speedGraphHeight+speedGraphBorder-125); // 125 + dc.SetPen(wxPen(wxColour(0, 0, 0))); + for (int i = 0; i < SPEED_HISTORY_LENGTH-1; ++i) { + int v0 = speedHistory[i]; + int v1 = speedHistory[i+1]; + if (v0 >= 0 && v1 >= 0) { + dc.DrawLine(speedGraphX+speedGraphWidth-i*lineLength-1, speedGraphY+speedGraphHeight+speedGraphBorder-v0, + speedGraphX+speedGraphWidth-(i+1)*lineLength-1, speedGraphY+speedGraphHeight+speedGraphBorder-v1); + } + } + dc.SetBrush(wxBrush(wxColour(255, 255, 255), wxBrushStyle(wxBRUSHSTYLE_TRANSPARENT))); + dc.DrawRectangle(speedGraphX, speedGraphY, speedGraphWidth, speedGraphHeight+speedGraphBorder*2); + + width = MAX(width, (speedGraphX+speedGraphWidth)); + height = MAX(height, speedGraphY+speedGraphHeight+speedGraphBorder*2); + } + } + + width += 5; + height += 5; + width = width < DEFAULT_WINDOW_WIDTH ? DEFAULT_WINDOW_WIDTH : width; + height = height < DEFAULT_WINDOW_HEIGHT ? DEFAULT_WINDOW_HEIGHT : height; + if (cSize.GetWidth() != width || cSize.GetHeight() != height) { + GetParent()->SetClientSize(width, height); + } +} + +extern "C" +{ + int window_remember; + void wx_handle_command(void*, int, int); + + void resume_emulation(); + void pause_emulation(); + int stop_emulation_confirm(); + void reset_emulation(); + + void hdconf_open(void* hwnd); + void config_open(void* hwnd); +} + +int wx_window_x = 0; +int wx_window_y = 0; + +StatusFrame::StatusFrame(wxWindow* parent) : + wxFrame(parent, STATUS_WINDOW_ID, "PCem Machine", wxPoint(0, 0), wxSize(DEFAULT_WINDOW_WIDTH, 200), wxCAPTION | wxCLOSE_BOX) +{ + SetMenuBar(wxXmlResource::Get()->LoadMenuBar(wxT("status_menu"))); + SetToolBar(wxXmlResource::Get()->LoadToolBar(this, wxT("tool_bar"))); + + this->statusPane = new StatusPane(this); + wxBoxSizer* sizer = new wxBoxSizer(wxHORIZONTAL); + sizer->Add(statusPane, 1, wxEXPAND); + SetSizer(sizer); + + Bind(wxEVT_MENU, &StatusFrame::OnCommand, this); + Bind(wxEVT_MOVE, &StatusFrame::OnMoveWindow, this); + + statusTimer = new StatusTimer(statusPane); + statusTimer->Start(); + + if (window_remember) + SetPosition(wxPoint(wx_window_x, wx_window_y)); + else + CenterOnScreen(); + + UpdateToolbar(); + GetMenuBar()->FindItem(XRCID("IDM_SHOW_STATUS"))->Check(show_status); + GetMenuBar()->FindItem(XRCID("IDM_SPEED_HISTORY"))->Check(show_speed_history); + GetMenuBar()->FindItem(XRCID("IDM_DISC_ACTIVITY"))->Check(show_disc_activity); + GetMenuBar()->FindItem(XRCID("IDM_MACHINE_MOUNT_PATHS"))->Check(show_mount_paths); + GetMenuBar()->FindItem(XRCID("IDM_SHOW_MACHINE_ON_START"))->Check(show_machine_on_start); +} + +StatusFrame::~StatusFrame() +{ + statusTimer->Stop(); + delete statusTimer; +} + +void StatusFrame::UpdateToolbar() +{ + GetToolBar()->EnableTool(XRCID("TOOLBAR_RUN"), emulation_state != EMULATION_RUNNING); + GetToolBar()->EnableTool(XRCID("TOOLBAR_PAUSE"), emulation_state != EMULATION_PAUSED); +} + +void StatusFrame::OnCommand(wxCommandEvent& event) +{ + if (event.GetId() == XRCID("TOOLBAR_RUN")) + { + resume_emulation(); + UpdateToolbar(); + } + else if (event.GetId() == XRCID("TOOLBAR_PAUSE")) + { + pause_emulation(); + UpdateToolbar(); + } + else if (event.GetId() == XRCID("TOOLBAR_RESET")) + { + int ret = wxID_OK; + if (confirm_on_reset_machine) + { + wxDialog dlg; + wxXmlResource::Get()->LoadDialog(&dlg, this, "ConfirmRememberDlg"); + dlg.FindWindow("IDC_CONFIRM_LABEL")->SetLabel("Reset machine?"); + dlg.FindWindow("IDC_CONFIRM_REMEMBER")->SetLabel("Do not ask again"); + dlg.Fit(); + ret = dlg.ShowModal(); + if (ret == wxID_OK) + confirm_on_reset_machine = !((wxCheckBox*)dlg.FindWindow("IDC_CONFIRM_REMEMBER"))->IsChecked(); + } + if (ret == wxID_OK) + { + reset_emulation(); + UpdateToolbar(); + } + } + else if (event.GetId() == XRCID("TOOLBAR_STOP")) + wx_stop_emulation(GetParent()); + else if (event.GetId() == XRCID("IDM_SHOW_STATUS")) + show_status = event.IsChecked(); + else if (event.GetId() == XRCID("IDM_SPEED_HISTORY")) + show_speed_history = event.IsChecked(); + else if (event.GetId() == XRCID("IDM_DISC_ACTIVITY")) + show_disc_activity = event.IsChecked(); + else if (event.GetId() == XRCID("IDM_MACHINE_MOUNT_PATHS")) + show_mount_paths = event.IsChecked(); + else if (event.GetId() == XRCID("IDM_SHOW_MACHINE_ON_START")) + show_machine_on_start = event.IsChecked(); + else if (event.GetId() == XRCID("IDM_HDCONF")) + hdconf_open(this); + else if (event.GetId() == XRCID("IDM_CONFIG")) + config_open(this); + else if (event.GetId() == XRCID("IDM_RESET_CONFIRMATION_DIALOGS")) + { + confirm_on_reset_machine = 1; + confirm_on_stop_emulation = 1; + wxMessageBox("Confirmation dialogs has been reset.", "PCem"); + } + else if (event.GetId() == XRCID("IDM_ABOUT")) + { + wxDialog dlg; + wxXmlResource::Get()->LoadDialog(&dlg, this, "AboutDlg"); + dlg.Fit(); + dlg.ShowModal(); + } + +} + +void StatusFrame::OnMoveWindow(wxMoveEvent& event) +{ + if (window_remember) { + wx_window_x = event.GetPosition().x; + wx_window_y = event.GetPosition().y; + } +} diff --git a/src/wx-status.h b/src/wx-status.h new file mode 100644 index 0000000..fd89f92 --- /dev/null +++ b/src/wx-status.h @@ -0,0 +1,70 @@ +#ifndef SRC_WX_STATUS_H_ +#define SRC_WX_STATUS_H_ + +#include +#include + +#define DEFAULT_WINDOW_WIDTH 350 +#define DEFAULT_WINDOW_HEIGHT 25 + +#define SPEED_HISTORY_LENGTH 240 + +class StatusPane; + +class StatusTimer : public wxTimer +{ +public: + StatusTimer(StatusPane* pane); + virtual ~StatusTimer() {}; + + void Notify(); + void Start(); +private: + StatusPane* pane; +}; + +class StatusPane : public wxPanel +{ + +public: + StatusPane(wxFrame* parent); + virtual ~StatusPane(); + + void PaintEvent(wxPaintEvent& evt); + void PaintNow(); + void Render( wxDC& dc ); + +private: + char machineInfoText[4096]; + char statusMachineText[4096]; + char statusDeviceText[4096]; + wxLongLong lastSpeedUpdate; + char speedHistory[SPEED_HISTORY_LENGTH]; + + wxBitmap bitmapFDD[2]; + wxBitmap bitmapCDROM[2]; + wxBitmap bitmapHDD[2]; + + DECLARE_EVENT_TABLE() +}; + +#define STATUS_WINDOW_ID 1000 + +class StatusFrame : public wxFrame { +public: + StatusFrame(wxWindow* parent); + virtual ~StatusFrame(); + void OnQuit(); +private: + void OnCommand(wxCommandEvent &event); + void OnMoveWindow(wxMoveEvent& event); + StatusPane* statusPane; + StatusTimer* statusTimer; + + void UpdateToolbar(); + + DECLARE_EVENT_TABLE() + +}; + +#endif /* SRC_WX_STATUS_H_ */ diff --git a/src/wx-thread.c b/src/wx-thread.c new file mode 100644 index 0000000..1015356 --- /dev/null +++ b/src/wx-thread.c @@ -0,0 +1,169 @@ +#include +#include +#include +#include "thread.h" +#if defined WIN32 || defined _WIN32 || defined _WIN32 +#include +#include +void *thread_create(void (*thread_rout)(void *param), void *param) +{ + return (void *)_beginthread(thread_rout, 0, param); +} + +void thread_kill(void *handle) +{ + TerminateThread(handle, 0); +} + +void thread_sleep(int t) +{ + Sleep(t); +} + +typedef struct win_event_t +{ + HANDLE handle; +} win_event_t; + +event_t *thread_create_event() +{ + win_event_t *event = malloc(sizeof(win_event_t)); + + event->handle = CreateEvent(NULL, FALSE, FALSE, NULL); + + return (event_t *)event; +} + +void thread_set_event(event_t *_event) +{ + win_event_t *event = (win_event_t *)_event; + + SetEvent(event->handle); +} + +void thread_reset_event(event_t *_event) +{ + win_event_t *event = (win_event_t *)_event; + + ResetEvent(event->handle); +} + +int thread_wait_event(event_t *_event, int timeout) +{ + win_event_t *event = (win_event_t *)_event; + + if (timeout == -1) + timeout = INFINITE; + + if (WaitForSingleObject(event->handle, timeout)) + return 1; + return 0; +} + +void thread_destroy_event(event_t *_event) +{ + win_event_t *event = (win_event_t *)_event; + + CloseHandle(event->handle); + + free(event); +} + +#else +#include +#include + +typedef struct event_pthread_t +{ + pthread_cond_t cond; + pthread_mutex_t mutex; +} event_pthread_t; + +thread_t *thread_create(void (*thread_rout)(void *param), void *param) +{ + pthread_t *thread = malloc(sizeof(pthread_t)); + + pthread_create(thread, NULL, (void*)thread_rout, param); + + return thread; +} + +void thread_kill(thread_t *handle) +{ + pthread_t *thread = (pthread_t *)handle; + + pthread_cancel(*thread); + pthread_join(*thread, NULL); + + free(thread); +} + +event_t *thread_create_event() +{ + event_pthread_t *event = malloc(sizeof(event_pthread_t)); + + pthread_cond_init(&event->cond, NULL); + pthread_mutex_init(&event->mutex, NULL); + + return (event_t *)event; +} + +void thread_set_event(event_t *handle) +{ + event_pthread_t *event = (event_pthread_t *)handle; + + pthread_mutex_lock(&event->mutex); + pthread_cond_broadcast(&event->cond); + pthread_mutex_unlock(&event->mutex); +} + +void thread_reset_event(event_t *handle) +{ +} + +int thread_wait_event(event_t *handle, int timeout) +{ + event_pthread_t *event = (event_pthread_t *)handle; + struct timespec abstime; + +#ifdef __linux__ + clock_gettime(CLOCK_REALTIME, &abstime); +#else + struct timeval now; + gettimeofday(&now, 0); + abstime.tv_sec = now.tv_sec; + abstime.tv_nsec = now.tv_usec*1000UL; +#endif + abstime.tv_nsec += (timeout % 1000) * 1000000; + abstime.tv_sec += (timeout / 1000); + if (abstime.tv_nsec > 1000000000) + { + abstime.tv_nsec -= 1000000000; + abstime.tv_sec++; + } + + pthread_mutex_lock(&event->mutex); + if (timeout == -1) + pthread_cond_wait(&event->cond, &event->mutex); + else + pthread_cond_timedwait(&event->cond, &event->mutex, &abstime); + pthread_mutex_unlock(&event->mutex); + + return 0; +} + +void thread_destroy_event(event_t *handle) +{ + event_pthread_t *event = (event_pthread_t *)handle; + + pthread_cond_destroy(&event->cond); + pthread_mutex_destroy(&event->mutex); + + free(event); +} + +void thread_sleep(int t) +{ + usleep(t * 1000); +} +#endif diff --git a/src/wx-utils.cc b/src/wx-utils.cc new file mode 100644 index 0000000..398a6d9 --- /dev/null +++ b/src/wx-utils.cc @@ -0,0 +1,442 @@ +#include "wx-utils.h" + +#include +#ifndef WX_PRECOMP +#include +#endif + +#include +#include +#include + +#include "wx-dialogbox.h" +#include "wx-app.h" +#include "wx-common.h" +#include "wx-status.h" + +int confirm() +{ + if (emulation_state != EMULATION_STOPPED) { + return wx_messagebox(NULL, "This will reset PCem!\nOkay to continue?", "PCem", WX_MB_OKCANCEL) == WX_IDOK; + } + return 1; +} + +int wx_messagebox(void* window, const char* message, const char* title = NULL, int style = 5) +{ + return wxMessageBox(message, title, style | wxCENTRE, (wxWindow*) window); +} + +int wx_textentrydialog(void* window, const char* message, const char* title, const char* value, int min_length, int max_length, LONG_PARAM result) +{ + while (1) + { + wxTextEntryDialog dlg((wxWindow*)window, message, title, value); + if (max_length > 0) + dlg.SetMaxLength(max_length); + if (dlg.ShowModal() == wxID_OK) + { + wxString value = dlg.GetValue(); + if (value.Length() >= min_length) + { + strcpy((char*)result, value); + return TRUE; + } + } + else + return FALSE; + } + return FALSE; +} + +void wx_setwindowtitle(void* window, char* s) +{ + ((wxFrame*) window)->SetTitle(s); +} + +int wx_xrcid(const char* s) +{ + return XRCID(s); +} + +int wx_filedialog(void* window, const char* title, const char* path, + const char* extensions, const char* extension, int open, char* file) +{ + wxFileDialog dlg((wxWindow*) window, title, "", path, extensions, + open ? wxFD_OPEN : wxFD_SAVE); + if (dlg.ShowModal() == wxID_OK) + { + wxString p = dlg.GetPath(); + wxFileName f(p); + if (!open && !f.HasExt() && extension) + { + wxString e = extension; + if (!p.EndsWith(".")) + p += "."; + p += extension; + strcpy(file, p); + } + else + strcpy(file, p); + return 0; + } + return 1; +} + +void wx_checkmenuitem(void* menu, int id, int checked) +{ + wxMenuItem* item = NULL; + if (((wxObject*)menu)->GetClassInfo()->IsKindOf(CLASSINFO(wxMenuBar))) + item = ((wxMenuBar*) menu)->FindItem(id); + else + item = ((wxMenu*) menu)->FindItem(id); + + if (item) + item->Check(checked); + else + std::cout << "Menu item not found: " << id << std::endl; +} + +void wx_enablemenuitem(void* menu, int id, int enable) +{ + wxMenuItem* item = NULL; + if (((wxObject*)menu)->GetClassInfo()->IsKindOf(CLASSINFO(wxMenuBar))) + item = ((wxMenuBar*) menu)->FindItem(id); + else + item = ((wxMenu*) menu)->FindItem(id); + + if (item) + item->Enable(enable); + else + std::cout << "Menu item not found: " << id << std::endl; +} + +void* wx_getsubmenu(void* menu, int id) +{ + wxMenuItem* m = ((wxMenu*) menu)->FindItem(id); + if (m) + return m->GetSubMenu(); + + return 0; +} + +void wx_appendmenu(void* sub_menu, int id, const char* title, enum wxItemKind type) +{ + ((wxMenu*) sub_menu)->Append(id, title, wxEmptyString, type); +} + + +void wx_enabletoolbaritem(void* toolbar, int id, int enable) +{ + ((wxToolBar*) toolbar)->EnableTool(id, enable); +} + +void* wx_getmenu(void* window) +{ + return ((Frame*) window)->GetMenu(); +} + +void* wx_getmenubar(void* window) +{ + return ((wxFrame*) window)->GetMenuBar(); +} + +void* wx_gettoolbar(void* window) +{ + return ((wxFrame*) window)->GetToolBar(); +} + +void* wx_getdlgitem(void* window, int id) +{ + return ((wxWindow*) window)->FindWindow(id); +} + +void wx_setdlgitemtext(void* window, int id, char* str) +{ + wxWindow* w = ((wxWindow*) window)->FindWindow(id); + if (w->GetClassInfo()->IsKindOf(CLASSINFO(wxTextCtrl))) + ((wxTextCtrl*) w)->SetValue(str); + else + ((wxStaticText*) w)->SetLabel(str); +} + +void wx_enablewindow(void* window, int enabled) +{ + ((wxWindow*) window)->Enable(enabled); +} + +void wx_showwindow(void* window, int show) +{ + wxCommandEvent* event = new wxCommandEvent(WX_SHOW_WINDOW_EVENT, wxID_ANY); + event->SetEventObject((wxWindow*)window); + event->SetInt(show); + wxQueueEvent((wxWindow*)window, event); +} + +void wx_togglewindow(void* window) +{ + wx_showwindow(window, -1); +} + +void wx_callback(void* window, WX_CALLBACK callback) +{ + CallbackEvent* event = new CallbackEvent(callback); + wxQueueEvent((wxWindow*)window, event); +} + +void wx_enddialog(void* window, int ret_code) +{ + ((wxDialog*) window)->EndModal(ret_code); +} + +int wx_dlgdirlist(void* window, const char* path, int id, int static_path, int file_type) +{ + wxWindow* w = ((wxWindow*) window)->FindWindow(id); + if (w->GetClassInfo()->IsKindOf(CLASSINFO(wxListBox))) + { + wxListBox* list = (wxListBox*)w; + list->Clear(); + wxArrayString items; + wxString f = wxFindFirstFile(path); + while (!f.empty()) + { + wxFileName file(f); + items.Add(file.GetName()); + f = wxFindNextFile(); + } + items.Sort(); + list->Set(items); + return TRUE; + } + return FALSE; +} + +int wx_dlgdirselectex(void* window, LONG_PARAM path, int count, int id) +{ + wxWindow* w = ((wxWindow*) window)->FindWindow(id); + if (w->GetClassInfo()->IsKindOf(CLASSINFO(wxListBox))) + { + wxListBox* list = (wxListBox*)w; + strcpy((char*)path, (list->GetStringSelection() + ".").GetData().AsChar()); + return TRUE; + } + return FALSE; +} + +int wx_sendmessage(void* window, int type, INT_PARAM param1, LONG_PARAM param2) +{ + switch (type) + { + case WX_CB_ADDSTRING: + ((wxComboBox*) window)->Append((char*) param2); + break; + case WX_CB_SETCURSEL: + ((wxComboBox*) window)->Select(param1); + break; + case WX_CB_GETCURSEL: + return ((wxComboBox*) window)->GetCurrentSelection(); + break; + case WX_CB_GETLBTEXT: + strcpy((char*) param2, ((wxComboBox*) window)->GetString(param1)); + break; + case WX_CB_RESETCONTENT: + { +#ifndef __WXOSX_MAC__ + ((wxComboBox*) window)->Clear(); +#else + /* Clear() does not work on OSX */ + wxComboBox* cb = (wxComboBox*) window; + int count = cb->GetCount(); + while (count--) + cb->Delete(0); +#endif + break; + } + case WX_BM_SETCHECK: + ((wxCheckBox*) window)->SetValue(param1); + break; + case WX_BM_GETCHECK: + return ((wxCheckBox*) window)->GetValue(); + break; + case WX_WM_SETTEXT: + { + if (((wxWindow*) window)->GetClassInfo()->IsKindOf(CLASSINFO(wxTextCtrl))) + ((wxTextCtrl*) window)->SetValue((char*) param2); + else + ((wxStaticText*) window)->SetLabel((char*) param2); + } + break; + case WX_WM_GETTEXT: + if (((wxWindow*) window)->GetClassInfo()->IsKindOf(CLASSINFO(wxTextCtrl))) + strcpy((char*) param2, ((wxTextCtrl*) window)->GetValue()); + else + strcpy((char*) param2, ((wxStaticText*) window)->GetLabel()); + break; + case WX_UDM_SETPOS: + ((wxSpinCtrl*) window)->SetValue(param2); + break; + case WX_UDM_GETPOS: + return ((wxSpinCtrl*) window)->GetValue(); + case WX_UDM_SETRANGE: + { + int min = (param2 >> 16) & 0xffff; + int max = param2 & 0xffff; + ((wxSpinCtrl*) window)->SetRange(min, max); + break; + } + case WX_UDM_SETINCR: + { + /* SetIncrement-method may not exist on all platforms */ +#ifdef __WXGTK__ + ((wxSpinCtrl*) window)->SetIncrement(param2); +#endif + break; + } + case WX_LB_GETCOUNT: + { + return ((wxListBox*) window)->GetCount(); + } + case WX_LB_GETCURSEL: + { + return ((wxListBox*) window)->GetSelection(); + } + case WX_LB_GETTEXT: + { + strcpy((char*) param2, ((wxListBox*) window)->GetString(param1)); + break; + } + case WX_LB_INSERTSTRING: + { + ((wxListBox*) window)->Insert((char*) param2, param1); + break; + } + case WX_LB_DELETESTRING: + { + ((wxListBox*) window)->Delete(param1); + break; + } + } + + ((wxWindow*)window)->Fit(); + + return 0; +} + +int wx_dialogbox(void* window, const char* name, int (*callback)(void* window, int message, INT_PARAM param1, LONG_PARAM param2)) +{ + PCemDialogBox dlg((wxWindow*) window, name, callback); + dlg.OnInit(); + dlg.Fit(); + int ret = dlg.ShowModal(); + dlg.Destroy(); + return ret; +} + +void wx_exit(void* window, int value) +{ + wxCommandEvent* event = new wxCommandEvent(WX_EXIT_EVENT, wxID_ANY); + event->SetEventObject((wxWindow*)window); + event->SetInt(value); + wxQueueEvent((wxWindow*)window, event); +} + +void wx_stop_emulation(void* window) +{ + wxCommandEvent* event = new wxCommandEvent(WX_STOP_EMULATION_EVENT, wxID_ANY); + event->SetEventObject((wxWindow*)window); + wxQueueEvent((wxWindow*)window, event); +} + +int wx_yield() +{ + return wxYield(); +} + +/* Timer stuff */ + +class PCemTimer : public wxTimer +{ +public: + PCemTimer(void (*fn)()) + { + this->fn = fn; + } + virtual ~PCemTimer() {}; + + void Notify() + { + fn(); + } +private: + void (*fn)(); +}; + +void* wx_createtimer(void (*fn)()) +{ + return new PCemTimer(fn); +} + +void wx_starttimer(void* timer, int milliseconds, int once) +{ + wxTimer* t = (wxTimer*)timer; + t->Start(milliseconds, once); +} + +void wx_stoptimer(void* timer) +{ + wxTimer* t = (wxTimer*)timer; + t->Stop(); +} + +void wx_destroytimer(void* timer) +{ + wx_stoptimer(timer); + delete (wxTimer*)timer; +} + +void wx_popupmenu(void* window, void* menu, int* x, int* y) +{ + PopupMenuEvent* event = new PopupMenuEvent((wxWindow*)window, (wxMenu*)menu, x, y); + wxQueueEvent((wxWindow*)window, event); +} + +void* wx_create_status_frame(void* window) +{ + StatusFrame* frame = new StatusFrame((wxWindow*)window); + return frame; +} + +void wx_destroy_status_frame(void* window) +{ + StatusFrame* frame = (StatusFrame*)window; + delete frame; +} + +void wx_setwindowposition(void* window, int x, int y) +{ + ((wxFrame*) window)->SetPosition(wxPoint(x, y)); +} + +void wx_setwindowsize(void* window, int width, int height) +{ + ((wxFrame*) window)->SetSize(wxSize(width, height)); +} + +void wx_show_status(void* window) +{ + wxWindow* status = ((wxWindow*)window)->FindWindowById(STATUS_WINDOW_ID); + if (!status) + { + StatusFrame* statusFrame = new StatusFrame((wxWindow*) window); + statusFrame->Show(); + } +} + +void wx_close_status(void* window) +{ + wxWindow* status = ((wxWindow*)window)->FindWindowById(STATUS_WINDOW_ID); + if (status) + { + status->Close(); + } +} diff --git a/src/wx-utils.h b/src/wx-utils.h new file mode 100644 index 0000000..84296bf --- /dev/null +++ b/src/wx-utils.h @@ -0,0 +1,112 @@ +#include + +#ifndef LONG_PARAM +#define LONG_PARAM wxIntPtr +#endif + +#ifndef INT_PARAM +#define INT_PARAM wxInt32 +#endif + +typedef void (*WX_CALLBACK)(); + +#ifdef __cplusplus +extern "C" { +#endif + int wx_messagebox(void* nothing, const char* message, const char* title, int style); + int wx_xrcid(const char* s); + int wx_filedialog(void* window, const char* title, const char* path, const char* extensions, const char* extension, int open, char* file); + void wx_checkmenuitem(void* window, int id, int checked); + void wx_enablemenuitem(void* menu, int id, int enable); + void* wx_getmenu(void* window); + void* wx_getmenubar(void* window); + void wx_enabletoolbaritem(void* toolbar, int id, int enable); + void* wx_gettoolbar(void* window); + + void* wx_getsubmenu(void* window, int id); + void wx_appendmenu(void* sub_menu, int id, const char* title, enum wxItemKind type); + + int wx_textentrydialog(void* window, const char* message, const char* title, const char* value, int min_length, int max_length, LONG_PARAM result); + + int wx_dlgdirlist(void* window, const char* path, int id, int static_path, int file_type); + int wx_dlgdirselectex(void* window, LONG_PARAM path, int count, int id); + + void wx_setwindowtitle(void* window, char* s); + int wx_sendmessage(void* window, int type, INT_PARAM param1, LONG_PARAM param2); + void* wx_getdlgitem(void* window, int id); + void wx_setdlgitemtext(void* window, int id, char* str); + void wx_enablewindow(void* window, int enabled); + void wx_showwindow(void* window, int show); + void wx_callback(void* window, WX_CALLBACK callback); + void wx_togglewindow(void* window); + + void wx_enddialog(void* window, int ret_code); + + int wx_dialogbox(void* window, const char* name, int(*callback)(void* window, int message, INT_PARAM param1, LONG_PARAM param2)); + + void wx_exit(void* window, int value); + void wx_stop_emulation(void* window); + + void* wx_createtimer(void (*fn)()); + void wx_starttimer(void* timer, int milliseconds, int once); + void wx_stoptimer(void* timer); + void wx_destroytimer(void* timer); + + void wx_popupmenu(void* window, void* menu, int* x, int* y); + + void* wx_create_status_frame(void* window); + void wx_destroy_status_frame(void* window); + + int wx_yield(); + + void wx_setwindowposition(void* window, int x, int y); + void wx_setwindowsize(void* window, int width, int height); + + void wx_show_status(void* window); + void wx_close_status(void* window); + + int confirm(); +#ifdef __cplusplus +} +#endif + +extern int (*wx_keydown_func)(void* window, void* event, int keycode, int modifiers); +extern int (*wx_keyup_func)(void* window, void* event, int keycode, int modifiers); +extern void (*wx_idle_func)(void* window, void* event); + +#define WX_ID wx_xrcid + +#define WX_MB_CHECKED 1 +#define WX_MB_UNCHECKED 0 + +#define WX_INITDIALOG 1 +#define WX_COMMAND 2 + +#define WX_CB_ADDSTRING 1 +#define WX_CB_SETCURSEL 2 +#define WX_CB_GETCURSEL 3 +#define WX_CB_RESETCONTENT 4 +#define WX_CB_GETLBTEXT 5 + +#define WX_BM_SETCHECK 20 +#define WX_BM_GETCHECK 21 + +#define WX_WM_SETTEXT 40 +#define WX_WM_GETTEXT 41 + +#define WX_UDM_SETPOS 50 +#define WX_UDM_GETPOS 51 +#define WX_UDM_SETINCR 52 +#define WX_UDM_SETRANGE 53 + +#define WX_LB_GETCOUNT 60 +#define WX_LB_GETCURSEL 61 +#define WX_LB_GETTEXT 62 +#define WX_LB_DELETESTRING 63 +#define WX_LB_INSERTSTRING 64 + +#define WX_MB_OK wxOK +#define WX_MB_OKCANCEL wxOK|wxCANCEL +#define WX_IDOK wxOK + +extern int has_been_inited;