From 926ffd969507da21e52705570ccae93d3f4a07c2 Mon Sep 17 00:00:00 2001 From: byuu Date: Mon, 4 Feb 2008 16:16:34 +0000 Subject: [PATCH] Update to bsnes v028 release. Changelog: - OpenGL (with hardware filter mode support) and SDL video drivers added to Linux port - OpenAL (with speed regulation disable support) and OSS audio drivers added to Linux port [Nach] - SDL input driver (with joypad support) added to Linux port - Emulator pause option added - Added option to select behavior of bsnes when idle: allow input, ignore input or pause emulator - Added support to remap common GUI actions to key/joypad presses on the "Input Configuration" screen - bsnes will now clamp the video output size when it is larger than the screen resolution - GUI library has been enhanced, and renamed to hiro - Fullscreen mode now always centers video, rather than approximates - Fullscreen mode now works correctly on Linux/Openbox - Extra layer of abstraction in src/ui has been removed, as GUI lib unifies all ports anyway - Video, audio and input drivers unified into standard library, named ruby - All custom headers have been merged into a new template library, named nall - Makefile rewritten, vastly improved. Allows quick toggling of compiled-in drivers - Makefile: all object files now placed in /src/obj, binary placed in / - libco greatly enhanced, no longer requires an assembler to build [byuu, blargg, Nach] - libco SJLJ driver added; bsnes should now build on any Unix-derivative now (Solaris, OS X, PS3, etc) [Nach] - Fixed register $213e.d4 PPU1 open bus behavior [zones] - Windows port will not activate screensaver while bsnes is running [Nightcrawler] - Visual C++ target no longer requires stdint.h - And lots more -- mostly code refactoring related --- license.txt | 2 +- readme.txt | 8 +- src/Makefile | 438 ++++++------- src/base.h | 31 +- src/bsnes.lnk | Bin 587 -> 0 bytes src/cart/cart_file.cpp | 2 +- src/cart/cart_st.cpp | 4 +- src/cc.bat | 9 +- src/cc.sh | 3 +- src/cheat/cheat.cpp | 4 +- src/cheat/cheat.h | 39 +- src/chip/chip.h | 1 - src/chip/superfx/core/core.h | 3 - src/chip/superfx/core/op0x.cpp | 7 - src/chip/superfx/memory/read.cpp | 66 -- src/chip/superfx/memory/write.cpp | 65 -- src/chip/superfx/regs.h | 174 ------ src/chip/superfx/superfx.cpp | 42 -- src/chip/superfx/superfx.h | 17 - src/clean.bat | 3 +- src/clean.sh | 2 +- src/config/config.cpp | 123 ++-- src/config/config.h | 45 +- src/cpu/scpu/timing/timing.cpp | 2 +- src/doc/base.dia | Bin 1943 -> 0 bytes src/interface.h | 1 - src/lib/bbase.h | 164 ++--- src/lib/bconfig.h | 185 ------ src/lib/bkeymap.h | 310 --------- src/lib/bstring.cpp | 95 --- src/lib/bstring.h | 99 --- src/lib/bstring/bstring.list.cpp | 14 - src/lib/bstring/bstring.math.cpp | 194 ------ src/lib/bstring/bstring.misc.cpp | 277 -------- src/lib/bstring/bstring.split.cpp | 39 -- src/lib/bstring/bstring.strl.cpp | 31 - src/lib/bstring/bstring.trim.cpp | 39 -- src/lib/{miu.cpp => hiro.cpp} | 68 +- src/lib/{miu.h => hiro.h} | 150 +++-- .../button.cpp} | 4 +- .../miu.gtk.button.h => hiro_gtk/button.h} | 2 +- .../canvas.cpp} | 30 +- .../miu.gtk.canvas.h => hiro_gtk/canvas.h} | 10 +- .../checkbox.cpp} | 4 +- .../checkbox.h} | 2 +- .../combobox.cpp} | 4 +- .../combobox.h} | 2 +- .../editbox.cpp} | 0 .../miu.gtk.editbox.h => hiro_gtk/editbox.h} | 2 +- .../formcontrol.cpp} | 0 .../formcontrol.h} | 2 +- .../miu.gtk.frame.cpp => hiro_gtk/frame.cpp} | 0 .../miu.gtk.frame.h => hiro_gtk/frame.h} | 2 +- src/lib/hiro_gtk/hiro.cpp | 121 ++++ src/lib/hiro_gtk/hiro.h | 56 ++ src/lib/hiro_gtk/keymap.cpp | 188 ++++++ .../miu.gtk.label.cpp => hiro_gtk/label.cpp} | 0 .../miu.gtk.label.h => hiro_gtk/label.h} | 2 +- .../listbox.cpp} | 12 +- .../miu.gtk.listbox.h => hiro_gtk/listbox.h} | 2 +- .../menucheckitem.cpp} | 4 +- .../menucheckitem.h} | 2 +- .../menucontrol.cpp} | 0 .../menucontrol.h} | 2 +- .../menugroup.cpp} | 0 .../menugroup.h} | 2 +- .../menuitem.cpp} | 4 +- .../menuitem.h} | 2 +- .../menuradioitem.cpp} | 4 +- .../menuradioitem.h} | 2 +- .../menuseparator.cpp} | 0 .../menuseparator.h} | 2 +- .../progressbar.cpp} | 4 +- .../progressbar.h} | 2 +- .../radiobox.cpp} | 4 +- .../radiobox.h} | 2 +- .../slider.cpp} | 4 +- .../miu.gtk.slider.h => hiro_gtk/slider.h} | 2 +- .../widget.cpp} | 2 +- .../miu.gtk.widget.h => hiro_gtk/widget.h} | 2 +- src/lib/hiro_gtk/window.cpp | 262 ++++++++ .../miu.gtk.window.h => hiro_gtk/window.h} | 46 +- .../button.cpp} | 4 +- .../miu.win.button.h => hiro_win/button.h} | 0 .../canvas.cpp} | 14 +- .../miu.win.canvas.h => hiro_win/canvas.h} | 6 +- .../checkbox.cpp} | 4 +- .../checkbox.h} | 0 .../combobox.cpp} | 4 +- .../combobox.h} | 2 +- .../editbox.cpp} | 24 +- .../miu.win.editbox.h => hiro_win/editbox.h} | 0 .../formcontrol.cpp} | 0 .../formcontrol.h} | 2 +- .../miu.win.frame.cpp => hiro_win/frame.cpp} | 4 +- .../miu.win.frame.h => hiro_win/frame.h} | 0 .../miu.win.cpp => hiro_win/hiro.cpp} | 122 ++-- src/lib/hiro_win/hiro.h | 73 +++ src/lib/hiro_win/keymap.cpp | 67 ++ .../miu.win.label.cpp => hiro_win/label.cpp} | 4 +- .../miu.win.label.h => hiro_win/label.h} | 0 .../listbox.cpp} | 4 +- .../miu.win.listbox.h => hiro_win/listbox.h} | 2 +- .../menucheckitem.cpp} | 0 .../menucheckitem.h} | 0 .../menucontrol.cpp} | 2 +- .../menucontrol.h} | 2 +- .../menugroup.cpp} | 0 .../menugroup.h} | 2 +- .../menuitem.cpp} | 0 .../menuitem.h} | 0 .../menuradioitem.cpp} | 0 .../menuradioitem.h} | 2 +- .../menuseparator.cpp} | 0 .../menuseparator.h} | 0 .../progressbar.cpp} | 6 +- .../progressbar.h} | 0 .../radiobox.cpp} | 4 +- .../radiobox.h} | 2 +- .../slider.cpp} | 2 +- .../miu.win.slider.h => hiro_win/slider.h} | 2 +- .../widget.cpp} | 2 +- src/lib/hiro_win/widget.h | 19 + .../window.cpp} | 123 +++- .../miu.win.window.h => hiro_win/window.h} | 47 +- src/lib/libco.c | 21 + src/lib/libco.h | 35 +- src/lib/libco/fiber.c | 51 ++ src/lib/libco/libco.ucontext.cpp | 80 --- src/lib/libco/libco.win.cpp | 66 -- src/lib/libco/libco.x86-64.asm | 146 ----- src/lib/libco/libco.x86.asm | 155 ----- src/lib/libco/{libco.ppc.s => ppc.s} | 0 src/lib/libco/{libco.ppc64.s => ppc64.s} | 0 src/lib/libco/sjlj.c | 102 +++ src/lib/libco/ucontext.c | 67 ++ src/lib/libco/x86-64.c | 81 +++ src/lib/libco/x86.c | 110 ++++ src/lib/miu.gtk/miu.gtk.cpp | 118 ---- src/lib/miu.gtk/miu.gtk.h | 58 -- src/lib/miu.gtk/miu.gtk.keymap.cpp | 188 ------ src/lib/miu.gtk/miu.gtk.window.cpp | 135 ---- src/lib/miu.win/miu.win.h | 73 --- src/lib/miu.win/miu.win.keymap.cpp | 67 -- src/lib/miu.win/miu.win.widget.h | 19 - src/lib/nall/Makefile.string | 63 ++ src/lib/nall/algorithm.hpp | 21 + src/lib/nall/any.hpp | 76 +++ src/lib/{barray.h => nall/array.hpp} | 41 +- src/lib/nall/bit.hpp | 28 + src/lib/nall/config.hpp | 186 ++++++ src/lib/nall/file.hpp | 189 ++++++ src/lib/{bfunction.h => nall/function.hpp} | 49 +- src/lib/nall/input.hpp | 134 ++++ src/lib/nall/new.hpp | 27 + src/lib/nall/sort.hpp | 40 ++ src/lib/nall/static.hpp | 21 + src/lib/nall/stdint.hpp | 46 ++ src/lib/nall/string.cpp | 16 + src/lib/nall/string.hpp | 120 ++++ src/lib/nall/string/class.cpp | 223 +++++++ src/lib/nall/string/compare.cpp | 100 +++ src/lib/nall/string/convert.cpp | 293 +++++++++ src/lib/nall/string/match.cpp | 72 +++ src/lib/nall/string/math.cpp | 150 +++++ .../string/replace.cpp} | 25 +- src/lib/nall/string/split.cpp | 52 ++ src/lib/nall/string/strl.cpp | 48 ++ src/lib/nall/string/trim.cpp | 36 ++ src/lib/nall/traits.hpp | 90 +++ src/lib/nall/utility.hpp | 24 + src/lib/nall/varint.hpp | 103 +++ src/lib/{bvector.h => nall/vector.hpp} | 55 +- src/{ui/vai => lib/ruby}/audio.h | 13 +- .../audio.ao.cpp => lib/ruby/audio/ao.cpp} | 83 +-- .../audio/audio.ao.h => lib/ruby/audio/ao.h} | 48 +- .../ruby/audio/directsound.cpp} | 55 +- src/lib/ruby/audio/directsound.h | 24 + src/lib/ruby/audio/openal.cpp | 194 ++++++ src/lib/ruby/audio/openal.h | 24 + src/lib/ruby/audio/oss.cpp | 118 ++++ src/lib/ruby/audio/oss.h | 23 + src/lib/ruby/input.h | 21 + src/lib/ruby/input/directinput.cpp | 321 ++++++++++ .../ruby/input/directinput.h} | 13 +- src/lib/ruby/input/sdl.cpp | 286 +++++++++ src/lib/ruby/input/sdl.h | 17 + src/lib/ruby/input/x.cpp | 175 ++++++ src/lib/ruby/input/x.h | 17 + src/lib/ruby/ruby.cpp | 195 ++++++ src/lib/ruby/ruby.h | 88 +++ src/lib/ruby/ruby.impl.h | 57 ++ src/{ui/vai => lib/ruby}/video.h | 15 +- .../ruby/video/direct3d.cpp} | 338 +++++----- src/lib/ruby/video/direct3d.h | 22 + .../ruby/video/directdraw.cpp} | 44 +- src/lib/ruby/video/directdraw.h | 22 + .../video.gdi.cpp => lib/ruby/video/gdi.cpp} | 36 +- .../video.gdi.h => lib/ruby/video/gdi.h} | 13 +- src/lib/ruby/video/glx.cpp | 241 +++++++ src/lib/ruby/video/glx.h | 22 + src/lib/ruby/video/sdl.cpp | 113 ++++ src/lib/ruby/video/sdl.h | 22 + .../video.xv.cpp => lib/ruby/video/xv.cpp} | 109 ++-- src/lib/ruby/video/xv.h | 22 + src/ppu/bppu/bppu_mmio.cpp | 14 +- src/ppu/bppu/bppu_render_mode7.cpp | 141 ++--- src/smp/iplrom.h | 2 +- src/snes/audio/audio.cpp | 3 +- src/snes/scheduler/scheduler.cpp | 21 +- src/snes/snes.cpp | 9 +- src/ui/config.cpp | 189 +++--- src/ui/{miu => }/event.cpp | 590 ++++++++++-------- src/ui/{miu => }/event.h | 12 +- src/ui/inputmgr.cpp | 274 ++++---- src/ui/interface.cpp | 18 +- src/ui/{miu => }/loader/ui_bsxloader.cpp | 0 src/ui/{miu => }/loader/ui_bsxloader.h | 0 src/ui/{miu => }/loader/ui_stloader.cpp | 0 src/ui/{miu => }/loader/ui_stloader.h | 0 src/ui/main.cpp | 203 +++++- src/ui/miu/main.cpp | 127 ---- src/ui/miu/settings/ui_inputconfig.cpp | 214 ------- src/ui/miu/ui.cpp | 114 ---- src/ui/{miu => }/settings/ui_advanced.cpp | 52 +- src/ui/{miu => }/settings/ui_advanced.h | 0 src/ui/{miu => }/settings/ui_cheateditor.cpp | 7 - src/ui/{miu => }/settings/ui_cheateditor.h | 0 src/ui/settings/ui_inputconfig.cpp | 238 +++++++ src/ui/{miu => }/settings/ui_inputconfig.h | 26 +- .../{miu => }/settings/ui_rastersettings.cpp | 12 +- src/ui/{miu => }/settings/ui_rastersettings.h | 0 src/ui/{miu => }/settings/ui_settings.cpp | 0 src/ui/{miu => }/settings/ui_settings.h | 0 src/ui/ui.cpp | 64 ++ src/ui/{miu => }/ui.h | 3 +- src/ui/{miu => }/ui_about.cpp | 0 src/ui/{miu => }/ui_about.h | 0 src/ui/{miu => }/ui_main.cpp | 59 +- src/ui/{miu => }/ui_main.h | 6 +- src/ui/ui_message.cpp | 20 + src/ui/ui_message.h | 9 + src/ui/vai/audio/audio.directsound.h | 26 - src/ui/vai/input.h | 29 - src/ui/vai/input/input.directinput.cpp | 293 --------- src/ui/vai/input/input.x.cpp | 168 ----- src/ui/vai/input/input.x.h | 24 - src/ui/vai/video/video.direct3d.h | 29 - src/ui/vai/video/video.directdraw.h | 29 - src/ui/vai/video/video.gtk.cpp | 120 ---- src/ui/vai/video/video.gtk.h | 28 - src/ui/vai/video/video.xv.h | 29 - src/ui/win/bsnes.cpp | 55 -- src/ui/win/bsnes.h | 11 - src/ui/win/config.cpp | 25 - src/ui/win/debugger/debugger.cpp | 105 ---- src/ui/win/debugger/debugger.h | 22 - src/ui/win/debugger/ui_debugger.cpp | 131 ---- src/ui/win/debugger/ui_debugger.h | 34 - src/ui/win/debugger/ui_memory.cpp | 270 -------- src/ui/win/debugger/ui_memory.h | 40 -- src/ui/win/debugger/ui_tracer.cpp | 48 -- src/ui/win/debugger/ui_tracer.h | 18 - src/ui/win/event.cpp | 145 ----- src/ui/win/event.h | 14 - src/ui/win/libwin32/libwin32.cpp | 107 ---- src/ui/win/libwin32/libwin32.h | 63 -- src/ui/win/libwin32/libwin32_button.cpp | 32 - src/ui/win/libwin32/libwin32_checkbox.cpp | 40 -- src/ui/win/libwin32/libwin32_combobox.cpp | 66 -- src/ui/win/libwin32/libwin32_control.cpp | 99 --- src/ui/win/libwin32/libwin32_control.h | 186 ------ src/ui/win/libwin32/libwin32_editbox.cpp | 43 -- src/ui/win/libwin32/libwin32_file.cpp | 48 -- src/ui/win/libwin32/libwin32_groupbox.cpp | 33 - src/ui/win/libwin32/libwin32_label.cpp | 38 -- src/ui/win/libwin32/libwin32_listbox.cpp | 66 -- src/ui/win/libwin32/libwin32_listview.cpp | 96 --- src/ui/win/libwin32/libwin32_misc.cpp | 33 - src/ui/win/libwin32/libwin32_radiobox.cpp | 39 -- src/ui/win/libwin32/libwin32_slider.cpp | 47 -- src/ui/win/libwin32/libwin32_window.cpp | 456 -------------- src/ui/win/libwin32/libwin32_window.h | 97 --- src/ui/win/main.cpp | 104 --- src/ui/win/settings/settings.cpp | 61 -- src/ui/win/settings/settings.h | 17 - src/ui/win/settings/ui_cheateditor.cpp | 169 ----- src/ui/win/settings/ui_cheateditor.h | 30 - src/ui/win/settings/ui_coloradjust.cpp | 102 --- src/ui/win/settings/ui_coloradjust.h | 19 - src/ui/win/settings/ui_emusettings.cpp | 100 --- src/ui/win/settings/ui_emusettings.h | 21 - src/ui/win/settings/ui_inputconfig.cpp | 249 -------- src/ui/win/settings/ui_inputconfig.h | 38 -- src/ui/win/settings/ui_rastersettings.cpp | 33 - src/ui/win/settings/ui_rastersettings.h | 13 - src/ui/win/settings/ui_settings.cpp | 52 -- src/ui/win/settings/ui_settings.h | 19 - src/ui/win/settings/ui_videosettings.cpp | 99 --- src/ui/win/settings/ui_videosettings.h | 38 -- src/ui/win/ui.cpp | 66 -- src/ui/win/ui.h | 91 --- src/ui/win/ui_about.cpp | 50 -- src/ui/win/ui_input.cpp | 29 - src/ui/win/ui_main.cpp | 284 --------- 305 files changed, 8060 insertions(+), 10130 deletions(-) delete mode 100644 src/bsnes.lnk delete mode 100644 src/chip/superfx/core/core.h delete mode 100644 src/chip/superfx/core/op0x.cpp delete mode 100644 src/chip/superfx/memory/read.cpp delete mode 100644 src/chip/superfx/memory/write.cpp delete mode 100644 src/chip/superfx/regs.h delete mode 100644 src/chip/superfx/superfx.cpp delete mode 100644 src/chip/superfx/superfx.h delete mode 100644 src/doc/base.dia delete mode 100644 src/lib/bconfig.h delete mode 100644 src/lib/bkeymap.h delete mode 100644 src/lib/bstring.cpp delete mode 100644 src/lib/bstring.h delete mode 100644 src/lib/bstring/bstring.list.cpp delete mode 100644 src/lib/bstring/bstring.math.cpp delete mode 100644 src/lib/bstring/bstring.misc.cpp delete mode 100644 src/lib/bstring/bstring.split.cpp delete mode 100644 src/lib/bstring/bstring.strl.cpp delete mode 100644 src/lib/bstring/bstring.trim.cpp rename src/lib/{miu.cpp => hiro.cpp} (84%) rename src/lib/{miu.h => hiro.h} (69%) rename src/lib/{miu.gtk/miu.gtk.button.cpp => hiro_gtk/button.cpp} (89%) rename src/lib/{miu.gtk/miu.gtk.button.h => hiro_gtk/button.h} (93%) rename src/lib/{miu.gtk/miu.gtk.canvas.cpp => hiro_gtk/canvas.cpp} (73%) rename src/lib/{miu.gtk/miu.gtk.canvas.h => hiro_gtk/canvas.h} (56%) rename src/lib/{miu.gtk/miu.gtk.checkbox.cpp => hiro_gtk/checkbox.cpp} (91%) rename src/lib/{miu.gtk/miu.gtk.checkbox.h => hiro_gtk/checkbox.h} (95%) rename src/lib/{miu.gtk/miu.gtk.combobox.cpp => hiro_gtk/combobox.cpp} (92%) rename src/lib/{miu.gtk/miu.gtk.combobox.h => hiro_gtk/combobox.h} (95%) rename src/lib/{miu.gtk/miu.gtk.editbox.cpp => hiro_gtk/editbox.cpp} (100%) rename src/lib/{miu.gtk/miu.gtk.editbox.h => hiro_gtk/editbox.h} (95%) rename src/lib/{miu.gtk/miu.gtk.formcontrol.cpp => hiro_gtk/formcontrol.cpp} (100%) rename src/lib/{miu.gtk/miu.gtk.formcontrol.h => hiro_gtk/formcontrol.h} (94%) rename src/lib/{miu.gtk/miu.gtk.frame.cpp => hiro_gtk/frame.cpp} (100%) rename src/lib/{miu.gtk/miu.gtk.frame.h => hiro_gtk/frame.h} (93%) create mode 100644 src/lib/hiro_gtk/hiro.cpp create mode 100644 src/lib/hiro_gtk/hiro.h create mode 100644 src/lib/hiro_gtk/keymap.cpp rename src/lib/{miu.gtk/miu.gtk.label.cpp => hiro_gtk/label.cpp} (100%) rename src/lib/{miu.gtk/miu.gtk.label.h => hiro_gtk/label.h} (93%) rename src/lib/{miu.gtk/miu.gtk.listbox.cpp => hiro_gtk/listbox.cpp} (95%) rename src/lib/{miu.gtk/miu.gtk.listbox.h => hiro_gtk/listbox.h} (97%) rename src/lib/{miu.gtk/miu.gtk.menucheckitem.cpp => hiro_gtk/menucheckitem.cpp} (88%) rename src/lib/{miu.gtk/miu.gtk.menucheckitem.h => hiro_gtk/menucheckitem.h} (94%) rename src/lib/{miu.gtk/miu.gtk.menucontrol.cpp => hiro_gtk/menucontrol.cpp} (100%) rename src/lib/{miu.gtk/miu.gtk.menucontrol.h => hiro_gtk/menucontrol.h} (92%) rename src/lib/{miu.gtk/miu.gtk.menugroup.cpp => hiro_gtk/menugroup.cpp} (100%) rename src/lib/{miu.gtk/miu.gtk.menugroup.h => hiro_gtk/menugroup.h} (93%) rename src/lib/{miu.gtk/miu.gtk.menuitem.cpp => hiro_gtk/menuitem.cpp} (83%) rename src/lib/{miu.gtk/miu.gtk.menuitem.h => hiro_gtk/menuitem.h} (91%) rename src/lib/{miu.gtk/miu.gtk.menuradioitem.cpp => hiro_gtk/menuradioitem.cpp} (91%) rename src/lib/{miu.gtk/miu.gtk.menuradioitem.h => hiro_gtk/menuradioitem.h} (93%) rename src/lib/{miu.gtk/miu.gtk.menuseparator.cpp => hiro_gtk/menuseparator.cpp} (100%) rename src/lib/{miu.gtk/miu.gtk.menuseparator.h => hiro_gtk/menuseparator.h} (91%) rename src/lib/{miu.gtk/miu.gtk.progressbar.cpp => hiro_gtk/progressbar.cpp} (88%) rename src/lib/{miu.gtk/miu.gtk.progressbar.h => hiro_gtk/progressbar.h} (94%) rename src/lib/{miu.gtk/miu.gtk.radiobox.cpp => hiro_gtk/radiobox.cpp} (93%) rename src/lib/{miu.gtk/miu.gtk.radiobox.h => hiro_gtk/radiobox.h} (94%) rename src/lib/{miu.gtk/miu.gtk.slider.cpp => hiro_gtk/slider.cpp} (92%) rename src/lib/{miu.gtk/miu.gtk.slider.h => hiro_gtk/slider.h} (94%) rename src/lib/{miu.gtk/miu.gtk.widget.cpp => hiro_gtk/widget.cpp} (87%) rename src/lib/{miu.gtk/miu.gtk.widget.h => hiro_gtk/widget.h} (91%) create mode 100644 src/lib/hiro_gtk/window.cpp rename src/lib/{miu.gtk/miu.gtk.window.h => hiro_gtk/window.h} (52%) rename src/lib/{miu.win/miu.win.button.cpp => hiro_win/button.cpp} (75%) rename src/lib/{miu.win/miu.win.button.h => hiro_win/button.h} (100%) rename src/lib/{miu.win/miu.win.canvas.cpp => hiro_win/canvas.cpp} (79%) rename src/lib/{miu.win/miu.win.canvas.h => hiro_win/canvas.h} (82%) rename src/lib/{miu.win/miu.win.checkbox.cpp => hiro_win/checkbox.cpp} (84%) rename src/lib/{miu.win/miu.win.checkbox.h => hiro_win/checkbox.h} (100%) rename src/lib/{miu.win/miu.win.combobox.cpp => hiro_win/combobox.cpp} (85%) rename src/lib/{miu.win/miu.win.combobox.h => hiro_win/combobox.h} (94%) rename src/lib/{miu.win/miu.win.editbox.cpp => hiro_win/editbox.cpp} (53%) rename src/lib/{miu.win/miu.win.editbox.h => hiro_win/editbox.h} (100%) rename src/lib/{miu.win/miu.win.formcontrol.cpp => hiro_win/formcontrol.cpp} (100%) rename src/lib/{miu.win/miu.win.formcontrol.h => hiro_win/formcontrol.h} (94%) rename src/lib/{miu.win/miu.win.frame.cpp => hiro_win/frame.cpp} (73%) rename src/lib/{miu.win/miu.win.frame.h => hiro_win/frame.h} (100%) rename src/lib/{miu.win/miu.win.cpp => hiro_win/hiro.cpp} (74%) create mode 100644 src/lib/hiro_win/hiro.h create mode 100644 src/lib/hiro_win/keymap.cpp rename src/lib/{miu.win/miu.win.label.cpp => hiro_win/label.cpp} (72%) rename src/lib/{miu.win/miu.win.label.h => hiro_win/label.h} (100%) rename src/lib/{miu.win/miu.win.listbox.cpp => hiro_win/listbox.cpp} (95%) rename src/lib/{miu.win/miu.win.listbox.h => hiro_win/listbox.h} (96%) rename src/lib/{miu.win/miu.win.menucheckitem.cpp => hiro_win/menucheckitem.cpp} (100%) rename src/lib/{miu.win/miu.win.menucheckitem.h => hiro_win/menucheckitem.h} (100%) rename src/lib/{miu.win/miu.win.menucontrol.cpp => hiro_win/menucontrol.cpp} (95%) rename src/lib/{miu.win/miu.win.menucontrol.h => hiro_win/menucontrol.h} (92%) rename src/lib/{miu.win/miu.win.menugroup.cpp => hiro_win/menugroup.cpp} (100%) rename src/lib/{miu.win/miu.win.menugroup.h => hiro_win/menugroup.h} (91%) rename src/lib/{miu.win/miu.win.menuitem.cpp => hiro_win/menuitem.cpp} (100%) rename src/lib/{miu.win/miu.win.menuitem.h => hiro_win/menuitem.h} (100%) rename src/lib/{miu.win/miu.win.menuradioitem.cpp => hiro_win/menuradioitem.cpp} (100%) rename src/lib/{miu.win/miu.win.menuradioitem.h => hiro_win/menuradioitem.h} (93%) rename src/lib/{miu.win/miu.win.menuseparator.cpp => hiro_win/menuseparator.cpp} (100%) rename src/lib/{miu.win/miu.win.menuseparator.h => hiro_win/menuseparator.h} (100%) rename src/lib/{miu.win/miu.win.progressbar.cpp => hiro_win/progressbar.cpp} (79%) rename src/lib/{miu.win/miu.win.progressbar.h => hiro_win/progressbar.h} (100%) rename src/lib/{miu.win/miu.win.radiobox.cpp => hiro_win/radiobox.cpp} (85%) rename src/lib/{miu.win/miu.win.radiobox.h => hiro_win/radiobox.h} (94%) rename src/lib/{miu.win/miu.win.slider.cpp => hiro_win/slider.cpp} (92%) rename src/lib/{miu.win/miu.win.slider.h => hiro_win/slider.h} (93%) rename src/lib/{miu.win/miu.win.widget.cpp => hiro_win/widget.cpp} (93%) create mode 100644 src/lib/hiro_win/widget.h rename src/lib/{miu.win/miu.win.window.cpp => hiro_win/window.cpp} (68%) rename src/lib/{miu.win/miu.win.window.h => hiro_win/window.h} (59%) create mode 100644 src/lib/libco.c create mode 100644 src/lib/libco/fiber.c delete mode 100644 src/lib/libco/libco.ucontext.cpp delete mode 100644 src/lib/libco/libco.win.cpp delete mode 100644 src/lib/libco/libco.x86-64.asm delete mode 100644 src/lib/libco/libco.x86.asm rename src/lib/libco/{libco.ppc.s => ppc.s} (100%) rename src/lib/libco/{libco.ppc64.s => ppc64.s} (100%) create mode 100644 src/lib/libco/sjlj.c create mode 100644 src/lib/libco/ucontext.c create mode 100644 src/lib/libco/x86-64.c create mode 100644 src/lib/libco/x86.c delete mode 100644 src/lib/miu.gtk/miu.gtk.cpp delete mode 100644 src/lib/miu.gtk/miu.gtk.h delete mode 100644 src/lib/miu.gtk/miu.gtk.keymap.cpp delete mode 100644 src/lib/miu.gtk/miu.gtk.window.cpp delete mode 100644 src/lib/miu.win/miu.win.h delete mode 100644 src/lib/miu.win/miu.win.keymap.cpp delete mode 100644 src/lib/miu.win/miu.win.widget.h create mode 100644 src/lib/nall/Makefile.string create mode 100644 src/lib/nall/algorithm.hpp create mode 100644 src/lib/nall/any.hpp rename src/lib/{barray.h => nall/array.hpp} (67%) create mode 100644 src/lib/nall/bit.hpp create mode 100644 src/lib/nall/config.hpp create mode 100644 src/lib/nall/file.hpp rename src/lib/{bfunction.h => nall/function.hpp} (84%) create mode 100644 src/lib/nall/input.hpp create mode 100644 src/lib/nall/new.hpp create mode 100644 src/lib/nall/sort.hpp create mode 100644 src/lib/nall/static.hpp create mode 100644 src/lib/nall/stdint.hpp create mode 100644 src/lib/nall/string.cpp create mode 100644 src/lib/nall/string.hpp create mode 100644 src/lib/nall/string/class.cpp create mode 100644 src/lib/nall/string/compare.cpp create mode 100644 src/lib/nall/string/convert.cpp create mode 100644 src/lib/nall/string/match.cpp create mode 100644 src/lib/nall/string/math.cpp rename src/lib/{bstring/bstring.replace.cpp => nall/string/replace.cpp} (77%) create mode 100644 src/lib/nall/string/split.cpp create mode 100644 src/lib/nall/string/strl.cpp create mode 100644 src/lib/nall/string/trim.cpp create mode 100644 src/lib/nall/traits.hpp create mode 100644 src/lib/nall/utility.hpp create mode 100644 src/lib/nall/varint.hpp rename src/lib/{bvector.h => nall/vector.hpp} (79%) rename src/{ui/vai => lib/ruby}/audio.h (57%) rename src/{ui/vai/audio/audio.ao.cpp => lib/ruby/audio/ao.cpp} (77%) rename src/{ui/vai/audio/audio.ao.h => lib/ruby/audio/ao.h} (54%) rename src/{ui/vai/audio/audio.directsound.cpp => lib/ruby/audio/directsound.cpp} (79%) create mode 100644 src/lib/ruby/audio/directsound.h create mode 100644 src/lib/ruby/audio/openal.cpp create mode 100644 src/lib/ruby/audio/openal.h create mode 100644 src/lib/ruby/audio/oss.cpp create mode 100644 src/lib/ruby/audio/oss.h create mode 100644 src/lib/ruby/input.h create mode 100644 src/lib/ruby/input/directinput.cpp rename src/{ui/vai/input/input.directinput.h => lib/ruby/input/directinput.h} (51%) create mode 100644 src/lib/ruby/input/sdl.cpp create mode 100644 src/lib/ruby/input/sdl.h create mode 100644 src/lib/ruby/input/x.cpp create mode 100644 src/lib/ruby/input/x.h create mode 100644 src/lib/ruby/ruby.cpp create mode 100644 src/lib/ruby/ruby.h create mode 100644 src/lib/ruby/ruby.impl.h rename src/{ui/vai => lib/ruby}/video.h (56%) rename src/{ui/vai/video/video.direct3d.cpp => lib/ruby/video/direct3d.cpp} (72%) create mode 100644 src/lib/ruby/video/direct3d.h rename src/{ui/vai/video/video.directdraw.cpp => lib/ruby/video/directdraw.cpp} (80%) create mode 100644 src/lib/ruby/video/directdraw.h rename src/{ui/vai/video/video.gdi.cpp => lib/ruby/video/gdi.cpp} (73%) rename src/{ui/vai/video/video.gdi.h => lib/ruby/video/gdi.h} (51%) create mode 100644 src/lib/ruby/video/glx.cpp create mode 100644 src/lib/ruby/video/glx.h create mode 100644 src/lib/ruby/video/sdl.cpp create mode 100644 src/lib/ruby/video/sdl.h rename src/{ui/vai/video/video.xv.cpp => lib/ruby/video/xv.cpp} (63%) create mode 100644 src/lib/ruby/video/xv.h rename src/ui/{miu => }/event.cpp (59%) rename src/ui/{miu => }/event.h (84%) rename src/ui/{miu => }/loader/ui_bsxloader.cpp (100%) rename src/ui/{miu => }/loader/ui_bsxloader.h (100%) rename src/ui/{miu => }/loader/ui_stloader.cpp (100%) rename src/ui/{miu => }/loader/ui_stloader.h (100%) delete mode 100644 src/ui/miu/main.cpp delete mode 100644 src/ui/miu/settings/ui_inputconfig.cpp delete mode 100644 src/ui/miu/ui.cpp rename src/ui/{miu => }/settings/ui_advanced.cpp (59%) rename src/ui/{miu => }/settings/ui_advanced.h (100%) rename src/ui/{miu => }/settings/ui_cheateditor.cpp (89%) rename src/ui/{miu => }/settings/ui_cheateditor.h (100%) create mode 100644 src/ui/settings/ui_inputconfig.cpp rename src/ui/{miu => }/settings/ui_inputconfig.h (68%) rename src/ui/{miu => }/settings/ui_rastersettings.cpp (91%) rename src/ui/{miu => }/settings/ui_rastersettings.h (100%) rename src/ui/{miu => }/settings/ui_settings.cpp (100%) rename src/ui/{miu => }/settings/ui_settings.h (100%) create mode 100644 src/ui/ui.cpp rename src/ui/{miu => }/ui.h (89%) rename src/ui/{miu => }/ui_about.cpp (100%) rename src/ui/{miu => }/ui_about.h (100%) rename src/ui/{miu => }/ui_main.cpp (90%) rename src/ui/{miu => }/ui_main.h (95%) create mode 100644 src/ui/ui_message.cpp create mode 100644 src/ui/ui_message.h delete mode 100644 src/ui/vai/audio/audio.directsound.h delete mode 100644 src/ui/vai/input.h delete mode 100644 src/ui/vai/input/input.directinput.cpp delete mode 100644 src/ui/vai/input/input.x.cpp delete mode 100644 src/ui/vai/input/input.x.h delete mode 100644 src/ui/vai/video/video.direct3d.h delete mode 100644 src/ui/vai/video/video.directdraw.h delete mode 100644 src/ui/vai/video/video.gtk.cpp delete mode 100644 src/ui/vai/video/video.gtk.h delete mode 100644 src/ui/vai/video/video.xv.h delete mode 100644 src/ui/win/bsnes.cpp delete mode 100644 src/ui/win/bsnes.h delete mode 100644 src/ui/win/config.cpp delete mode 100644 src/ui/win/debugger/debugger.cpp delete mode 100644 src/ui/win/debugger/debugger.h delete mode 100644 src/ui/win/debugger/ui_debugger.cpp delete mode 100644 src/ui/win/debugger/ui_debugger.h delete mode 100644 src/ui/win/debugger/ui_memory.cpp delete mode 100644 src/ui/win/debugger/ui_memory.h delete mode 100644 src/ui/win/debugger/ui_tracer.cpp delete mode 100644 src/ui/win/debugger/ui_tracer.h delete mode 100644 src/ui/win/event.cpp delete mode 100644 src/ui/win/event.h delete mode 100644 src/ui/win/libwin32/libwin32.cpp delete mode 100644 src/ui/win/libwin32/libwin32.h delete mode 100644 src/ui/win/libwin32/libwin32_button.cpp delete mode 100644 src/ui/win/libwin32/libwin32_checkbox.cpp delete mode 100644 src/ui/win/libwin32/libwin32_combobox.cpp delete mode 100644 src/ui/win/libwin32/libwin32_control.cpp delete mode 100644 src/ui/win/libwin32/libwin32_control.h delete mode 100644 src/ui/win/libwin32/libwin32_editbox.cpp delete mode 100644 src/ui/win/libwin32/libwin32_file.cpp delete mode 100644 src/ui/win/libwin32/libwin32_groupbox.cpp delete mode 100644 src/ui/win/libwin32/libwin32_label.cpp delete mode 100644 src/ui/win/libwin32/libwin32_listbox.cpp delete mode 100644 src/ui/win/libwin32/libwin32_listview.cpp delete mode 100644 src/ui/win/libwin32/libwin32_misc.cpp delete mode 100644 src/ui/win/libwin32/libwin32_radiobox.cpp delete mode 100644 src/ui/win/libwin32/libwin32_slider.cpp delete mode 100644 src/ui/win/libwin32/libwin32_window.cpp delete mode 100644 src/ui/win/libwin32/libwin32_window.h delete mode 100644 src/ui/win/main.cpp delete mode 100644 src/ui/win/settings/settings.cpp delete mode 100644 src/ui/win/settings/settings.h delete mode 100644 src/ui/win/settings/ui_cheateditor.cpp delete mode 100644 src/ui/win/settings/ui_cheateditor.h delete mode 100644 src/ui/win/settings/ui_coloradjust.cpp delete mode 100644 src/ui/win/settings/ui_coloradjust.h delete mode 100644 src/ui/win/settings/ui_emusettings.cpp delete mode 100644 src/ui/win/settings/ui_emusettings.h delete mode 100644 src/ui/win/settings/ui_inputconfig.cpp delete mode 100644 src/ui/win/settings/ui_inputconfig.h delete mode 100644 src/ui/win/settings/ui_rastersettings.cpp delete mode 100644 src/ui/win/settings/ui_rastersettings.h delete mode 100644 src/ui/win/settings/ui_settings.cpp delete mode 100644 src/ui/win/settings/ui_settings.h delete mode 100644 src/ui/win/settings/ui_videosettings.cpp delete mode 100644 src/ui/win/settings/ui_videosettings.h delete mode 100644 src/ui/win/ui.cpp delete mode 100644 src/ui/win/ui.h delete mode 100644 src/ui/win/ui_about.cpp delete mode 100644 src/ui/win/ui_input.cpp delete mode 100644 src/ui/win/ui_main.cpp diff --git a/license.txt b/license.txt index 18995f5d..0f3bc4f5 100644 --- a/license.txt +++ b/license.txt @@ -1,5 +1,5 @@ bsnes (TM) Reference License -Copyright (C) 2004 - 2007 byuu +Copyright (C) 2004 - 2008 byuu All rights reserved 1. Definitions diff --git a/readme.txt b/readme.txt index e2398abd..76b555ba 100644 --- a/readme.txt +++ b/readme.txt @@ -1,5 +1,5 @@ bsnes -Version 0.027 +Version: 0.028 Author: byuu -------- @@ -13,12 +13,6 @@ http://byuu.org/ Please see license.txt for important licensing information. --------------- -Shortcut Keys: --------------- -Esc - Toggle menubar visibility -F11 - Toggle fullscreen mode - ------------------ Known Limitations: ------------------ diff --git a/src/Makefile b/src/Makefile index 0ada8639..fd228d7e 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,333 +1,303 @@ -###################### -### bsnes makefile ### -###################### +include lib/nall/Makefile.string -ifeq ($(PLATFORM),) -null_: help +prefix = /usr/local +arch = ARCH_LSB + +################ +### compiler ### +################ + +ifneq ($(findstring gcc,$(compiler)),) # GCC family + flags = -O3 -fomit-frame-pointer -Ilib + c = $(compiler) $(flags) + cpp = $(subst cc,++,$(compiler)) $(flags) + obj = o + rule = -c $< -o $@ + link = + mkbin = -o$1 + mkdef = -D$1 + mklib = -l$1 +else ifeq ($(compiler),cl) # Visual C++ + flags = /nologo /wd4355 /wd4996 /O2 /EHsc /Ilib + c = cl $(flags) + cpp = cl $(flags) + obj = obj + rule = /c $< /Fo$@ + link = /link + mkbin = /Fe$1 + mkdef = /D$1 + mklib = $1.lib +else + unknown_compiler: help; endif -################################## -### platform-specific settings ### -################################## +########## +### os ### +########## -PREFIX = /usr/local - -ifeq ($(PLATFORM),x-gcc-x86) -OS = unix -CC = gcc -CFLAGS = -O3 -fomit-frame-pointer -DPLATFORM_X -DCOMPILER_GCC -DPROCESSOR_X86 -DUI_MIU `pkg-config --cflags gtk+-2.0` -AS = yasm -ASFLAGS = -f elf -LIBS = `pkg-config --libs gtk+-2.0` -lXv -lao -LIBCO = libco.x86 -MIU = miu.gtk -VAI = video.xv.$(OBJ) video.gtk.$(OBJ) audio.ao.$(OBJ) input.x.$(OBJ) +ifeq ($(platform),x) # X11 + ruby = video.glx video.xv video.sdl audio.openal audio.oss audio.ao input.sdl input.x + arch += PLATFORM_X + link += `pkg-config --libs gtk+-2.0` + delete = rm -f $1 +else ifeq ($(platform),win) # Windows + ruby = video.direct3d video.directdraw video.gdi audio.directsound input.directinput + arch += PLATFORM_WIN + link += $(if $(findstring mingw,$(compiler)),-mwindows) + link += $(call mklib,uuid) + link += $(call mklib,kernel32) + link += $(call mklib,user32) + link += $(call mklib,gdi32) + link += $(call mklib,shell32) + link += $(call mklib,winmm) + link += $(call mklib,comdlg32) + link += $(call mklib,comctl32) + delete = $(if $(findstring i586-mingw-gcc,$(compiler)),rm -f $1,del $(subst /,\,$1)) +else + unknown_platform: help; endif -ifeq ($(PLATFORM),x-gcc-x86-64) -OS = unix -CC = gcc -CFLAGS = -O3 -fomit-frame-pointer -DPLATFORM_X -DCOMPILER_GCC -DPROCESSOR_X86_64 -DUI_MIU `pkg-config --cflags gtk+-2.0` -AS = yasm -ASFLAGS = -f elf64 -LIBS = `pkg-config --libs gtk+-2.0` -lXv -lao -LIBCO = libco.x86-64 -MIU = miu.gtk -VAI = video.xv.$(OBJ) video.gtk.$(OBJ) audio.ao.$(OBJ) input.x.$(OBJ) -endif +############ +### ruby ### +############ -ifeq ($(PLATFORM),win-mingw-x86) -OS = win -CC = mingw32-gcc -CFLAGS = -mwindows -O3 -fomit-frame-pointer -DPLATFORM_WIN -DCOMPILER_GCC -DPROCESSOR_X86 -DUI_MIU -AS = nasm -ASFLAGS = -f win32 -DWIN -LIBS = -ld3d9 -lddraw -ldsound -ldinput8 -ldxguid -luuid -lkernel32 -luser32 -lgdi32 -lshell32 -lwinmm -lcomdlg32 -lcomctl32 -LIBCO = libco.x86 -MIU = miu.win -VAI = video.direct3d.$(OBJ) video.directdraw.$(OBJ) video.gdi.$(OBJ) audio.directsound.$(OBJ) input.directinput.$(OBJ) -endif - -ifeq ($(PLATFORM),win-visualc-x86) -OS = win -CC = cl -CFLAGS = /nologo /wd4996 /O2 /EHsc /DPLATFORM_WIN /DCOMPILER_VISUALC /DPROCESSOR_X86 /DUI_MIU -AS = nasm -ASFLAGS = -f win32 -DWIN -LIBS = d3d9.lib ddraw.lib dsound.lib dinput8.lib dxguid.lib kernel32.lib user32.lib gdi32.lib shell32.lib winmm.lib comdlg32.lib comctl32.lib -LIBCO = libco.x86 -MIU = miu.win -VAI = video.direct3d.$(OBJ) video.directdraw.$(OBJ) video.gdi.$(OBJ) audio.directsound.$(OBJ) input.directinput.$(OBJ) -endif - -##################################### -### compiler / assembler switches ### -##################################### - -ifeq ($(CC),gcc) -OUT = -obsnes -CPP = g++ -OBJ = o -CARGS = -c $< -o $@ -DEFINE = -D -endif - -ifeq ($(CC),mingw32-gcc) -OUT = -obsnes -CPP = mingw32-g++ -OBJ = o -CARGS = -c $< -o $@ -DEFINE = -D -endif - -ifeq ($(CC),cl) -OUT = /Febsnes -CPP = cl -OBJ = obj -CARGS = /c $< /Fo$@ -DEFINE = /D -endif - -ifeq ($(AS),nasm) -ASARGS = $< -o $@ -endif - -ifeq ($(AS),yasm) -ASARGS = $< -o $@ -endif - -################### -### OS switches ### -################### - -ifeq ($(OS),unix) -RM = rm -f -endif - -ifeq ($(OS),win) -OUT := $(OUT).exe -RM = del -endif +link += $(if $(findstring video.direct3d,$(ruby)),$(call mklib,d3d9)) +link += $(if $(findstring video.directdraw,$(ruby)),$(call mklib,ddraw)) +link += $(if $(findstring video.glx,$(ruby)),$(call mklib,GL)) +link += $(if $(findstring video.xv,$(ruby)),$(call mklib,Xv)) +link += $(if $(findstring audio.ao,$(ruby)),$(call mklib,ao)) +link += $(if $(findstring audio.directsound,$(ruby)),$(call mklib,dsound)) +link += $(if $(findstring audio.openal,$(ruby)),$(call mklib,openal) $(call mklib,alut)) +link += $(if $(findstring input.directinput,$(ruby)),$(call mklib,dinput8) $(call mklib,dxguid)) +link += $(if $(findstring input.sdl,$(ruby)),`sdl-config --libs`) #################################### ### main target and dependencies ### #################################### -OBJECTS = main.$(OBJ) $(LIBCO).$(OBJ) $(MIU).$(OBJ) $(VAI) bstring.$(OBJ) \ - reader.$(OBJ) cart.$(OBJ) cheat.$(OBJ) memory.$(OBJ) smemory.$(OBJ) \ - cpu.$(OBJ) scpu.$(OBJ) smp.$(OBJ) ssmp.$(OBJ) bdsp.$(OBJ) ppu.$(OBJ) \ - bppu.$(OBJ) snes.$(OBJ) bsx.$(OBJ) superfx.$(OBJ) srtc.$(OBJ) \ - sdd1.$(OBJ) cx4.$(OBJ) dsp1.$(OBJ) dsp2.$(OBJ) dsp3.$(OBJ) dsp4.$(OBJ) \ - obc1.$(OBJ) st010.$(OBJ) +objects = main libco hiro ruby $(ruby) string reader cart cheat \ + memory smemory cpu scpu smp ssmp bdsp ppu bppu snes \ + bsx srtc sdd1 cx4 dsp1 dsp2 dsp3 dsp4 obc1 st010 -ifeq ($(GZIP_SUPPORT),true) - OBJECTS += adler32.$(OBJ) compress.$(OBJ) crc32.$(OBJ) deflate.$(OBJ) \ - gzio.$(OBJ) inffast.$(OBJ) inflate.$(OBJ) inftrees.$(OBJ) ioapi.$(OBJ) \ - trees.$(OBJ) unzip.$(OBJ) zip.$(OBJ) zutil.$(OBJ) - CFLAGS += $(DEFINE)GZIP_SUPPORT +ifeq ($(enable_gzip),true) + objects += adler32 compress crc32 deflate gzio inffast inflate inftrees ioapi trees unzip zip zutil + flags += $(call mkdef,GZIP_SUPPORT) endif -ifeq ($(JMA_SUPPORT),true) - OBJECTS += jma.$(OBJ) jcrc32.$(OBJ) lzmadec.$(OBJ) 7zlzma.$(OBJ) \ - iiostrm.$(OBJ) inbyte.$(OBJ) lzma.$(OBJ) winout.$(OBJ) - CFLAGS += $(DEFINE)JMA_SUPPORT +ifeq ($(enable_jma),true) + objects += jma jcrc32 lzmadec 7zlzma iiostrm inbyte lzma winout + flags += $(call mkdef,JMA_SUPPORT) endif -ifeq ($(OS),win) - ifeq ($(CC),cl) - OBJECTS += bsnes.res - endif - ifeq ($(CC),mingw32-gcc) - OBJECTS += bsnesrc.o +arch := $(patsubst %,$(call mkdef,%),$(arch)) +objects := $(patsubst %,obj/%.$(obj),$(objects)) +rubydef := $(foreach c,$(subst .,_,$(call strupper,$(ruby))),$(call mkdef,$c)) + +# Windows resource file +ifeq ($(platform),win) + ifeq ($(compiler),cl) + objects += obj/bsnes.res + else ifneq ($(findstring gcc,$(compiler)),) + objects += obj/bsnesrc.$(obj) endif endif -all: $(OBJECTS) - $(CPP) $(OUT) $(CFLAGS) $(OBJECTS) $(LIBS) $(LINK) +################ +### implicit ### +################ -###################### -### implicit rules ### -###################### +compile = \ + $(strip \ + $(if $(filter %.c,$<), \ + $(c) $1 $(rule), \ + $(if $(filter %.cpp,$<), \ + $(cpp) $1 $(rule) \ + ) \ + ) \ + ) -%.$(OBJ): $< - $(if $(filter %.asm,$<),$(AS) $(ASFLAGS) $(ASARGS)) - $(if $(filter %.s,$<),$(AS) $(ASFLAGS) $(ASARGS)) - $(if $(filter %.c,$<),$(CC) $(CFLAGS) $(CARGS)) - $(if $(filter %.cpp,$<),$(CPP) $(CFLAGS) $(CARGS)) +%.$(obj): $<; $(call compile) + +all: build; ############ ### main ### ############ -main.$(OBJ): ui/main.cpp config/* \ -ui/* ui/vai/* \ -ui/miu/* ui/miu/loader/* ui/miu/settings/* +obj/main.$(obj): ui/main.cpp config/* lib/nall/* lib/ruby/* ui/* ui/loader/* ui/settings/* + $(call compile,$(arch)) -bsnes.res: ui/bsnes.rc ; rc /r /fobsnes.res ui/bsnes.rc -bsnesrc.o: ui/bsnes.rc ; windres -I data ui/bsnes.rc bsnesrc.o +obj/bsnes.res : ui/bsnes.rc; rc /r /foobj/bsnes.res ui/bsnes.rc +obj/bsnesrc.$(obj): ui/bsnes.rc; windres -I data ui/bsnes.rc obj/bsnesrc.$(obj) -########## -### ui ### -########## +############ +### ruby ### +############ -video.direct3d.$(OBJ) : ui/vai/video/video.direct3d.cpp ui/vai/video/* -video.directdraw.$(OBJ) : ui/vai/video/video.directdraw.cpp ui/vai/video/* -video.gdi.$(OBJ) : ui/vai/video/video.gdi.cpp ui/vai/video/* -video.gtk.$(OBJ) : ui/vai/video/video.gtk.cpp ui/vai/video/* -video.xv.$(OBJ) : ui/vai/video/video.xv.cpp ui/vai/video/* -audio.ao.$(OBJ) : ui/vai/audio/audio.ao.cpp ui/vai/audio/* -audio.directsound.$(OBJ): ui/vai/audio/audio.directsound.cpp ui/vai/audio/* -input.directinput.$(OBJ): ui/vai/input/input.directinput.cpp ui/vai/input/* -input.x.$(OBJ) : ui/vai/input/input.x.cpp ui/vai/input/* +obj/ruby.$(obj) : lib/ruby/ruby.cpp lib/ruby/* + $(call compile,$(rubydef)) +obj/video.direct3d.$(obj) : lib/ruby/video/direct3d.cpp lib/ruby/video/direct3d.* +obj/video.directdraw.$(obj) : lib/ruby/video/directdraw.cpp lib/ruby/video/directdraw.* +obj/video.gdi.$(obj) : lib/ruby/video/gdi.cpp lib/ruby/video/gdi.* +obj/video.glx.$(obj) : lib/ruby/video/glx.cpp lib/ruby/video/glx.* +obj/video.sdl.$(obj) : lib/ruby/video/sdl.cpp lib/ruby/video/sdl.* + $(call compile,`sdl-config --cflags`) +obj/video.xv.$(obj) : lib/ruby/video/xv.cpp lib/ruby/video/xv.* +obj/audio.ao.$(obj) : lib/ruby/audio/ao.cpp lib/ruby/audio/ao.* +obj/audio.directsound.$(obj): lib/ruby/audio/directsound.cpp lib/ruby/audio/directsound.* +obj/audio.openal.$(obj) : lib/ruby/audio/openal.cpp lib/ruby/audio/openal.* +obj/audio.oss.$(obj) : lib/ruby/audio/oss.cpp lib/ruby/audio/oss.* +obj/input.directinput.$(obj): lib/ruby/input/directinput.cpp lib/ruby/input/directinput.* +obj/input.sdl.$(obj) : lib/ruby/input/sdl.cpp lib/ruby/input/sdl.* + $(call compile,`sdl-config --cflags`) +obj/input.x.$(obj) : lib/ruby/input/x.cpp lib/ruby/input/x.* -############# -### libco ### -############# +############ +### hiro ### +############ -libco.x86.$(OBJ) : lib/libco/libco.x86.asm lib/libco/* -libco.x86-64.$(OBJ): lib/libco/libco.x86-64.asm lib/libco/* -libco.pcc.$(OBJ) : lib/libco/libco.ppc.s lib/libco/* -libco.ppc64.$(OBJ) : lib/libco/libco.ppc64.s lib/libco/* - -########### -### miu ### -########### - -miu.gtk.$(OBJ): lib/miu.gtk/miu.gtk.cpp lib/miu.gtk/* -miu.win.$(OBJ): lib/miu.win/miu.win.cpp lib/miu.win/* +obj/hiro.$(obj): lib/hiro.cpp lib/hiro.* lib/hiro_gtk/* lib/hiro_win/* + $(call compile,$(if $(call streq,$(platform),x),`pkg-config --cflags gtk+-2.0`)) ################# ### libraries ### ################# -bstring.$(OBJ): lib/bstring.cpp lib/* +obj/libco.$(obj): lib/libco.c lib/libco.* lib/libco/* +obj/string.$(obj): lib/nall/string.cpp lib/nall/* ################# ### utilities ### ################# -reader.$(OBJ): reader/reader.cpp reader/* -cart.$(OBJ) : cart/cart.cpp cart/* -cheat.$(OBJ) : cheat/cheat.cpp cheat/* +obj/reader.$(obj): reader/reader.cpp reader/* +obj/cart.$(obj) : cart/cart.cpp cart/* +obj/cheat.$(obj) : cheat/cheat.cpp cheat/* ############## ### memory ### ############## -memory.$(OBJ) : memory/memory.cpp memory/* -bmemory.$(OBJ): memory/bmemory/bmemory.cpp memory/bmemory/* memory/bmemory/mapper/* -smemory.$(OBJ): memory/smemory/smemory.cpp memory/smemory/* memory/smemory/mapper/* +obj/memory.$(obj) : memory/memory.cpp memory/* +obj/bmemory.$(obj): memory/bmemory/bmemory.cpp memory/bmemory/* memory/bmemory/mapper/* +obj/smemory.$(obj): memory/smemory/smemory.cpp memory/smemory/* memory/smemory/mapper/* ########### ### cpu ### ########### -cpu.$(OBJ) : cpu/cpu.cpp cpu/* -scpu.$(OBJ): cpu/scpu/scpu.cpp cpu/scpu/* cpu/scpu/core/* cpu/scpu/dma/* cpu/scpu/memory/* cpu/scpu/mmio/* cpu/scpu/timing/* +obj/cpu.$(obj) : cpu/cpu.cpp cpu/* +obj/scpu.$(obj): cpu/scpu/scpu.cpp cpu/scpu/* cpu/scpu/core/* cpu/scpu/dma/* cpu/scpu/memory/* cpu/scpu/mmio/* cpu/scpu/timing/* ########### ### smp ### ########### -smp.$(OBJ) : smp/smp.cpp smp/* -ssmp.$(OBJ): smp/ssmp/ssmp.cpp smp/ssmp/* smp/ssmp/core/* smp/ssmp/memory/* smp/ssmp/timing/* +obj/smp.$(obj) : smp/smp.cpp smp/* +obj/ssmp.$(obj): smp/ssmp/ssmp.cpp smp/ssmp/* smp/ssmp/core/* smp/ssmp/memory/* smp/ssmp/timing/* ########### ### dsp ### ########### -adsp.$(OBJ): dsp/adsp/adsp.cpp dsp/adsp/* -bdsp.$(OBJ): dsp/bdsp/bdsp.cpp dsp/bdsp/* +obj/adsp.$(obj): dsp/adsp/adsp.cpp dsp/adsp/* +obj/bdsp.$(obj): dsp/bdsp/bdsp.cpp dsp/bdsp/* ########### ### ppu ### ########### -ppu.$(OBJ) : ppu/ppu.cpp ppu/* -bppu.$(OBJ): ppu/bppu/bppu.cpp ppu/bppu/* +obj/ppu.$(obj) : ppu/ppu.cpp ppu/* +obj/bppu.$(obj): ppu/bppu/bppu.cpp ppu/bppu/* ############ ### snes ### ############ -snes.$(OBJ): snes/snes.cpp snes/* snes/scheduler/* snes/video/* snes/audio/* snes/input/* +obj/snes.$(obj): snes/snes.cpp snes/* snes/scheduler/* snes/video/* snes/audio/* snes/input/* ##################### ### special chips ### ##################### -bsx.$(OBJ) : chip/bsx/bsx.cpp chip/bsx/* -superfx.$(OBJ): chip/superfx/superfx.cpp chip/superfx/* chip/superfx/core/* chip/superfx/memory/* -srtc.$(OBJ) : chip/srtc/srtc.cpp chip/srtc/* -sdd1.$(OBJ) : chip/sdd1/sdd1.cpp chip/sdd1/* -cx4.$(OBJ) : chip/cx4/cx4.cpp chip/cx4/* -dsp1.$(OBJ) : chip/dsp1/dsp1.cpp chip/dsp1/* -dsp2.$(OBJ) : chip/dsp2/dsp2.cpp chip/dsp2/* -dsp3.$(OBJ) : chip/dsp3/dsp3.cpp chip/dsp3/* -dsp4.$(OBJ) : chip/dsp4/dsp4.cpp chip/dsp4/* -obc1.$(OBJ) : chip/obc1/obc1.cpp chip/obc1/* -st010.$(OBJ) : chip/st010/st010.cpp chip/st010/* +obj/bsx.$(obj) : chip/bsx/bsx.cpp chip/bsx/* +obj/srtc.$(obj) : chip/srtc/srtc.cpp chip/srtc/* +obj/sdd1.$(obj) : chip/sdd1/sdd1.cpp chip/sdd1/* +obj/cx4.$(obj) : chip/cx4/cx4.cpp chip/cx4/* +obj/dsp1.$(obj) : chip/dsp1/dsp1.cpp chip/dsp1/* +obj/dsp2.$(obj) : chip/dsp2/dsp2.cpp chip/dsp2/* +obj/dsp3.$(obj) : chip/dsp3/dsp3.cpp chip/dsp3/* +obj/dsp4.$(obj) : chip/dsp4/dsp4.cpp chip/dsp4/* +obj/obc1.$(obj) : chip/obc1/obc1.cpp chip/obc1/* +obj/st010.$(obj): chip/st010/st010.cpp chip/st010/* ############ ### zlib ### ############ -adler32.$(OBJ) : reader/zlib/adler32.c reader/zlib/* -compress.$(OBJ): reader/zlib/compress.c reader/zlib/* -crc32.$(OBJ) : reader/zlib/crc32.c reader/zlib/* -deflate.$(OBJ) : reader/zlib/deflate.c reader/zlib/* -gzio.$(OBJ) : reader/zlib/gzio.c reader/zlib/* -inffast.$(OBJ) : reader/zlib/inffast.c reader/zlib/* -inflate.$(OBJ) : reader/zlib/inflate.c reader/zlib/* -inftrees.$(OBJ): reader/zlib/inftrees.c reader/zlib/* -ioapi.$(OBJ) : reader/zlib/ioapi.c reader/zlib/* -trees.$(OBJ) : reader/zlib/trees.c reader/zlib/* -unzip.$(OBJ) : reader/zlib/unzip.c reader/zlib/* -zip.$(OBJ) : reader/zlib/zip.c reader/zlib/* -zutil.$(OBJ) : reader/zlib/zutil.c reader/zlib/* +obj/adler32.$(obj) : reader/zlib/adler32.c reader/zlib/* +obj/compress.$(obj): reader/zlib/compress.c reader/zlib/* +obj/crc32.$(obj) : reader/zlib/crc32.c reader/zlib/* +obj/deflate.$(obj) : reader/zlib/deflate.c reader/zlib/* +obj/gzio.$(obj) : reader/zlib/gzio.c reader/zlib/* +obj/inffast.$(obj) : reader/zlib/inffast.c reader/zlib/* +obj/inflate.$(obj) : reader/zlib/inflate.c reader/zlib/* +obj/inftrees.$(obj): reader/zlib/inftrees.c reader/zlib/* +obj/ioapi.$(obj) : reader/zlib/ioapi.c reader/zlib/* +obj/trees.$(obj) : reader/zlib/trees.c reader/zlib/* +obj/unzip.$(obj) : reader/zlib/unzip.c reader/zlib/* +obj/zip.$(obj) : reader/zlib/zip.c reader/zlib/* +obj/zutil.$(obj) : reader/zlib/zutil.c reader/zlib/* ########### ### jma ### ########### -jma.$(OBJ) : reader/jma/jma.cpp reader/jma/* -jcrc32.$(OBJ) : reader/jma/jcrc32.cpp reader/jma/* -lzmadec.$(OBJ): reader/jma/lzmadec.cpp reader/jma/* -7zlzma.$(OBJ) : reader/jma/7zlzma.cpp reader/jma/* -iiostrm.$(OBJ): reader/jma/iiostrm.cpp reader/jma/* -inbyte.$(OBJ) : reader/jma/inbyte.cpp reader/jma/* -lzma.$(OBJ) : reader/jma/lzma.cpp reader/jma/* -winout.$(OBJ) : reader/jma/winout.cpp reader/jma/* +obj/jma.$(obj) : reader/jma/jma.cpp reader/jma/* +obj/jcrc32.$(obj) : reader/jma/jcrc32.cpp reader/jma/* +obj/lzmadec.$(obj): reader/jma/lzmadec.cpp reader/jma/* +obj/7zlzma.$(obj) : reader/jma/7zlzma.cpp reader/jma/* +obj/iiostrm.$(obj): reader/jma/iiostrm.cpp reader/jma/* +obj/inbyte.$(obj) : reader/jma/inbyte.cpp reader/jma/* +obj/lzma.$(obj) : reader/jma/lzma.cpp reader/jma/* +obj/winout.$(obj) : reader/jma/winout.cpp reader/jma/* -#################### -### misc targets ### -#################### +############### +### targets ### +############### + +build: $(objects) + $(strip $(cpp) $(call mkbin,../bsnes) $(objects) $(link)) install: - install -m 775 bsnes $(PREFIX)/bin/bsnes - install -m 775 data/bsnes.png $(PREFIX)/share/icons/bsnes.png + install -m 755 ../bsnes $(prefix)/bin/bsnes + install -m 644 data/bsnes.png $(prefix)/share/icons/bsnes.png clean: - -@$(RM) *.$(OBJ) - -@$(RM) *.res - -@$(RM) *.pgd - -@$(RM) *.pgc - -@$(RM) *.ilk - -@$(RM) *.pdb - -@$(RM) *.manifest + -@$(call delete,obj/*.$(obj)) + -@$(call delete,*.res) + -@$(call delete,*.pgd) + -@$(call delete,*.pgc) + -@$(call delete,*.ilk) + -@$(call delete,*.pdb) + -@$(call delete,*.manifest) help: - @echo "Usage: $(MAKE) PLATFORM=platform [options]" + @echo "Usage: $(MAKE) platform=(os) compiler=(cc) [options]" @echo "" - @echo "Available platform targets:" - @echo " x-gcc-x86 - Linux / BSD (x86) (requires yasm)" - @echo " x-gcc-x86-64 - Linux / BSD (x86-64) (requires yasm)" - @echo " win-mingw-x86 - Windows (x86) (requires nasm)" - @echo " win-visualc-x86 - Windows (x86) (requires nasm)" + @echo "Supported platforms:" + @echo " x - Linux / BSD (x86, x86-64)" + @echo " win - Windows (x86, x86-64)" + @echo "" + @echo "Supported compilers:" + @echo " gcc - GCC compiler" + @echo " mingw32-gcc - MinGW compiler" + @echo " i586-mingw32-gcc - MinGW cross compiler" + @echo " cl - Visual C++" @echo "" @echo "Available options:" - @echo " GZIP_SUPPORT=[true|false] - Enable ZIP / GZ support (default=false)" - @echo " JMA_SUPPORT=[true|false] - Enable JMA support (default=false)" + @echo " enable_gzip=[true|false] - Enable ZIP / GZ support (default=false)" + @echo " enable_jma=[true|false] - Enable JMA support (default=false)" @echo "" - @echo "Example: $(MAKE) PLATFORM=x-gcc-lui GZIP_SUPPORT=true" + @echo "Example: $(MAKE) platform=x compiler=gcc enable_gzip=true" @echo "" diff --git a/src/base.h b/src/base.h index 0d5bf36f..a4d1ada2 100644 --- a/src/base.h +++ b/src/base.h @@ -1,4 +1,4 @@ -#define BSNES_VERSION "0.027" +#define BSNES_VERSION "0.028" #define BSNES_TITLE "bsnes v" BSNES_VERSION #define BUSCORE sBus @@ -17,22 +17,23 @@ //game genie + pro action replay code support (~1-3% speed hit) #define CHEAT_SYSTEM -#if defined(PROCESSOR_X86) || defined(PROCESSOR_X86_64) - #define ARCH_LSB -#elif defined(PROCESSOR_PPC) || defined(PROCESSOR_PPC64) - #define ARCH_MSB -#else //guess - #define ARCH_LSB +#if !defined(ARCH_LSB) && !defined(ARCH_MSB) + #define ARCH_LSB //guess #endif -#include "lib/libco.h" -#include "lib/bbase.h" -#include "lib/bfunction.h" -#include "lib/barray.h" -#include "lib/bvector.h" -#include "lib/bkeymap.h" -#include "lib/bstring.h" -#include "lib/bconfig.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +using namespace nall; + +#include +#include //platform-specific global functions void alert(const char*, ...); diff --git a/src/bsnes.lnk b/src/bsnes.lnk deleted file mode 100644 index 8a244e95f909d2cb883e87a65c16a5afd9c0881c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 587 zcmeZaU|?VrVFHp231%+2unF5P$a4={a7|fMq(2uf;L8yYWOc)Ho>@8+Ob^;7V`S~RvYnd5X z7~bz&X0~wGRI4EaC^lmr@Y2Gz6GOj1gKA*nbowU|K(MUSKuNKX<&F+(0h zDv$)}a$+!I067|@O97%wFSR0-K?|yLtC@t3uoq9n16+q0uAOXZ~Kr92qAWws6 zT_6SlS0EMyVrC%jb57O~0MZOV4}<&@19l*U1Y5|!!=ML*F-Y!%*}}^Z#b5=Lf%z6$ zjRGFI7@!}E7?OcHQy3C~p_GVbdL~dVpCJM0D4+`$M1Wie1WA>prNxPP5Dt*k;Q7a1 l$HC##ZvQDLy-9!HnHM~}JlXFEHd(NEH#9Ub6OsoR1OOVMc{~6B diff --git a/src/cart/cart_file.cpp b/src/cart/cart_file.cpp index ac1158ce..d2ed5499 100644 --- a/src/cart/cart_file.cpp +++ b/src/cart/cart_file.cpp @@ -31,7 +31,7 @@ char* Cartridge::get_save_filename(const char *source, const char *extension) { if(config::path.save != "") { lstring part; split(part, "/", savefn); - string fn = config::path.save(); + string fn = (const char*)config::path.save; if(strend(fn, "/") == false) strcat(fn, "/"); strcat(fn, part[count(part) - 1]); strcpy(savefn, fn); diff --git a/src/cart/cart_st.cpp b/src/cart/cart_st.cpp index 579d0541..4eac85ed 100644 --- a/src/cart/cart_st.cpp +++ b/src/cart/cart_st.cpp @@ -28,7 +28,7 @@ uint size; memset(stA.ram, 0xff, stA.ram_size); if(load_file(get_save_filename(stA.fn, "srm"), data, size) == true) { - memcpy(stA.ram, data, min(size, 0x020000)); + memcpy(stA.ram, data, min(size, 0x020000U)); safe_free(data); } } @@ -44,7 +44,7 @@ uint size; memset(stB.ram, 0xff, stB.ram_size); if(load_file(get_save_filename(stB.fn, "srm"), data, size) == true) { - memcpy(stB.ram, data, min(size, 0x020000)); + memcpy(stB.ram, data, min(size, 0x020000U)); safe_free(data); } } diff --git a/src/cc.bat b/src/cc.bat index 19a5664a..2efde1c3 100644 --- a/src/cc.bat +++ b/src/cc.bat @@ -1,6 +1,3 @@ -@make -r PLATFORM=win-mingw-x86 -::@make -r PLATFORM=win-mingw-x86 GZIP_SUPPORT=true JMA_SUPPORT=true -::@make -r PLATFORM=win-visualc-x86 -::@make -r PLATFORM=win-visualc-x86 GZIP_SUPPORT=true JMA_SUPPORT=true -@move bsnes.exe ../bsnes.exe>nul -@pause \ No newline at end of file +@make platform=win compiler=mingw32-gcc +::@make platform=win compiler=mingw32-gcc enable_gzip=true enable_jma=true +@pause diff --git a/src/cc.sh b/src/cc.sh index 02258c8d..51da6a6b 100644 --- a/src/cc.sh +++ b/src/cc.sh @@ -1 +1,2 @@ -make PLATFORM=x-gcc-x86 +make platform=x compiler=gcc +#make platform=x compiler=gcc enable_gzip=true enable_jma=true diff --git a/src/cheat/cheat.cpp b/src/cheat/cheat.cpp index a177b38e..73aa96f4 100644 --- a/src/cheat/cheat.cpp +++ b/src/cheat/cheat.cpp @@ -16,7 +16,7 @@ string t, part; if(strlen(t) == 8 || (strlen(t) == 9 && t()[6] == ':')) { type = CT_PRO_ACTION_REPLAY; replace(t, ":", ""); - uint32 r = strhex(t); + uint32 r = strhex((const char*)t); addr = r >> 8; data = r & 0xff; return true; @@ -24,7 +24,7 @@ string t, part; type = CT_GAME_GENIE; replace(t, "-", ""); strtr(t, "df4709156bc8a23e", "0123456789abcdef"); - uint32 r = strhex(t); + uint32 r = strhex((const char*)t); //8421 8421 8421 8421 8421 8421 //abcd efgh ijkl mnop qrst uvwx //ijkl qrst opab cduv wxef ghmn diff --git a/src/cheat/cheat.h b/src/cheat/cheat.h index 51386f57..58041537 100644 --- a/src/cheat/cheat.h +++ b/src/cheat/cheat.h @@ -2,18 +2,22 @@ class Cheat { public: -enum { CT_PRO_ACTION_REPLAY, CT_GAME_GENIE }; + enum { + CT_PRO_ACTION_REPLAY, + CT_GAME_GENIE + }; -struct CheatIndex { - bool enabled; - uint32 addr; - uint8 data; - char code[ 16 + 1]; - char desc[128 + 1]; -} index[CHEAT_LIMIT + 1]; -bool cheat_enabled; -uint32 cheat_count; -uint8 mask[0x200000]; + struct CheatIndex { + bool enabled; + uint32 addr; + uint8 data; + char code[ 16 + 1]; + char desc[128 + 1]; + } index[CHEAT_LIMIT + 1]; + + bool cheat_enabled; + uint32 cheat_count; + uint8 mask[0x200000]; inline bool enabled() { return cheat_enabled; } inline uint count() { return cheat_count; } @@ -22,12 +26,6 @@ uint8 mask[0x200000]; bool decode(char *str, uint32 &addr, uint8 &data, uint8 &type); bool encode(char *str, uint32 addr, uint8 data, uint8 type); -private: - uint mirror_address(uint addr); - void set(uint32 addr); - void clear(uint32 addr); -public: - bool read(uint32 addr, uint8 &data); void update_cheat_status(); @@ -42,7 +40,12 @@ public: bool save(const char *fn); void clear(); - Cheat(); + Cheat(); + +private: + uint mirror_address(uint addr); + void set(uint32 addr); + void clear(uint32 addr); }; extern Cheat cheat; diff --git a/src/chip/chip.h b/src/chip/chip.h index 67bf003d..f28ce348 100644 --- a/src/chip/chip.h +++ b/src/chip/chip.h @@ -1,5 +1,4 @@ #include "bsx/bsx.h" -#include "superfx/superfx.h" #include "srtc/srtc.h" #include "sdd1/sdd1.h" #include "cx4/cx4.h" diff --git a/src/chip/superfx/core/core.h b/src/chip/superfx/core/core.h deleted file mode 100644 index c3588bac..00000000 --- a/src/chip/superfx/core/core.h +++ /dev/null @@ -1,3 +0,0 @@ -void op_unknown() {} - -void op_00(); diff --git a/src/chip/superfx/core/op0x.cpp b/src/chip/superfx/core/op0x.cpp deleted file mode 100644 index 1ffaacc9..00000000 --- a/src/chip/superfx/core/op0x.cpp +++ /dev/null @@ -1,7 +0,0 @@ -//STOP -void SuperFX::op_00() { - regs.sfr.g = 0; - regs.sfr.b = 0; - regs.sfr.alt1 = 0; - regs.sfr.alt2 = 0; -} diff --git a/src/chip/superfx/memory/read.cpp b/src/chip/superfx/memory/read.cpp deleted file mode 100644 index 0f7fba1f..00000000 --- a/src/chip/superfx/memory/read.cpp +++ /dev/null @@ -1,66 +0,0 @@ -uint8 SuperFX::mmio_read(uint addr) { - addr &= 0xffff; - - switch(addr) { - case 0x3000: return regs.r0.l; - case 0x3001: return regs.r0.h; - case 0x3002: return regs.r1.l; - case 0x3003: return regs.r1.h; - case 0x3004: return regs.r2.l; - case 0x3005: return regs.r2.h; - case 0x3006: return regs.r3.l; - case 0x3007: return regs.r3.h; - case 0x3008: return regs.r4.l; - case 0x3009: return regs.r4.h; - case 0x300a: return regs.r5.l; - case 0x300b: return regs.r5.h; - case 0x300c: return regs.r6.l; - case 0x300d: return regs.r6.h; - case 0x300e: return regs.r7.l; - case 0x300f: return regs.r7.h; - - case 0x3010: return regs.r8.l; - case 0x3011: return regs.r8.h; - case 0x3012: return regs.r9.l; - case 0x3013: return regs.r9.h; - case 0x3014: return regs.r10.l; - case 0x3015: return regs.r10.h; - case 0x3016: return regs.r11.l; - case 0x3017: return regs.r11.h; - case 0x3018: return regs.r12.l; - case 0x3019: return regs.r12.h; - case 0x301a: return regs.r13.l; - case 0x301b: return regs.r13.h; - case 0x301c: return regs.r14.l; - case 0x301d: return regs.r14.h; - case 0x301e: return regs.r15.l; - case 0x301f: return regs.r15.h; - -//0x3020 - 0x302f unused - - case 0x3030: return regs.sfr; - case 0x3031: return regs.sfr >> 8; - case 0x3032: return 0x00; //unused - case 0x3033: return 0x00; //BRAMR (write only) - case 0x3034: return regs.pbr; - case 0x3035: return 0x00; //unused - case 0x3036: return regs.rombr; - case 0x3037: return 0x00; //CFGR (write only) - case 0x3038: return 0x00; //SCBR (write only) - case 0x3039: return 0x00; //CLSR (write only) - case 0x303a: return 0x00; //SCMR (write only) - case 0x303b: return regs.vcr; - case 0x303c: return regs.rambr; - case 0x303d: return 0x00; //unused - case 0x303e: return regs.cbr; - case 0x303f: return regs.cbr >> 8; - -//0x3040 - 0x30ff unused - } - - if(addr >= 0x3100 && addr <= 0x32ff) { - return cache[addr - 0x3100]; - } - - return 0x00; -} diff --git a/src/chip/superfx/memory/write.cpp b/src/chip/superfx/memory/write.cpp deleted file mode 100644 index b453b999..00000000 --- a/src/chip/superfx/memory/write.cpp +++ /dev/null @@ -1,65 +0,0 @@ -void SuperFX::mmio_write(uint addr, uint8 data) { - addr &= 0xffff; - - switch(addr) { - case 0x3000: regs.r0.l = data; return; - case 0x3001: regs.r0.h = data; return; - case 0x3002: regs.r1.l = data; return; - case 0x3003: regs.r1.h = data; return; - case 0x3004: regs.r2.l = data; return; - case 0x3005: regs.r2.h = data; return; - case 0x3006: regs.r3.l = data; return; - case 0x3007: regs.r3.h = data; return; - case 0x3008: regs.r4.l = data; return; - case 0x3009: regs.r4.h = data; return; - case 0x300a: regs.r5.l = data; return; - case 0x300b: regs.r5.h = data; return; - case 0x300c: regs.r6.l = data; return; - case 0x300d: regs.r6.h = data; return; - case 0x300e: regs.r7.l = data; return; - case 0x300f: regs.r7.h = data; return; - - case 0x3010: regs.r8.l = data; return; - case 0x3011: regs.r8.h = data; return; - case 0x3012: regs.r9.l = data; return; - case 0x3013: regs.r9.h = data; return; - case 0x3014: regs.r10.l = data; return; - case 0x3015: regs.r10.h = data; return; - case 0x3016: regs.r11.l = data; return; - case 0x3017: regs.r11.h = data; return; - case 0x3018: regs.r12.l = data; return; - case 0x3019: regs.r12.h = data; return; - case 0x301a: regs.r13.l = data; return; - case 0x301b: regs.r13.h = data; return; - case 0x301c: regs.r14.l = data; return; - case 0x301d: regs.r14.h = data; return; - case 0x301e: regs.r15.l = data; return; - case 0x301f: regs.r15.h = data; return; - -//0x3020 - 0x302f unused - - case 0x3030: regs.sfr.l = data & 0x7e; return; //mask invalid bits - case 0x3031: regs.sfr.h = data & 0x9f; return; //mask invalid bits - case 0x3032: return; //unused - case 0x3033: regs.bramr = data; return; - case 0x3034: regs.pbr = data; return; - case 0x3035: return; //unused - case 0x3036: return; //ROMBR (read only) - case 0x3037: regs.cfgr = data; return; - case 0x3038: regs.scbr = data; return; - case 0x3039: regs.clsr = data; return; - case 0x303a: regs.scmr = data; return; - case 0x303b: return; //VCR (read only) - case 0x303c: return; //RAMBR (read only) - case 0x303d: return; //unused - case 0x303e: return; //CBR low (read only) - case 0x303f: return; //CBR high (read only) - -//0x3040 - 0x30ff unused - } - - if(addr >= 0x3100 && addr <= 0x32ff) { - cache[addr - 0x3100] = data; - return; - } -} diff --git a/src/chip/superfx/regs.h b/src/chip/superfx/regs.h deleted file mode 100644 index 30014a5b..00000000 --- a/src/chip/superfx/regs.h +++ /dev/null @@ -1,174 +0,0 @@ -struct Reg16 { - union { - uint16 w; - struct { uint8 order_lsb2(l, h); }; - }; - - inline operator unsigned() const { return w; } - inline unsigned operator=(const unsigned i) { return w = i; } - - Reg16() : w(0) {} -}; - -template struct RegFlag8 { - uint8 data; - - inline operator bool() const { return data & bit; } - inline bool operator=(const bool i) { i ? data |= bit : data &= ~bit; return i; } -}; - -template struct RegFlag16 { - uint16 data; - - inline operator bool() const { return data & bit; } - inline bool operator=(const bool i) { i ? data |= bit : data &= ~bit; return i; } -}; - -struct SFR { - union { - uint16 w; - struct { uint8 order_lsb2(l, h); }; - RegFlag16<0x0002> z; //zero flag - RegFlag16<0x0004> c; //carry flag - RegFlag16<0x0008> s; //sign flag - RegFlag16<0x0010> v; //overflow flag - RegFlag16<0x0020> g; //go flag - RegFlag16<0x0040> r; //ROM read using r14 flag - RegFlag16<0x0100> alt1; //alternate instruction 1 flag - RegFlag16<0x0200> alt2; //alternate instruction 2 flag - RegFlag16<0x0400> il; //immediate lower 8-bit flag - RegFlag16<0x0800> ih; //immediate upper 8-bit flag - RegFlag16<0x1000> b; //WITH instruction flag - RegFlag16<0x8000> irq; //interrupt flag - }; - - inline operator unsigned() const { return w & 0x9f7e; } //invalid flag bits always return 0 when read - inline unsigned operator=(const unsigned i) { return w = i & 0x9f7e; } - - SFR() : w(0) {} -}; - -struct RAMBR { - union { - uint8 b; - RegFlag8<0x01> bank; - }; - - inline operator unsigned() const { return b & 0x01; } - inline unsigned operator=(const unsigned i) { return b = i & 0x01; } - - RAMBR() : b(0) {} -}; - -struct CBR { - uint16 w; - - inline operator unsigned() const { return w & 0xfff0; } - inline unsigned operator=(const unsigned i) { return w = i & 0xfff0; } - - CBR() : w(0) {} -}; - -struct SCMR { - union { - uint8 b; - RegFlag8<0x01> md0; //color mode low - RegFlag8<0x02> md1; //color mode high - RegFlag8<0x04> ht0; //height low - RegFlag8<0x08> ran; //ram enable - RegFlag8<0x10> ron; //rom enable - RegFlag8<0x20> ht1; //height high - }; - - inline operator unsigned() const { return b; } - inline unsigned operator=(const unsigned i) { return b = i; } - - SCMR() : b(0) {} -}; - -struct BRAMR { - union { - uint8 b; - RegFlag8<0x01> flag; - }; - - inline operator unsigned() const { return b; } - inline unsigned operator=(const unsigned i) { return b = i; } - - BRAMR() : b(0) {} -}; - -struct CFGR { - union { - uint8 b; - RegFlag8<0x20> ms0; //multiplier speed selection - RegFlag8<0x80> irq; //irq mask flag - }; - - inline operator unsigned() const { return b; } - inline unsigned operator=(const unsigned i) { return b = i; } - - CFGR() : b(0) {} -}; - -struct CLSR { - union { - uint8 b; - RegFlag8<0x01> flag; - }; - - inline operator unsigned() const { return b; } - inline unsigned operator=(const unsigned i) { return b = i; } - - CLSR() : b(0) {} -}; - -struct POR { - union { - uint8 b; - RegFlag8<0x01> transparent; //transparent flag - RegFlag8<0x02> dither; //dither flag - RegFlag8<0x04> highnibble; //high nibble flag - RegFlag8<0x08> freezehigh; //freeze high flag - RegFlag8<0x10> obj; //OBJ flag - }; - - inline operator unsigned() const { return b; } - inline unsigned operator=(const unsigned i) { return b = i; } - - POR() : b(0) {} -}; - -struct Regs { - Reg16 r0; //default source/destination register - Reg16 r1; //pixel plot X position register - Reg16 r2; //pixel plot Y position register - Reg16 r3; - Reg16 r4; //lower 16-bit result of lmult - Reg16 r5; - Reg16 r6; //multiplier for fmult and lmult - Reg16 r7; //fixed point texel X position for merge - Reg16 r8; //fixed point texel Y position for merge - Reg16 r9; - Reg16 r10; - Reg16 r11; //return address set by link - Reg16 r12; //loop counter - Reg16 r13; //loop point address - Reg16 r14; //rom address for getb, getbh, getbl, getbs - Reg16 r15; //program counter - - SFR sfr; //status/flag register - uint8 pbr; //program bank register - uint8 rombr; //rom bank register - RAMBR rambr; //ram bank register - CBR cbr; //cache base register - uint8 scbr; //screen base register - SCMR scmr; //screen mode register - BRAMR bramr; //backup ram register - uint8 vcr; //version code register - CFGR cfgr; //config register - CLSR clsr; //clock select register - - uint8 colr; //color register - POR por; //plot option register -} regs; diff --git a/src/chip/superfx/superfx.cpp b/src/chip/superfx/superfx.cpp deleted file mode 100644 index 3cb27b95..00000000 --- a/src/chip/superfx/superfx.cpp +++ /dev/null @@ -1,42 +0,0 @@ -#include "../../base.h" - -#include "core/op0x.cpp" - -#include "memory/read.cpp" -#include "memory/write.cpp" - -void SuperFX::init() { -} - -void SuperFX::enable() { - for(uint i = 0x3000; i <= 0x32ff; i++) { - memory::mmio.map(i, *this); - } -} - -void SuperFX::power() { - reset(); -} - -void SuperFX::reset() { - regs.r0 = 0; - regs.r1 = 0; - regs.r2 = 0; - regs.r3 = 0; - regs.r4 = 0; - regs.r5 = 0; - regs.r6 = 0; - regs.r7 = 0; - regs.r8 = 0; - regs.r9 = 0; - regs.r10 = 0; - regs.r11 = 0; - regs.r12 = 0; - regs.r13 = 0; - regs.r14 = 0; - regs.r15 = 0; - - regs.sfr = 0; - - memset(cache, 0, sizeof cache); -} diff --git a/src/chip/superfx/superfx.h b/src/chip/superfx/superfx.h deleted file mode 100644 index d8b0b8df..00000000 --- a/src/chip/superfx/superfx.h +++ /dev/null @@ -1,17 +0,0 @@ -class SuperFX : public MMIO { public: - #include "core/core.h" - - void init(); - void enable(); - void power(); - void reset(); - - uint8 mmio_read (uint addr); - void mmio_write(uint addr, uint8 data); - -private: - #include "regs.h" - uint8 cache[512]; //cache RAM -}; - -extern SuperFX superfx; diff --git a/src/clean.bat b/src/clean.bat index 80cc34cc..3a500869 100644 --- a/src/clean.bat +++ b/src/clean.bat @@ -1,2 +1 @@ -@make PLATFORM=win-mingw-x86 clean -::@make PLATFORM=win-visualc-x86 clean +@make platform=win compiler=mingw32-gcc clean diff --git a/src/clean.sh b/src/clean.sh index 0709a319..fddeab62 100644 --- a/src/clean.sh +++ b/src/clean.sh @@ -1 +1 @@ -make PLATFORM=x-gcc-x86 clean +make platform=x compiler=gcc clean diff --git a/src/config/config.cpp b/src/config/config.cpp index dea6cd8b..a48a8445 100644 --- a/src/config/config.cpp +++ b/src/config/config.cpp @@ -1,7 +1,7 @@ namespace config { -Config& config() { -static Config config; +configuration& config() { +static configuration config; return config; } @@ -28,48 +28,45 @@ lstring part; return path; } -StringSetting Path::base(0, "path.base", +string_setting Path::base("path.base", "Path that bsnes resides in", ""); -StringSetting Path::rom(&config(), "path.rom", +string_setting Path::rom(config(), "path.rom", "Default path to look for ROM files in (\"\" = use default directory)", ""); -StringSetting Path::save(&config(), "path.save", +string_setting Path::save(config(), "path.save", "Default path for all save RAM and cheat files (\"\" = use current directory)", ""); -StringSetting Path::bsx(&config(), "path.bsx", "", ""); -StringSetting Path::st(&config(), "path.st", "", ""); +string_setting Path::bsx(config(), "path.bsx", "", ""); +string_setting Path::st(config(), "path.st", "", ""); -IntegerSetting SNES::gamma_ramp(&config(), "snes.colorfilter.gamma_ramp", - "Use precalculated TV-style gamma ramp", IntegerSetting::Boolean, true); -IntegerSetting SNES::sepia(&config(), "snes.colorfilter.sepia", - "Convert color to sepia tone", IntegerSetting::Boolean, false); -IntegerSetting SNES::grayscale(&config(), "snes.colorfilter.grayscale", - "Convert color to grayscale tone", IntegerSetting::Boolean, false); -IntegerSetting SNES::invert(&config(), "snes.colorfilter.invert", - "Invert output image colors", IntegerSetting::Boolean, false); -IntegerSetting SNES::contrast(&config(), "snes.colorfilter.contrast", - "Contrast", IntegerSetting::Decimal, 0); -IntegerSetting SNES::brightness(&config(), "snes.colorfilter.brightness", - "Brightness", IntegerSetting::Decimal, 0); -IntegerSetting SNES::gamma(&config(), "snes.colorfilter.gamma", - "Gamma", IntegerSetting::Decimal, 80); +integral_setting SNES::gamma_ramp(config(), "snes.colorfilter.gamma_ramp", + "Use precalculated TV-style gamma ramp", integral_setting::boolean, true); +integral_setting SNES::sepia(config(), "snes.colorfilter.sepia", + "Convert color to sepia tone", integral_setting::boolean, false); +integral_setting SNES::grayscale(config(), "snes.colorfilter.grayscale", + "Convert color to grayscale tone", integral_setting::boolean, false); +integral_setting SNES::invert(config(), "snes.colorfilter.invert", + "Invert output image colors", integral_setting::boolean, false); +integral_setting SNES::contrast(config(), "snes.colorfilter.contrast", + "Contrast", integral_setting::decimal, 0); +integral_setting SNES::brightness(config(), "snes.colorfilter.brightness", + "Brightness", integral_setting::decimal, 0); +integral_setting SNES::gamma(config(), "snes.colorfilter.gamma", + "Gamma", integral_setting::decimal, 80); -IntegerSetting SNES::ntsc_merge_fields(&config(), "snes.ntsc_merge_fields", +integral_setting SNES::ntsc_merge_fields(config(), "snes.ntsc_merge_fields", "Merge fields in NTSC video filter\n" "Set to true if using filter at any refresh rate other than 60hz\n" - "", IntegerSetting::Boolean, true); + "", integral_setting::boolean, true); -IntegerSetting SNES::mute(&config(), "snes.mute", "Mutes SNES audio output when enabled", - IntegerSetting::Boolean, false); +integral_setting SNES::controller_port0(config(), "snes.controller_port_1", + "Controller attached to SNES port 1", integral_setting::decimal, ::SNES::DEVICEID_JOYPAD1); +integral_setting SNES::controller_port1(config(), "snes.controller_port_2", + "Controller attached to SNES port 2", integral_setting::decimal, ::SNES::DEVICEID_JOYPAD2); -IntegerSetting SNES::controller_port0(&config(), "snes.controller_port_1", - "Controller attached to SNES port 1", IntegerSetting::Decimal, ::SNES::DEVICEID_JOYPAD1); -IntegerSetting SNES::controller_port1(&config(), "snes.controller_port_2", - "Controller attached to SNES port 2", IntegerSetting::Decimal, ::SNES::DEVICEID_JOYPAD2); - -IntegerSetting CPU::ntsc_clock_rate(&config(), "cpu.ntsc_clock_rate", - "NTSC S-CPU clock rate (in hz)", IntegerSetting::Decimal, 21477272); -IntegerSetting CPU::pal_clock_rate(&config(), "cpu.pal_clock_rate", - "PAL S-CPU clock rate (in hz)", IntegerSetting::Decimal, 21281370); -IntegerSetting CPU::wram_init_value(&config(), "cpu.wram_init_value", +integral_setting CPU::ntsc_clock_rate(config(), "cpu.ntsc_clock_rate", + "NTSC S-CPU clock rate (in hz)", integral_setting::decimal, 21477272); +integral_setting CPU::pal_clock_rate(config(), "cpu.pal_clock_rate", + "PAL S-CPU clock rate (in hz)", integral_setting::decimal, 21281370); +integral_setting CPU::wram_init_value(config(), "cpu.wram_init_value", "Value to initialize 128k WRAM to upon power cycle.\n" "Note that on real hardware, this value is undefined; meaning it can vary\n" "per power-on, and per SNES unit. Such randomness is undesirable for an\n" @@ -81,52 +78,52 @@ IntegerSetting CPU::wram_init_value(&config(), "cpu.wram_init_value", "which executed on these copiers. Using 0x00 will therefore fix many homebrew\n" "programs, but *will* break some poorly programmed commercial software titles,\n" "which do not properly initialize WRAM upon power cycle.\n", - IntegerSetting::Hex, 0x55); + integral_setting::hex, 0x55); -IntegerSetting CPU::hdma_enable(0, "cpu.hdma_enable", - "Enable HDMA effects", IntegerSetting::Boolean, true); +integral_setting CPU::hdma_enable("cpu.hdma_enable", + "Enable HDMA effects", integral_setting::boolean, true); -IntegerSetting SMP::ntsc_clock_rate(&config(), "smp.ntsc_clock_rate", - "NTSC S-SMP clock rate (in hz)", IntegerSetting::Decimal, 24606720); -IntegerSetting SMP::pal_clock_rate(&config(), "smp.pal_clock_rate", - "PAL S-SMP clock rate (in hz)", IntegerSetting::Decimal, 24606720); +integral_setting SMP::ntsc_clock_rate(config(), "smp.ntsc_clock_rate", + "NTSC S-SMP clock rate (in hz)", integral_setting::decimal, 24606720); +integral_setting SMP::pal_clock_rate(config(), "smp.pal_clock_rate", + "PAL S-SMP clock rate (in hz)", integral_setting::decimal, 24606720); -IntegerSetting PPU::Hack::render_scanline_position(&config(), "ppu.hack.render_scanline_position", +integral_setting PPU::Hack::render_scanline_position(config(), "ppu.hack.render_scanline_position", "Approximate HCLOCK position to render at for scanline-based renderers", - IntegerSetting::Decimal, 512); -IntegerSetting PPU::Hack::obj_cache(&config(), "ppu.hack.obj_cache", + integral_setting::decimal, 512); +integral_setting PPU::Hack::obj_cache(config(), "ppu.hack.obj_cache", "Cache OAM OBJ attributes one scanline before rendering\n" "This is technically closer to the actual operation of the SNES,\n" "but can cause problems in some games if enabled", - IntegerSetting::Boolean, false); -IntegerSetting PPU::Hack::oam_address_invalidation(&config(), "ppu.hack.oam_address_invalidation", + integral_setting::boolean, false); +integral_setting PPU::Hack::oam_address_invalidation(config(), "ppu.hack.oam_address_invalidation", "OAM access address changes during active display, as the S-PPU reads\n" "data to render the display. Thusly, the address retrieved when accessing\n" "OAM during active display is unpredictable. Unfortunately, the exact\n" "algorithm for this is completely unknown at this time. It is more hardware\n" "accurate to enable this setting, but one must *not* rely on the actual\n" "address to match hardware under emulation.", - IntegerSetting::Boolean, true); -IntegerSetting PPU::Hack::cgram_address_invalidation(&config(), "ppu.hack.cgram_address_invalidation", + integral_setting::boolean, true); +integral_setting PPU::Hack::cgram_address_invalidation(config(), "ppu.hack.cgram_address_invalidation", "CGRAM access address changes during active display (excluding hblank), as\n" "the S-PPU reads data to render the display. Thusly, as with OAM, the access\n" "address is unpredictable. Again, enabling this setting is more hardware\n" "accurate, but one must *not* rely on the actual address to match hardware\n" "under emulation.", - IntegerSetting::Boolean, true); + integral_setting::boolean, true); -IntegerSetting PPU::opt_enable(0, "ppu.opt_enable", "Enable offset-per-tile effects", IntegerSetting::Boolean, true); -IntegerSetting PPU::bg1_pri0_enable(0, "ppu.bg1_pri0_enable", "Enable BG1 Priority 0", IntegerSetting::Boolean, true); -IntegerSetting PPU::bg1_pri1_enable(0, "ppu.bg1_pri1_enable", "Enable BG1 Priority 1", IntegerSetting::Boolean, true); -IntegerSetting PPU::bg2_pri0_enable(0, "ppu.bg2_pri0_enable", "Enable BG2 Priority 0", IntegerSetting::Boolean, true); -IntegerSetting PPU::bg2_pri1_enable(0, "ppu.bg2_pri1_enable", "Enable BG2 Priority 1", IntegerSetting::Boolean, true); -IntegerSetting PPU::bg3_pri0_enable(0, "ppu.bg3_pri0_enable", "Enable BG3 Priority 0", IntegerSetting::Boolean, true); -IntegerSetting PPU::bg3_pri1_enable(0, "ppu.bg3_pri1_enable", "Enable BG3 Priority 1", IntegerSetting::Boolean, true); -IntegerSetting PPU::bg4_pri0_enable(0, "ppu.bg4_pri0_enable", "Enable BG4 Priority 0", IntegerSetting::Boolean, true); -IntegerSetting PPU::bg4_pri1_enable(0, "ppu.bg4_pri1_enable", "Enable BG4 Priority 1", IntegerSetting::Boolean, true); -IntegerSetting PPU::oam_pri0_enable(0, "ppu.oam_pri0_enable", "Enable OAM Priority 0", IntegerSetting::Boolean, true); -IntegerSetting PPU::oam_pri1_enable(0, "ppu.oam_pri1_enable", "Enable OAM Priority 1", IntegerSetting::Boolean, true); -IntegerSetting PPU::oam_pri2_enable(0, "ppu.oam_pri2_enable", "Enable OAM Priority 2", IntegerSetting::Boolean, true); -IntegerSetting PPU::oam_pri3_enable(0, "ppu.oam_pri3_enable", "Enable OAM Priority 3", IntegerSetting::Boolean, true); +integral_setting PPU::opt_enable("ppu.opt_enable", "Enable offset-per-tile effects", integral_setting::boolean, true); +integral_setting PPU::bg1_pri0_enable("ppu.bg1_pri0_enable", "Enable BG1 Priority 0", integral_setting::boolean, true); +integral_setting PPU::bg1_pri1_enable("ppu.bg1_pri1_enable", "Enable BG1 Priority 1", integral_setting::boolean, true); +integral_setting PPU::bg2_pri0_enable("ppu.bg2_pri0_enable", "Enable BG2 Priority 0", integral_setting::boolean, true); +integral_setting PPU::bg2_pri1_enable("ppu.bg2_pri1_enable", "Enable BG2 Priority 1", integral_setting::boolean, true); +integral_setting PPU::bg3_pri0_enable("ppu.bg3_pri0_enable", "Enable BG3 Priority 0", integral_setting::boolean, true); +integral_setting PPU::bg3_pri1_enable("ppu.bg3_pri1_enable", "Enable BG3 Priority 1", integral_setting::boolean, true); +integral_setting PPU::bg4_pri0_enable("ppu.bg4_pri0_enable", "Enable BG4 Priority 0", integral_setting::boolean, true); +integral_setting PPU::bg4_pri1_enable("ppu.bg4_pri1_enable", "Enable BG4 Priority 1", integral_setting::boolean, true); +integral_setting PPU::oam_pri0_enable("ppu.oam_pri0_enable", "Enable OAM Priority 0", integral_setting::boolean, true); +integral_setting PPU::oam_pri1_enable("ppu.oam_pri1_enable", "Enable OAM Priority 1", integral_setting::boolean, true); +integral_setting PPU::oam_pri2_enable("ppu.oam_pri2_enable", "Enable OAM Priority 2", integral_setting::boolean, true); +integral_setting PPU::oam_pri3_enable("ppu.oam_pri3_enable", "Enable OAM Priority 3", integral_setting::boolean, true); }; diff --git a/src/config/config.h b/src/config/config.h index 4a5b318c..7e44de36 100644 --- a/src/config/config.h +++ b/src/config/config.h @@ -1,47 +1,46 @@ namespace config { -extern Config& config(); +extern configuration& config(); string file_updatepath(const char *, const char *); extern struct Path { - static StringSetting base, rom, save; - static StringSetting bsx, st; + static string_setting base, rom, save; + static string_setting bsx, st; } path; extern struct SNES { - static IntegerSetting gamma_ramp, sepia, grayscale, invert, contrast, brightness, gamma; - static IntegerSetting ntsc_merge_fields; - static IntegerSetting mute; - static IntegerSetting controller_port0; - static IntegerSetting controller_port1; + static integral_setting gamma_ramp, sepia, grayscale, invert, contrast, brightness, gamma; + static integral_setting ntsc_merge_fields; + static integral_setting controller_port0; + static integral_setting controller_port1; } snes; extern struct CPU { - static IntegerSetting ntsc_clock_rate, pal_clock_rate; - static IntegerSetting wram_init_value; - static IntegerSetting hdma_enable; + static integral_setting ntsc_clock_rate, pal_clock_rate; + static integral_setting wram_init_value; + static integral_setting hdma_enable; } cpu; extern struct SMP { - static IntegerSetting ntsc_clock_rate, pal_clock_rate; + static integral_setting ntsc_clock_rate, pal_clock_rate; } smp; extern struct PPU { struct Hack { - static IntegerSetting render_scanline_position; - static IntegerSetting obj_cache; - static IntegerSetting oam_address_invalidation; - static IntegerSetting cgram_address_invalidation; + static integral_setting render_scanline_position; + static integral_setting obj_cache; + static integral_setting oam_address_invalidation; + static integral_setting cgram_address_invalidation; } hack; - static IntegerSetting opt_enable; - static IntegerSetting bg1_pri0_enable, bg1_pri1_enable; - static IntegerSetting bg2_pri0_enable, bg2_pri1_enable; - static IntegerSetting bg3_pri0_enable, bg3_pri1_enable; - static IntegerSetting bg4_pri0_enable, bg4_pri1_enable; - static IntegerSetting oam_pri0_enable, oam_pri1_enable; - static IntegerSetting oam_pri2_enable, oam_pri3_enable; + static integral_setting opt_enable; + static integral_setting bg1_pri0_enable, bg1_pri1_enable; + static integral_setting bg2_pri0_enable, bg2_pri1_enable; + static integral_setting bg3_pri0_enable, bg3_pri1_enable; + static integral_setting bg4_pri0_enable, bg4_pri1_enable; + static integral_setting oam_pri0_enable, oam_pri1_enable; + static integral_setting oam_pri2_enable, oam_pri3_enable; } ppu; }; diff --git a/src/cpu/scpu/timing/timing.cpp b/src/cpu/scpu/timing/timing.cpp index 606fca68..3be22721 100644 --- a/src/cpu/scpu/timing/timing.cpp +++ b/src/cpu/scpu/timing/timing.cpp @@ -250,7 +250,7 @@ void sCPU::timing_reset() { status.prev_line_clocks = 1364; status.line_rendered = false; - status.line_render_position = min(1112, (uint16)config::ppu.hack.render_scanline_position); + status.line_render_position = min(1112U, (uint)config::ppu.hack.render_scanline_position); status.dram_refreshed = false; status.dram_refresh_position = (cpu_version == 1) ? 530 : 538; diff --git a/src/doc/base.dia b/src/doc/base.dia deleted file mode 100644 index dfbe69e41c8520136e8228945cb30086688535ae..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1943 zcmV;I2Wa>oiwFP!000003+R_PJa29!f zI3Ewbef{~`8GO9G`r!HGJ^!7@WTEjR!X$k+9y~C%d_NjJJw55cIw35I^}t{02_5}Q zf`E*8q0!*>O4GItc!ZJkv;0%SSnN+%jA|iS(D7hOX8+9NXcc;cO{u)xEDEAndnCbl z@a{hQ8H{o>qa8a3Y%j^2PGd^`sW%PykLxxuy`*v3>|z-uJ}<)7%e^8scGB0aGI^-stHm8(-P}r(E(b`Jbg2Zz_+^>iCO|a<*q&o;9-WjIrxWG1S_|hk*S2yjp zx}e+Y;%=++lgToQSxkJkU*$B40!qS7tt?*A=Jg~q5^xtg)GUEk-2040N6!DA1j$<( zu=)5k+D?t!dF*?K19zuHjg=?gV-J&ON!_)vzLsSD(NFwoK&#H)4_RyG*X@`uU!9EJ z#o>b9u(4Jv51vC!YMw3+^Of(>-BQEw|30tqmo!>RRm;BV;_fH=VJ(d3TJ29*I5eTKgP54~kI-A9MKLc;VC&8%;zZ ztEwvfT)QU=KUniKB4IMn61GlB#hJ4?^cNaDQs&RdHc(GLgS~*L2nwJ(VE4xmt8~}x zj=NryI(GH&z@!NPv5NR;a~>{e^@XJ2YLR#18*8alyVHW|{D54fb z(ULBTW+94>d{MNND4tssaSNho%N0dyBZ>&?kh`Vb3r)QH_8uF zrH_5qN23LOgh0ALx`jYOBwrz$wn#~2dlG53AdwKt)kp|(kpw!xi2Ek&jZ7+W>_8kL zRO;Agb+kkogoaS+>@mBen#~?Lic)cuJ$-E6Af=71xuq>Ejk5i6%P~56(Lmh72$%QKB`JQFL=?9?-V^FvzUno#)3J%U3+CNzPb zJ{3*H9P+=c#%?)_!f--EFFWmRahK|c85VK{u=BhlJliZ4tm`z9=M^E)L7KDV2 zPXZdw4}~1RP~w#w3G2pn@Cz@ik6um7>!G5Gw)!WH1|Ddf1-LFkA?fmO{EiRiEpq4zB#h_X20?+n@YaUg!YRV_ znQ%yeaK@Pkhgu*Ul$m^KrYZD}l|G>`fst|!+BUD#(hb*=&${il?H8~bPeT;z6zlrT zIzxbU)|ps`FP(MJ)GZ@to$cThcG!eQ20H}pbJGqg+$r2C+?|R$`%JhqE**D#_PUEZ z>!NUn6z&x66z)#NopUDKnLWTApUS!~Gg)k1(o7aB*eTd4*qsVHS2FDCmZl2l_dz^_ zQrF?&6l|N-sivN#824l)&h-ypzNs8z={d%`{-<(`FFD7!jzYreoJcZ-P(dNYDP;AC zLU+G^Q52F*A*3kOe+mhw?qbOl!Uct}$??;t!O)L)3PaK{gcXMRk0J3qZOIgRg;3uZ z^hHg`I$)4OP~Ue90xc~11hN->x?5{Lk^D8EYCi;lRU&o!?D`>{WOS_ec%$h9jr5XE zV&eI$q`rI7BtX+}4QzsRgI&iq={3MkCs795SdRsyug7w?mSdp~mSd?vQ-Rj*h#H|5 zM$}O5h&ta!#nz$QmpxSe@;w@9(TXisObx3$7*?yTRQf%$N4Sj}j8O6o#+*dBPbm7d z@_dD&F7Glb7WIThHCb**IH}i?yBUP3XPe3Kxrdeh)xnDU-3C>Dk1i;&O{HwLkg`?3 zg6Iuv$?F%QOHEKk!U?Kaa_r(FcyU+Ji;smbR`L7&#jh(8zwk`)YqcP~K&te**sjv_vfbC{`y#fmw@?{ttTs&wu-S=IE@x^X<07T+=_gLIj7~5^gu*^6{hVCGM zUgMZ+aT>oJ#W6k>$jDTI{M`jIY%h?Ft^(O4Nq88>dWFCq`)o9qc(ns6g~I9+N| zMFG&b&1#*OTIbbg$l0|6j+3`6>5OsWNrgc23X1}AxGTt&+Eks7pdhCp_dkT3Qwyq- z7qfOXBg5i(i;^J+3&^3aAcu}Y4k^ef$f=RssgQHd1Ud2lCJp2!k!%i=m6&q%pe?u!}%JHdA5ps0wA8A~`=LGbP$)1NHbf`G doA&`()A;sk^M?P +typedef int8_t int8; +typedef int16_t int16; +typedef int32_t int32; +typedef int64_t int64; +typedef uint8_t uint8; +typedef uint16_t uint16; +typedef uint32_t uint32; +typedef uint64_t uint64; +typedef unsigned int uint; + +#include +using std::min; +using std::max; #include #include -#include #include #include #include @@ -16,8 +30,6 @@ #include #include -#include - #if defined(_MSC_VER) || defined(__MINGW32__) #include #include @@ -70,22 +82,6 @@ #define alwaysinline inline #endif -/***** - * typedefs - *****/ - -typedef unsigned int uint; - -typedef uint8_t uint8; -typedef uint16_t uint16; -typedef uint32_t uint32; -typedef uint64_t uint64; - -typedef int8_t int8; -typedef int16_t int16; -typedef int32_t int32; -typedef int64_t int64; - /***** * OS localization *****/ @@ -108,26 +104,6 @@ struct passwd *userinfo = getpwuid(getuid()); } #endif -/***** - * template classes - *****/ - -class noncopyable { -protected: - noncopyable() {} - ~noncopyable() {} - -private: - noncopyable(const noncopyable&); - const noncopyable& operator=(const noncopyable&); -}; - -template -struct base_from_member { - T value; - base_from_member(T value_) : value(value_) {} -}; - /***** * template functions *****/ @@ -153,88 +129,57 @@ template inline void safe_release(T &handle) { } } -template inline void swap(T &x, T &y) { -T z = x; - x = y; - y = z; -} - -#undef min -#define min(x, y) (((x) < (y)) ? (x) : (y)) - -#undef max -#define max(x, y) (((x) > (y)) ? (x) : (y)) - template inline T minmax(const T x) { return (x < (T)min) ? (T)min : (x > (T)max) ? (T)max : x; } -template inline unsigned uclamp(const unsigned x) { -enum { y = (1U << bits) - 1 }; - return y + ((x - y) & -(x < y)); //min(x, y); -} - -template inline unsigned uclip(const unsigned x) { -enum { m = (1U << bits) - 1 }; - return (x & m); -} - -template inline signed sclamp(const signed x) { -enum { b = 1U << (bits - 1), m = (1U << (bits - 1)) - 1 }; - return (x > m) ? m : (x < -b) ? -b : x; -} - -template inline signed sclip(const signed x) { -enum { b = 1U << (bits - 1), m = (1U << bits) - 1 }; - return ((x & m) ^ b) - b; -} - /***** * endian wrappers *****/ -#ifndef ARCH_MSB -//little-endian: uint8[] { 0x01, 0x02, 0x03, 0x04 } = 0x04030201 -#define order_lsb2(a,b) a,b -#define order_lsb3(a,b,c) a,b,c -#define order_lsb4(a,b,c,d) a,b,c,d -#define order_lsb5(a,b,c,d,e) a,b,c,d,e -#define order_lsb6(a,b,c,d,e,f) a,b,c,d,e,f -#define order_lsb7(a,b,c,d,e,f,g) a,b,c,d,e,f,g -#define order_lsb8(a,b,c,d,e,f,g,h) a,b,c,d,e,f,g,h -#define order_msb2(a,b) b,a -#define order_msb3(a,b,c) c,b,a -#define order_msb4(a,b,c,d) d,c,b,a -#define order_msb5(a,b,c,d,e) e,d,c,b,a -#define order_msb6(a,b,c,d,e,f) f,e,d,c,b,a -#define order_msb7(a,b,c,d,e,f,g) g,f,e,d,c,b,a -#define order_msb8(a,b,c,d,e,f,g,h) h,g,f,e,d,c,b,a -#else -//big-endian: uint8[] { 0x01, 0x02, 0x03, 0x04 } = 0x01020304 -#define order_lsb2(a,b) b,a -#define order_lsb3(a,b,c) c,b,a -#define order_lsb4(a,b,c,d) d,c,b,a -#define order_lsb5(a,b,c,d,e) e,d,c,b,a -#define order_lsb6(a,b,c,d,e,f) f,e,d,c,b,a -#define order_lsb7(a,b,c,d,e,f,g) g,f,e,d,c,b,a -#define order_lsb8(a,b,c,d,e,f,g,h) h,g,f,e,d,c,b,a -#define order_msb2(a,b) a,b -#define order_msb3(a,b,c) a,b,c -#define order_msb4(a,b,c,d) a,b,c,d -#define order_msb5(a,b,c,d,e) a,b,c,d,e -#define order_msb6(a,b,c,d,e,f) a,b,c,d,e,f -#define order_msb7(a,b,c,d,e,f,g) a,b,c,d,e,f,g -#define order_msb8(a,b,c,d,e,f,g,h) a,b,c,d,e,f,g,h +#ifndef ARCH_MSB +//little-endian: uint8[] { 0x01, 0x02, 0x03, 0x04 } == 0x04030201 + #define order_lsb2(a,b) a,b + #define order_lsb3(a,b,c) a,b,c + #define order_lsb4(a,b,c,d) a,b,c,d + #define order_lsb5(a,b,c,d,e) a,b,c,d,e + #define order_lsb6(a,b,c,d,e,f) a,b,c,d,e,f + #define order_lsb7(a,b,c,d,e,f,g) a,b,c,d,e,f,g + #define order_lsb8(a,b,c,d,e,f,g,h) a,b,c,d,e,f,g,h + #define order_msb2(a,b) b,a + #define order_msb3(a,b,c) c,b,a + #define order_msb4(a,b,c,d) d,c,b,a + #define order_msb5(a,b,c,d,e) e,d,c,b,a + #define order_msb6(a,b,c,d,e,f) f,e,d,c,b,a + #define order_msb7(a,b,c,d,e,f,g) g,f,e,d,c,b,a + #define order_msb8(a,b,c,d,e,f,g,h) h,g,f,e,d,c,b,a +#else +//big-endian: uint8[] { 0x01, 0x02, 0x03, 0x04 } == 0x01020304 + #define order_lsb2(a,b) b,a + #define order_lsb3(a,b,c) c,b,a + #define order_lsb4(a,b,c,d) d,c,b,a + #define order_lsb5(a,b,c,d,e) e,d,c,b,a + #define order_lsb6(a,b,c,d,e,f) f,e,d,c,b,a + #define order_lsb7(a,b,c,d,e,f,g) g,f,e,d,c,b,a + #define order_lsb8(a,b,c,d,e,f,g,h) h,g,f,e,d,c,b,a + #define order_msb2(a,b) a,b + #define order_msb3(a,b,c) a,b,c + #define order_msb4(a,b,c,d) a,b,c,d + #define order_msb5(a,b,c,d,e) a,b,c,d,e + #define order_msb6(a,b,c,d,e,f) a,b,c,d,e,f + #define order_msb7(a,b,c,d,e,f,g) a,b,c,d,e,f,g + #define order_msb8(a,b,c,d,e,f,g,h) a,b,c,d,e,f,g,h #endif /***** * libc extensions *****/ - -//static uint random() { -//static uint n = 0; -// return n = (n >> 1) ^ (((n & 1) - 1) & 0xedb88320); -//} + +//pseudo-random number generator +static uint prng() { +static uint n = 0; + return n = (n >> 1) ^ (((n & 1) - 1) & 0xedb88320); +} static uint64 fget(FILE *fp, uint length = 1) { uint64 data = 0; @@ -283,7 +228,6 @@ static int fresize(FILE *fp, long size) { /***** * crc32 calculation - * TODO: create libhash and move this code there *****/ const uint32 crc32_table[256] = { diff --git a/src/lib/bconfig.h b/src/lib/bconfig.h deleted file mode 100644 index 926c25b6..00000000 --- a/src/lib/bconfig.h +++ /dev/null @@ -1,185 +0,0 @@ -/* - bconfig : version 0.16 ~byuu (2007-11-28) - license: public domain -*/ - -#ifndef BCONFIG_H -#define BCONFIG_H - -#include "bbase.h" -#include "barray.h" -#include "bstring.h" - -class Setting; - -class Config { -public: - array list; - uint list_count; - - string data; - lstring line, part, subpart; - - bool load(const char *fn); - bool save(const char *fn); - void add(Setting *setting) { list[list_count++] = setting; } - - Config() : list_count(0) {} -}; - -class Setting { -public: - enum Type { - Integer, - String, - } type; - char *name, *desc, *def; - - virtual void set(const char *input) = 0; - virtual void get(string &output) = 0; -}; - -class IntegerSetting : public Setting { -public: - enum Format { - Boolean, - Decimal, - Hex, - } ifmt; - uint data, idef; - - void set(const char *input) { - if(ifmt == Boolean) { data = !strcmp(input, "true"); } - if(ifmt == Decimal) { data = strdec(input); } - if(ifmt == Hex) { data = strhex(input + (stribegin(input, "0x") ? 2 : 0)); } - } - - void get(string &output) { - output.reserve(64); - if(ifmt == Boolean) { sprintf(output(), "%s", data ? "true" : "false"); } - if(ifmt == Decimal) { sprintf(output(), "%d", data); } - if(ifmt == Hex) { sprintf(output(), "0x%x", data); } - } - - uint operator()() { return data; } - operator uint() { return data; } - template IntegerSetting &operator=(T x) { data = uint(x); return *this; } - template bool operator==(T x) { return (T(data) == x); } - template bool operator!=(T x) { return (T(data) != x); } - template bool operator>=(T x) { return (T(data) >= x); } - template bool operator> (T x) { return (T(data) > x); } - template bool operator<=(T x) { return (T(data) <= x); } - template bool operator< (T x) { return (T(data) < x); } - - IntegerSetting(Config *parent, const char *r_name, const char *r_desc, Format r_format, uint r_data) { - type = Setting::Integer; - name = strdup(r_name); - desc = strdup(r_desc); - ifmt = r_format; - data = idef = r_data; - string t; - get(t); - def = strdup(t); - - if(parent) { parent->add(this); } - } - - ~IntegerSetting() { - safe_free(name); - safe_free(desc); - safe_free(def); - } -}; - -class StringSetting : public Setting { -public: - string data; - void set(const char *input) { data = input; trim(data(), "\""); } - void get(string &output) { output = string() << "\"" << data << "\""; } - - char* operator()() { return data(); } - operator const char*() { return data; } - StringSetting &operator=(const char *x) { data = x; return *this; } - bool operator==(const char *x) { return !strcmp(data, x); } - bool operator!=(const char *x) { return strcmp(data, x); } - - StringSetting(Config *parent, const char *r_name, const char *r_desc, const char *r_data) { - type = Setting::String; - name = strdup(r_name); - desc = strdup(r_desc); - data = r_data; - string t; - get(t); - def = strdup(t); - - if(parent) { parent->add(this); } - } - - ~StringSetting() { - safe_free(name); - safe_free(desc); - safe_free(def); - } -}; - -inline bool Config::load(const char *fn) { -FILE *fp = fopen(fn, "rb"); - if(!fp)return false; - -//load the config file into memory - fseek(fp, 0, SEEK_END); -int fsize = ftell(fp); - fseek(fp, 0, SEEK_SET); -char *buffer = (char*)malloc(fsize + 1); - fread(buffer, 1, fsize, fp); - fclose(fp); - *(buffer + fsize) = 0; - strcpy(data, buffer); - free(buffer); - -//split the file into lines - replace(data, "\r\n", "\n"); - qreplace(data, "\t", ""); - qreplace(data, " ", ""); - split(line, "\n", data); - - for(int i = 0; i < count(line); i++) { - if(strlen(line[i]) == 0)continue; - if(*line[i] == '#')continue; - - qsplit(part, "=", line[i]); - for(int l = 0; l < list_count; l++) { - if(!strcmp(list[l]->name, part[0])) { - list[l]->set(part[1]); - break; - } - } - } - - return true; -} - -inline bool Config::save(const char *fn) { -FILE *fp; -string t; - fp = fopen(fn, "wb"); - if(!fp)return false; - - for(int i = 0; i < list_count; i++) { - strcpy(data, list[i]->desc); - replace(data, "\r\n", "\n"); - split(line, "\n", data); - for(int l = 0; l < count(line); l++) { - if(line[l] != "") { fprintf(fp, "# %s\r\n", line[l]()); } - } - - fprintf(fp, "# (default = %s)\r\n", list[i]->def); - list[i]->get(t); - fprintf(fp, "%s = %s\r\n\r\n", list[i]->name, t()); - } - - fclose(fp); - return true; -} - -#endif //ifndef BCONFIG_H diff --git a/src/lib/bkeymap.h b/src/lib/bkeymap.h deleted file mode 100644 index b11af5a5..00000000 --- a/src/lib/bkeymap.h +++ /dev/null @@ -1,310 +0,0 @@ -/* - bkeymap : version 0.02 ~byuu (2007-05-28) - license: public domain -*/ - -#ifndef BKEYMAP_H -#define BKEYMAP_H - -namespace keymap { - -//TODO: use lookup table for find() functions -static char keytable[][64] = { - "none", - "esc", - "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9", "f10", "f11", "f12", - "print_screen", "sys_req", "scroll_lock", "pause", "brk", - "grave", "tilde", - "num_1", "exclamation", - "num_2", "at", - "num_3", "pound", - "num_4", "dollar", - "num_5", "percent", - "num_6", "power", - "num_7", "ampersand", - "num_8", "asterisk", - "num_9", "lparenthesis", - "num_0", "rparenthesis", - "minus", "underscore", - "equal", "plus", - "backspace", -}; - -enum { - none = 0x0000, - - esc, - - f1, - f2, - f3, - f4, - f5, - f6, - f7, - f8, - f9, - f10, - f11, - f12, - - print_screen, sys_req, - scroll_lock, - pause, brk, - - grave, tilde, - - num_1, exclamation, - num_2, at, - num_3, pound, - num_4, dollar, - num_5, percent, - num_6, power, - num_7, ampersand, - num_8, asterisk, - num_9, lparenthesis, - num_0, rparenthesis, - - minus, underscore, - equal, plus, - backspace, - - ins, - del, - home, - end, - page_up, - page_down, - - a, b, c, d, e, f, g, h, i, j, k, l, m, - n, o, p, q, r, s, t, u, v, w, x, y, z, - - A, B, C, D, E, F, G, H, I, J, K, L, M, - N, O, P, Q, R, S, T, U, V, W, X, Y, Z, - - lbracket, lbrace, - rbracket, rbrace, - backslash, pipe, - semicolon, colon, - apostrophe, quote, - comma, lcaret, - period, rcaret, - slash, question, - - kp_1, kp_end, - kp_2, kp_down, - kp_3, kp_page_down, - kp_4, kp_left, - kp_5, kp_center, - kp_6, kp_right, - kp_7, kp_home, - kp_8, kp_up, - kp_9, kp_page_up, - kp_0, kp_insert, - kp_decimal, kp_delete, - - kp_plus, - kp_minus, - kp_mul, - kp_div, - kp_enter, - - num_lock, - caps_lock, - - up, - down, - left, - right, - - tab, - enter, - space, - - lctrl, - rctrl, - lalt, - ralt, - lshift, - rshift, - lsuper, - rsuper, - menu, - - limit, //not an actual key -- marks the end of linear key entries - - joypad_flag = 0x8000, - joypad_nummask = 0x7f00, - joypad_keymask = 0x00ff, - - joypad_up = 0x0080, - joypad_down = 0x0081, - joypad_left = 0x0082, - joypad_right = 0x0083, -}; - -static uint16 find(const char *key) { -#define match(_n) if(!strcmp(#_n, key)) { return _n; } - match(none) - match(esc) - match(f1) match(f2) match(f3) match(f4) match(f5) match(f6) - match(f7) match(f8) match(f9) match(f10) match(f11) match(f12) - match(print_screen) match(sys_req) match(scroll_lock) match(pause) match(brk) - match(grave) match(tilde) - match(num_1) match(exclamation) - match(num_2) match(at) - match(num_3) match(pound) - match(num_4) match(dollar) - match(num_5) match(percent) - match(num_6) match(power) - match(num_7) match(ampersand) - match(num_8) match(asterisk) - match(num_9) match(lparenthesis) - match(num_0) match(rparenthesis) - match(minus) match(underscore) match(equal) match(plus) match(backspace) - match(ins) match(del) match(home) match(end) match(page_up) match(page_down) - match(a) match(b) match(c) match(d) match(e) match(f) - match(g) match(h) match(i) match(j) match(k) match(l) - match(m) match(n) match(o) match(p) match(q) match(r) - match(s) match(t) match(u) match(v) match(w) match(x) - match(y) match(z) - match(A) match(B) match(C) match(D) match(E) match(F) - match(G) match(H) match(I) match(J) match(K) match(L) - match(M) match(N) match(O) match(P) match(Q) match(R) - match(S) match(T) match(U) match(V) match(W) match(X) - match(Y) match(Z) - match(lbracket) match(lbrace) - match(rbracket) match(rbrace) - match(backslash) match(pipe) - match(semicolon) match(colon) - match(apostrophe) match(quote) - match(comma) match(lcaret) - match(period) match(rcaret) - match(slash) match(question) - match(kp_1) match(kp_end) - match(kp_2) match(kp_down) - match(kp_3) match(kp_page_down) - match(kp_4) match(kp_left) - match(kp_5) match(kp_center) - match(kp_6) match(kp_right) - match(kp_7) match(kp_home) - match(kp_8) match(kp_up) - match(kp_9) match(kp_page_up) - match(kp_0) match(kp_insert) - match(kp_decimal) match(kp_delete) - match(kp_plus) match(kp_minus) match(kp_mul) match(kp_div) match(kp_enter) - match(num_lock) match(caps_lock) - match(up) match(down) match(left) match(right) - match(tab) match(enter) match(space) - match(lctrl) match(rctrl) - match(lalt) match(ralt) - match(lshift) match(rshift) - match(lsuper) match(rsuper) - match(menu) -#undef match - - if(!memcmp(key, "joypad", 6)) { - const char *p = key + 6; - uint joypad, button, n; - sscanf(p, "%u%n", &joypad, &n); - joypad &= 127; - p += n; - if(!strcmp(p, ".up")) { return joypad_flag | (joypad << 8) | joypad_up; } - if(!strcmp(p, ".down")) { return joypad_flag | (joypad << 8) | joypad_down; } - if(!strcmp(p, ".left")) { return joypad_flag | (joypad << 8) | joypad_left; } - if(!strcmp(p, ".right")) { return joypad_flag | (joypad << 8) | joypad_right; } - if(!memcmp(p, ".button", 7)) { - sscanf(p + 7, "%u", &button); - button &= 127; - return joypad_flag | (joypad << 8) | button; - } - } - - return none; -} - -static char *find(char *out, uint16 key) { -#define match(_n) if(_n == key) { strcpy(out, #_n); return out; } - match(none) - match(esc) - match(f1) match(f2) match(f3) match(f4) match(f5) match(f6) - match(f7) match(f8) match(f9) match(f10) match(f11) match(f12) - match(print_screen) match(sys_req) match(scroll_lock) match(pause) match(brk) - match(grave) match(tilde) - match(num_1) match(exclamation) - match(num_2) match(at) - match(num_3) match(pound) - match(num_4) match(dollar) - match(num_5) match(percent) - match(num_6) match(power) - match(num_7) match(ampersand) - match(num_8) match(asterisk) - match(num_9) match(lparenthesis) - match(num_0) match(rparenthesis) - match(minus) match(underscore) match(equal) match(plus) match(backspace) - match(ins) match(del) match(home) match(end) match(page_up) match(page_down) - match(a) match(b) match(c) match(d) match(e) match(f) - match(g) match(h) match(i) match(j) match(k) match(l) - match(m) match(n) match(o) match(p) match(q) match(r) - match(s) match(t) match(u) match(v) match(w) match(x) - match(y) match(z) - match(A) match(B) match(C) match(D) match(E) match(F) - match(G) match(H) match(I) match(J) match(K) match(L) - match(M) match(N) match(O) match(P) match(Q) match(R) - match(S) match(T) match(U) match(V) match(W) match(X) - match(Y) match(Z) - match(lbracket) match(lbrace) - match(rbracket) match(rbrace) - match(backslash) match(pipe) - match(semicolon) match(colon) - match(apostrophe) match(quote) - match(comma) match(lcaret) - match(period) match(rcaret) - match(slash) match(question) - match(kp_1) match(kp_end) - match(kp_2) match(kp_down) - match(kp_3) match(kp_page_down) - match(kp_4) match(kp_left) - match(kp_5) match(kp_center) - match(kp_6) match(kp_right) - match(kp_7) match(kp_home) - match(kp_8) match(kp_up) - match(kp_9) match(kp_page_up) - match(kp_0) match(kp_insert) - match(kp_decimal) match(kp_delete) - match(kp_plus) match(kp_minus) match(kp_mul) match(kp_div) match(kp_enter) - match(num_lock) match(caps_lock) - match(up) match(down) match(left) match(right) - match(tab) match(enter) match(space) - match(lctrl) match(rctrl) - match(lalt) match(ralt) - match(lshift) match(rshift) - match(lsuper) match(rsuper) - match(menu) -#undef match - - if(key & joypad_flag) { - uint joypad = (key & joypad_nummask) >> 8; - uint button = (key & joypad_keymask); - if(button == joypad_up) { sprintf(out, "joypad%d.up", joypad); return out; } - if(button == joypad_down) { sprintf(out, "joypad%d.down", joypad); return out; } - if(button == joypad_left) { sprintf(out, "joypad%d.left", joypad); return out; } - if(button == joypad_right) { sprintf(out, "joypad%d.right", joypad); return out; } - sprintf(out, "joypad%d.button%d", joypad, button & 127); - return out; - } - - strcpy(out, "none"); - return out; -} - -static char find_t[256]; - -static const char *find(uint16 key) { - find(find_t, key); - return find_t; -} - -}; - -#endif //ifndef BKEYMAP_H diff --git a/src/lib/bstring.cpp b/src/lib/bstring.cpp deleted file mode 100644 index 65fc66f8..00000000 --- a/src/lib/bstring.cpp +++ /dev/null @@ -1,95 +0,0 @@ -#include "bstring.h" - -#include "bstring/bstring.list.cpp" -#include "bstring/bstring.strl.cpp" -#include "bstring/bstring.math.cpp" -#include "bstring/bstring.misc.cpp" -#include "bstring/bstring.replace.cpp" -#include "bstring/bstring.split.cpp" -#include "bstring/bstring.trim.cpp" - -void string::reserve(uint size_) { - if(size_ > size) { - size = size_; - data = (char*)realloc(data, size + 1); - data[size] = 0; - } -} - -//implicit-conversion, read-only -string::operator const char*() const { - return data; -} - -//explicit-coversion, read-write -char* string::operator()() { - return data; -} - -//index, read-write -char& string::operator[](const uint index) { - reserve(index); - return data[index]; -} - -string& string::operator=(const int num) { - itoa(*this, num); - return *this; -} - -string& string::operator=(const char *str) { - strcpy(*this, str); - return *this; -} - -string& string::operator=(const string &str) { - strcpy(*this, str); - return *this; -} - -string& string::operator<<(const int num) { -string temp(num); - strcat(*this, temp); - return *this; -} - -string& string::operator<<(const char *str) { - strcat(*this, str); - return *this; -} - -bool string::operator==(const char *str) { return strcmp(data, str) == 0; } -bool string::operator!=(const char *str) { return strcmp(data, str) != 0; } -bool string::operator< (const char *str) { return strcmp(data, str) < 0; } -bool string::operator<=(const char *str) { return strcmp(data, str) <= 0; } -bool string::operator> (const char *str) { return strcmp(data, str) > 0; } -bool string::operator>=(const char *str) { return strcmp(data, str) >= 0; } - -string::string() { - size = 64; - data = (char*)malloc(size + 1); - *data = 0; -} - -string::string(const int source) { - size = 64; - data = (char*)malloc(size + 1); - *data = 0; - itoa(*this, source); -} - -string::string(const char *source) { - size = strlen(source); - data = (char*)malloc(size + 1); - strcpy(data, source); -} - -string::string(const string &source) { - size = strlen(source); - data = (char*)malloc(size + 1); - strcpy(data, source); -} - -string::~string() { - safe_free(data); -} diff --git a/src/lib/bstring.h b/src/lib/bstring.h deleted file mode 100644 index 64602e4d..00000000 --- a/src/lib/bstring.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - bstring : version 0.01a ~byuu (2007-12-12) - license: public domain -*/ - -#ifndef BSTRING_H -#define BSTRING_H - -#include "bbase.h" -#include "bvector.h" - -class string; -typedef linear_vector lstring; - -uint count(lstring&); -int find(lstring &str, const char *key); - -uint strlcpy(char *dest, const char *src, uint length); -uint strlcat(char *dest, const char *src, uint length); -uint strlcpy(string &dest, const char *src, uint length); -uint strlcat(string &dest, const char *src, uint length); - -int strmath(const char *str); - -char chrlower(char c); -char chrupper(char c); -int stricmp(const char *dest, const char *src); -void strcpy(string &dest, const char *src); -void strcat(string &dest, const char *src); -string substr(string &dest, const char *src, uint start = 0, uint length = 0); -char* strlower(char *str); -char* strupper(char *str); -string& strlower(string &str); -string& strupper(string &str); -int strpos(const char *str, const char *key); -int qstrpos(const char *str, const char *key); -char* strtr(char *dest, const char *before, const char *after); -string& strtr(string &dest, const char *before, const char *after); -bool strbegin(const char *str, const char *key); -bool stribegin(const char *str, const char *key); -bool strend(const char *str, const char *key); -bool striend(const char *str, const char *key); - -uint strhex(const char *str); -uint strdec(const char *str); -uint strbin(const char *str); - -string& utoa(string &str, uint num); -string& itoa(string &str, uint num); -string& htoa(string &str, uint num); -string& btoa(string &str, uint num); - -bool fread(string &str, const char *filename); - -string& replace(string &str, const char *key, const char *token); -string& qreplace(string &str, const char *key, const char *token); - -void split(lstring &dest, const char *key, const char *src); -void qsplit(lstring &dest, const char *key, const char *src); - -char* ltrim(char *str, const char *key = " "); -char* rtrim(char *str, const char *key = " "); -char* trim(char *str, const char *key = " "); -string& ltrim(string &str, const char *key = " "); -string& rtrim(string &str, const char *key = " "); -string& trim(string &str, const char *key = " "); - -class string { -public: - char *data; - uint size; - - void reserve(uint size_); - - operator const char*() const; - char* operator()(); - char& operator[](const uint); - - string& operator=(const int num); - string& operator=(const char *str); - string& operator=(const string &str); - string& operator<<(const int num); - string& operator<<(const char *str); - - bool operator==(const char *str); - bool operator!=(const char *str); - bool operator< (const char *str); - bool operator<=(const char *str); - bool operator> (const char *str); - bool operator>=(const char *str); - - string(); - string(const int num); - string(const char *source); - string(const string &source); - ~string(); -}; - -#endif //ifndef BSTRING_H diff --git a/src/lib/bstring/bstring.list.cpp b/src/lib/bstring/bstring.list.cpp deleted file mode 100644 index c924ead0..00000000 --- a/src/lib/bstring/bstring.list.cpp +++ /dev/null @@ -1,14 +0,0 @@ -#ifdef BSTRING_H - -uint count(lstring &str) { - return str.size(); -} - -int find(lstring &str, const char *key) { - for(uint i = 0; i < count(str); i++) { - if(str[i] == key) return i; - } - return -1; -} - -#endif //ifdef BSTRING_H diff --git a/src/lib/bstring/bstring.math.cpp b/src/lib/bstring/bstring.math.cpp deleted file mode 100644 index 8f08c5f1..00000000 --- a/src/lib/bstring/bstring.math.cpp +++ /dev/null @@ -1,194 +0,0 @@ -#ifdef BSTRING_H - -/* - recursive descent math processor v0.02 (2007-11-28) - authors: gladius, byuu - license: public domain -*/ - -void strmath_space(const char *&s) { - while(*s == ' ' || *s == '\t')s++; -} - -int strmath_number(const char *&s) { -int result = 0; -enum type { dec, hex, bin, oct }; -type t = dec; - if(*s == '0') { - s++; - if(*s == 'x' || *s == 'X') { s++; t = hex; } - else if(*s == 'b' || *s == 'B') { s++; t = bin; } - else { t = oct; } - } else if(*s == '$') { - s++; - t = hex; - } else if(*s == '%') { - s++; - t = bin; - } - - switch(t) { - - case dec: { - while(true) { - char x = *s; - if(x >= '0' && x <= '9')x = x - '0'; - else break; - result = result * 10 + x; - s++; - } - } break; - - case hex: { - while(true) { - char x = *s; - if(x >= '0' && x <= '9')x = x - '0'; - else if(x >= 'a' && x <= 'f')x = x - 'a' + 0x0a; - else if(x >= 'A' && x <= 'F')x = x - 'A' + 0x0a; - else break; - result = result * 16 + x; - s++; - } - } break; - - case bin: { - while(true) { - char x = *s; - if(x >= '0' && x <= '1')x = x - '0'; - else break; - result = result * 2 + x; - s++; - } - } break; - - case oct: { - while(true) { - char x = *s; - if(x >= '0' && x <= '7')x = x - '0'; - else break; - result = result * 8 + x; - s++; - } - } break; - - } - - return result; - -int num, len; - sscanf(s, "%d%n", &num, &len); - s += len; - return num; -} - -#define maxlevel 12 -int strmath_rdp(const char *&s, int level = 0) { - strmath_space(s); - - if(level == maxlevel) { - if(*s == '(') { - int result = strmath_rdp(++s, 0); - s++; - return result; - } else if(*s == '+') { - return +strmath_rdp(++s, maxlevel); - } else if(*s == '-') { - return -strmath_rdp(++s, maxlevel); - } else if(*s == '!') { - return !strmath_rdp(++s, maxlevel); - } else if(*s == '~') { - return ~strmath_rdp(++s, maxlevel); - } else if((*s >= '0' && *s <= '9') || *s == '$' || *s == '%') { - return strmath_number(s); - } else { - return 0; //error - } - } - -int lhs = strmath_rdp(s, level + 1); - strmath_space(s); - while(*s) { - int a = *s; - int b = *s ? *(s + 1) : 0; - switch(level) { - case 0: - if(a == '?')break; - return lhs; - case 1: - if(a == '|' && b == '|') { s++; break; } - return lhs; - case 2: - if(a == '^' && b == '^') { s++; break; } - return lhs; - case 3: - if(a == '&' && b == '&') { s++; break; } - return lhs; - case 4: - if(a == '|' && b != '|')break; - return lhs; - case 5: - if(a == '^' && b != '^')break; - return lhs; - case 6: - if(a == '&' && b != '&')break; - return lhs; - case 7: - if(a == '=' && b == '=') { s++; break; } - if(a == '!' && b == '=') { s++; break; } - return lhs; - case 8: - if(a == '<' && b == '=') { s++; break; } - if(a == '>' && b == '=') { s++; break; } - if(a == '<')break; - if(a == '>')break; - return lhs; - case 9: - if(a == '<' && b == '<') { s++; break; } - if(a == '>' && b == '>') { s++; break; } - return lhs; - case 10: - if(a == '+')break; - if(a == '-')break; - return lhs; - case 11: - if(a == '*')break; - if(a == '/')break; - if(a == '%')break; - return lhs; - } - if(a == '?') { - int tr = strmath_rdp(++s, level); - int fr = strmath_rdp(++s, level); - lhs = (lhs) ? tr : fr; - } else { - int rhs = strmath_rdp(++s, level + 1); - if (a == '|' && b == '|') lhs = (lhs || rhs); - else if(a == '^' && b == '^') lhs = (!lhs != !rhs); - else if(a == '&' && b == '&') lhs = (lhs && rhs); - else if(a == '|' && b != '|') lhs |= rhs; - else if(a == '^' && b != '^') lhs ^= rhs; - else if(a == '&' && b != '&') lhs &= rhs; - else if(a == '=' && b == '=') lhs = (lhs == rhs); - else if(a == '!' && b == '=') lhs = (lhs != rhs); - else if(a == '<' && b == '=') lhs = (lhs <= rhs); - else if(a == '>' && b == '=') lhs = (lhs >= rhs); - else if(a == '<' && b != '<') lhs = (lhs < rhs); - else if(a == '>' && b != '>') lhs = (lhs > rhs); - else if(a == '<' && b == '<') lhs <<= rhs; - else if(a == '>' && b == '>') lhs >>= rhs; - else if(a == '+') lhs += rhs; - else if(a == '-') lhs -= rhs; - else if(a == '*') lhs *= rhs; - else if(a == '/') lhs /= rhs; - else if(a == '%') lhs %= rhs; - } - } - return lhs; -} -#undef maxlevel - -int strmath(const char *str) { - return strmath_rdp(str); -} - -#endif //ifdef BSTRING_H diff --git a/src/lib/bstring/bstring.misc.cpp b/src/lib/bstring/bstring.misc.cpp deleted file mode 100644 index 8bf85fad..00000000 --- a/src/lib/bstring/bstring.misc.cpp +++ /dev/null @@ -1,277 +0,0 @@ -#ifdef BSTRING_H - -char chrlower(char c) { - return (c >= 'A' && c <= 'Z') ? c + ('a' - 'A') : c; -} - -char chrupper(char c) { - return (c >= 'a' && c <= 'z') ? c - ('a' - 'A') : c; -} - -int stricmp(const char *dest, const char *src) { - while(*dest) { - if(chrlower(*dest) != chrlower(*src)) break; - dest++; - src++; - } - - return (int)chrlower(*dest) - (int)chrlower(*src); -} - -void strcpy(string &dest, const char *src) { -int srclen = strlen(src); - dest.reserve(srclen); - strcpy(dest(), src); -} - -void strcat(string &dest, const char *src) { -int srclen = strlen(src); -int destlen = strlen(dest); - dest.reserve(srclen + destlen); - strcat(dest(), src); -} - -string substr(const char *src, uint start, uint length) { -string dest; - if(length == 0) { - //copy entire string - strcpy(dest, src + start); - } else { - //copy partial string - strlcpy(dest, src + start, length + 1); - } - return dest; -} - -char* strlower(char *str) { -uint i = 0; - while(str[i]) { - str[i] = chrlower(str[i]); - i++; - } - return str; -} - -char* strupper(char *str) { -uint i = 0; - while(str[i]) { - str[i] = chrupper(str[i]); - i++; - } - return str; -} - -string& strlower(string &str) { - strlower(str()); - return str; -} - -string& strupper(string &str) { - strupper(str()); - return str; -} - -int strpos(const char *str, const char *key) { -int ssl = strlen(str), ksl = strlen(key); - if(ksl > ssl) return -1; - for(int i = 0; i <= ssl - ksl; i++) { - if(!memcmp(str + i, key, ksl)) { - return i; - } - } - return -1; -} - -int qstrpos(const char *str, const char *key) { -int ssl = strlen(str), ksl = strlen(key); - if(ksl > ssl) return -1; - for(int i = 0; i <= ssl - ksl;) { - uint8 x = str[i]; - if(x == '\"' || x == '\'') { - uint8 z = i++; - while(str[i] != x && i < ssl) i++; - if(i >= ssl) i = z; - } - if(!memcmp(str + i, key, ksl)) { - return i; - } else { - i++; - } - } - return -1; -} - -char* strtr(char *dest, const char *before, const char *after) { -int sl = strlen(dest), bsl = strlen(before), asl = strlen(after); - if(bsl != asl || bsl == 0) return dest; //patterns must be the same length for 1:1 replace - for(int i = 0; i < sl; i++) { - for(int l = 0; l < bsl; l++) { - if(dest[i] == before[l]) { - dest[i] = after[l]; - break; - } - } - } - return dest; -} - -string& strtr(string &dest, const char *before, const char *after) { - strtr(dest(), before, after); - return dest; -} - -bool strbegin(const char *str, const char *key) { -int i, ssl = strlen(str), ksl = strlen(key); - if(ksl > ssl)return false; - return (!memcmp(str, key, ksl)); -} - -bool stribegin(const char *str, const char *key) { -int ssl = strlen(str), ksl = strlen(key); - if(ksl > ssl)return false; - for(int i = 0; i < ksl; i++) { - if(str[i] >= 'A' && str[i] <= 'Z') { - if(str[i] != key[i] && str[i]+0x20 != key[i])return false; - } else if(str[i] >= 'a' && str[i] <= 'z') { - if(str[i] != key[i] && str[i]-0x20 != key[i])return false; - } else { - if(str[i] != key[i])return false; - } - } - return true; -} - -bool strend(const char *str, const char *key) { -int ssl = strlen(str), ksl = strlen(key); - if(ksl > ssl)return false; - return (!memcmp(str + ssl - ksl, key, ksl)); -} - -bool striend(const char *str, const char *key) { -int ssl = strlen(str), ksl = strlen(key); - if(ksl > ssl)return false; - for(int i = ssl - ksl, z = 0; i < ssl; i++, z++) { - if(str[i] >= 'A' && str[i] <= 'Z') { - if(str[i] != key[z] && str[i]+0x20 != key[z])return false; - } else if(str[i] >= 'a' && str[i] <= 'z') { - if(str[i] != key[z] && str[i]-0x20 != key[z])return false; - } else { - if(str[i] != key[z])return false; - } - } - return true; -} - -uint strhex(const char *str) { -uint r = 0, m = 0; -int i = 0, ssl = strlen(str); -uint8 x; -bool negate = (str[0] == '-'); - if(negate)i++; - for(; i < ssl; i++) { - if(str[i] >= '0' && str[i] <= '9'); - else if(str[i] >= 'A' && str[i] <= 'F'); - else if(str[i] >= 'a' && str[i] <= 'f'); - else break; - } - for(--i; i >= 0; i--, m += 4) { - x = str[i]; - if(x >= '0' && x <= '9')x -= '0'; - else if(x >= 'A' && x <= 'F')x -= 'A' - 0x0a; - else if(x >= 'a' && x <= 'f')x -= 'a' - 0x0a; - else break; - r |= x << m; - } - return !negate ? r : (uint)-r; -} - -uint strdec(const char *str) { -uint m = 1; -int i = 0, r = 0, ssl = strlen(str); -uint8 x; -bool negate = (str[0] == '-'); - if(negate)i++; - for(; i < ssl; i++) { - if(str[i] >= '0' && str[i] <= '9'); - else break; - } - for(--i; i >= 0; i--, m *= 10) { - x = str[i]; - if(x >= '0' && x <= '9')x -= '0'; - else break; - r += x * m; - } - return !negate ? r : (uint)-r; -} - -uint strbin(const char *str) { -uint r = 0, m = 0; -int i = 0, ssl = strlen(str); -uint8 x; -bool negate = (str[0] == '-'); - if(negate)i++; - for(; i < ssl; i++) { - if(str[i] == '0' || str[i] == '1'); - else break; - } - for(--i; i >= 0; i--, m++) { - x = str[i]; - if(str[i] == '0' || str[i] == '1')x -= '0'; - else break; - r |= x << m; - } - return !negate ? r : (uint)-r; -} - -string &utoa(string &str, uint num) { - str.reserve(16); - sprintf(str(), "%u", num); - return str; -} - -string &itoa(string &str, uint num) { - str.reserve(16); - sprintf(str(), "%d", num); - return str; -} - -string &htoa(string &str, uint num) { - str.reserve(16); - sprintf(str(), "%x", num); - return str; -} - -string &btoa(string &str, uint num) { - str.reserve(64); - -char *pstr = str(); -uint mask = 0x80000000; - while(mask && (num & mask) == 0)mask >>= 1; - while(mask > 1) { - *pstr++ = (num & mask) ? '1' : '0'; - mask >>= 1; - } - *pstr++ = (num & mask) ? '1' : '0'; - *pstr = 0; - - return str; -} - -bool fread(string &str, const char *filename) { - strcpy(str, ""); - -FILE *fp = fopen(filename, "rb"); - if(!fp)return false; - -uint size = fsize(fp); -char *fdata = (char*)malloc(size + 1); - fread(fdata, 1, size, fp); - fclose(fp); - fdata[size] = 0; - strcpy(str, fdata); - free(fdata); - - return true; -} - -#endif //ifdef BSTRING_H diff --git a/src/lib/bstring/bstring.split.cpp b/src/lib/bstring/bstring.split.cpp deleted file mode 100644 index 24436f77..00000000 --- a/src/lib/bstring/bstring.split.cpp +++ /dev/null @@ -1,39 +0,0 @@ -#ifdef BSTRING_H - -void split(lstring &dest, const char *key, const char *src) { - dest.reset(); - -int ssl = strlen(src), ksl = strlen(key); -int lp = 0, split_count = 0; - for(int i = 0; i <= ssl - ksl;) { - if(!memcmp(src + i, key, ksl)) { - strlcpy(dest[split_count++], src + lp, i - lp + 1); - i += ksl; - lp = i; - } else i++; - } - strcpy(dest[split_count++], src + lp); -} - -void qsplit(lstring &dest, const char *key, const char *src) { - dest.reset(); - -int z, ssl = strlen(src), ksl = strlen(key); -int lp = 0, split_count = 0; - for(int i = 0; i <= ssl - ksl;) { - uint8 x = src[i]; - if(x == '\"' || x == '\'') { - z = i++; - while(src[i] != x && i < ssl)i++; - if(i >= ssl)i = z; - } - if(!memcmp(src + i, key, ksl)) { - strlcpy(dest[split_count++], src + lp, i - lp + 1); - i += ksl; - lp = i; - } else i++; - } - strcpy(dest[split_count++], src + lp); -} - -#endif //ifdef BSTRING_H diff --git a/src/lib/bstring/bstring.strl.cpp b/src/lib/bstring/bstring.strl.cpp deleted file mode 100644 index 33c4e1f8..00000000 --- a/src/lib/bstring/bstring.strl.cpp +++ /dev/null @@ -1,31 +0,0 @@ -#ifdef BSTRING_H - -uint strlcpy(char *dest, const char *src, uint length) { -uint srclen = strlen(src); - length--; - if(length > srclen) length = srclen; - memcpy(dest, src, length); - dest[length] = 0; - return srclen; -} - -uint strlcat(char *dest, const char *src, uint length) { -uint destlen = strlen(dest), srclen = strlen(src); - length--; - if(length > destlen + srclen) length = destlen + srclen; - memcpy(dest + destlen, src, length - destlen); - dest[length] = 0; - return destlen + srclen; -} - -uint strlcpy(string &dest, const char *src, uint length) { - dest.reserve(length); - return strlcpy(dest(), src, length); -} - -uint strlcat(string &dest, const char *src, uint length) { - dest.reserve(length); - return strlcat(dest(), src, length); -} - -#endif //ifdef BSTRING_H diff --git a/src/lib/bstring/bstring.trim.cpp b/src/lib/bstring/bstring.trim.cpp deleted file mode 100644 index 59ba3c1a..00000000 --- a/src/lib/bstring/bstring.trim.cpp +++ /dev/null @@ -1,39 +0,0 @@ -#ifdef BSTRING_H - -char* ltrim(char *str, const char *key) { - if(!key || !*key) return str; - while(strbegin(str, key)) { - string temp = str; - strcpy(str, temp() + strlen(key)); - } - return str; -} - -char* rtrim(char *str, const char *key) { - if(!key || !*key) return str; - while(strend(str, key)) { - str[strlen(str) - strlen(key)] = 0; - } - return str; -} - -char* trim(char *str, const char *key) { - return ltrim(rtrim(str, key), key); -} - -string& ltrim(string &str, const char *key) { - ltrim(str(), key); - return str; -} - -string& rtrim(string &str, const char *key) { - rtrim(str(), key); - return str; -} - -string& trim(string &str, const char *key) { - trim(str(), key); - return str; -} - -#endif //ifdef BSTRING_H diff --git a/src/lib/miu.cpp b/src/lib/hiro.cpp similarity index 84% rename from src/lib/miu.cpp rename to src/lib/hiro.cpp index 56208806..7dca8509 100644 --- a/src/lib/miu.cpp +++ b/src/lib/hiro.cpp @@ -1,21 +1,28 @@ -#include "miu.h" +#include +using namespace nall; -namespace ns_miu { +#if defined(_WIN32) + #include +#else + #include +#endif -/* Miu (singleton) */ +namespace libhiro { -void Miu::init() { p.init(); } -void Miu::term() { p.term(); } -bool Miu::run() { return p.run(); } -bool Miu::pending() { return p.pending(); } -bool Miu::file_load(Window *focus, char *filename, const char *filter, const char *path) { return p.file_load(focus, filename, filter, path); } -bool Miu::file_save(Window *focus, char *filename, const char *filter, const char *path) { return p.file_save(focus, filename, filter, path); } -uint Miu::screen_width() { return p.screen_width(); } -uint Miu::screen_height() { return p.screen_height(); } -Miu& Miu::handle() { static Miu miu; return miu; } -Miu::Miu() : p(*new pMiu(*this)) {} -Miu::~Miu() { delete &p; } -Miu& miu() { return Miu::handle(); } +/* Hiro (singleton) */ + +void Hiro::init() { p.init(); } +void Hiro::term() { p.term(); } +bool Hiro::run() { return p.run(); } +bool Hiro::pending() { return p.pending(); } +bool Hiro::file_load(Window *focus, char *filename, const char *filter, const char *path) { return p.file_load(focus, filename, filter, path); } +bool Hiro::file_save(Window *focus, char *filename, const char *filter, const char *path) { return p.file_save(focus, filename, filter, path); } +uint Hiro::screen_width() { return p.screen_width(); } +uint Hiro::screen_height() { return p.screen_height(); } +Hiro& Hiro::handle() { static Hiro hiro; return hiro; } +Hiro::Hiro() : p(*new pHiro(*this)) {} +Hiro::~Hiro() { delete &p; } +Hiro& hiro() { return Hiro::handle(); } /* Widget */ @@ -37,24 +44,33 @@ void Window::focus() { p.focus(); } bool Window::focused() { return p.focused(); } void Window::fullscreen() { p.fullscreen(); } void Window::unfullscreen() { p.unfullscreen(); } -void Window::set_background_color(uint8 r, uint8 g, uint8 b) { p.set_background_color(r, g, b); } +uint Window::get_width() { return p.get_width(); } +uint Window::get_height() { return p.get_height(); } +void Window::set_background_color(uint8_t r, uint8_t g, uint8_t b) { p.set_background_color(r, g, b); } void Window::set_text(const char *text) { p.set_text(text); } void Window::attach(Window &window, uint x, uint y) { p.attach(window, x, y); } void Window::attach(MenuGroup &menugroup) { p.attach(menugroup); } void Window::attach(FormControl &formcontrol, uint x, uint y) { p.attach(formcontrol, x, y); } void Window::move(Window &window, uint x, uint y) { p.move(window, x, y); } void Window::move(FormControl &formcontrol, uint x, uint y) { p.move(formcontrol, x, y); } -void Window::menu_show(bool state) { p.menu_show(state); } -void Window::menu_hide() { p.menu_hide(); } -bool Window::menu_visible() { return p.menu_visible(); } + +void Window::Menubar::show(bool state) { p.menu.show(state); } +void Window::Menubar::hide() { p.menu.hide(); } +bool Window::Menubar::visible() { return p.menu.visible(); } +Window::Menubar::Menubar(pWindow &p_) : p(p_) {} + +void Window::Statusbar::set_text(const char *text) { p.status.set_text(text); } +void Window::Statusbar::show(bool state) { p.status.show(state); } +void Window::Statusbar::hide() { p.status.hide(); } +bool Window::Statusbar::visible() { return p.status.visible(); } +Window::Statusbar::Statusbar(pWindow &p_) : p(p_) {} + Window::Window() : base_from_member(*new pWindow(*this)), Widget(base_from_member::value), - p(base_from_member::value) { type = WindowType; } -Window::Window(pWindow &p_) : - base_from_member(p_), - Widget(base_from_member::value), - p(base_from_member::value) { type = WindowType; } + p(base_from_member::value), + menu(base_from_member::value), + status(base_from_member::value) { type = WindowType; } /* Widget -> MenuControl */ @@ -146,7 +162,7 @@ Frame::Frame() : void Canvas::create(uint style, uint width, uint height) { p.create(style, width, height); } void Canvas::redraw() { p.redraw(); } -uint32* Canvas::buffer() { return p.buffer(); } +uint32_t* Canvas::buffer() { return p.buffer(); } Canvas::Canvas() : base_from_member(*new pCanvas(*this)), FormControl(base_from_member::value), @@ -250,4 +266,4 @@ Slider::Slider() : FormControl(base_from_member::value), p(base_from_member::value) { type = SliderType; } -} //namespace ns_miu +} //namespace libhiro diff --git a/src/lib/miu.h b/src/lib/hiro.h similarity index 69% rename from src/lib/miu.h rename to src/lib/hiro.h index 8ce90101..069797fc 100644 --- a/src/lib/miu.h +++ b/src/lib/hiro.h @@ -1,22 +1,24 @@ /* - miu - version: 0.012 (2007-12-22) + hiro + version: 0.001 (2008-02-03) author: byuu license: public domain */ -#ifndef MIU_H -#define MIU_H +#ifndef HIRO_H +#define HIRO_H -#include "bbase.h" -#include "barray.h" -#include "bfunction.h" -#include "bkeymap.h" -#include "bstring.h" +#include +#include +#include +#include +#include +#include +typedef unsigned int uint; -namespace ns_miu { +namespace libhiro { -class pMiu; +class pHiro; class pWidget; class pWindow; class pMenuControl; @@ -39,7 +41,7 @@ class pWidget; class pSlider; #define pFriends \ - friend class pMiu; \ + friend class pHiro; \ friend class pWidget; \ friend class pWindow; \ friend class pMenuControl; \ @@ -61,7 +63,7 @@ class pWidget; friend class pProgressbar; \ friend class pSlider -class Miu; +class Hiro; class Widget; class Window; class MenuControl; @@ -83,8 +85,8 @@ class Widget; class Progressbar; class Slider; -typedef array MenuRadioItemGroup; -typedef array RadioboxGroup; +typedef nall::array MenuRadioItemGroup; +typedef nall::array RadioboxGroup; struct Event { enum Type { @@ -103,7 +105,7 @@ struct Event { type(type_), param(param_), widget(widget_) {} }; -class Miu : noncopyable { +class Hiro : nall::noncopyable { public: void init(); void term(); @@ -116,18 +118,18 @@ public: uint screen_width(); uint screen_height(); - static Miu& handle(); - Miu(); - ~Miu(); + static Hiro& handle(); + Hiro(); + ~Hiro(); private: pFriends; - pMiu &p; + pHiro &p; }; -Miu& miu(); +Hiro& hiro(); -class Widget : noncopyable { +class Widget : nall::noncopyable { public: enum Type { WidgetType, @@ -169,7 +171,7 @@ private: pWidget &p; }; -class Window : private base_from_member, public Widget { +class Window : private nall::base_from_member, public Widget { public: enum Style { AutoCenter = 1 << 1, @@ -183,33 +185,51 @@ public: bool focused(); void fullscreen(); void unfullscreen(); - void set_background_color(uint8 r, uint8 g, uint8 b); + uint get_width(); + uint get_height(); + void set_background_color(uint8_t r, uint8_t g, uint8_t b); + void set_status_text(const char *text = ""); void set_text(const char *text = ""); void attach(Window &window, uint x, uint y); void attach(MenuGroup &menugroup); void attach(FormControl &formcontrol, uint x, uint y); void move(Window &window, uint x, uint y); void move(FormControl &formcontrol, uint x, uint y); - void menu_show(bool = true); - void menu_hide(); - bool menu_visible(); - function on_close; - function on_block; - function on_keydown; - function on_keyup; + class Menubar { + public: + void show(bool = true); + void hide(); + bool visible(); + + pWindow &p; + Menubar(pWindow&); + } menu; + + class Statusbar { + public: + void set_text(const char *text = ""); + void show(bool = true); + void hide(); + bool visible(); + + pWindow &p; + Statusbar(pWindow&); + } status; + + nall::function on_close; + nall::function on_block; + nall::function on_keydown; + nall::function on_keyup; Window(); -protected: - Window(pWindow&); - private: pFriends; pWindow &p; }; -class MenuControl : public base_from_member, public Widget { +class MenuControl : public nall::base_from_member, public Widget { public: void enable(bool = true); void disable(); @@ -225,7 +245,7 @@ private: pMenuControl &p; }; -class MenuGroup : public base_from_member, public MenuControl { +class MenuGroup : public nall::base_from_member, public MenuControl { public: MenuGroup& create(const char *text); void attach(MenuControl &menucontrol); @@ -236,19 +256,19 @@ private: pMenuGroup &p; }; -class MenuItem : public base_from_member, public MenuControl { +class MenuItem : public nall::base_from_member, public MenuControl { public: MenuItem& create(const char *text); MenuItem(); - function on_tick; + nall::function on_tick; private: pFriends; pMenuItem &p; }; -class MenuCheckItem : public base_from_member, public MenuControl { +class MenuCheckItem : public nall::base_from_member, public MenuControl { public: MenuCheckItem& create(const char *text); void check(bool = true); @@ -256,28 +276,28 @@ public: bool checked(); MenuCheckItem(); - function on_tick; + nall::function on_tick; private: pFriends; pMenuCheckItem &p; }; -class MenuRadioItem : public base_from_member, public MenuControl { +class MenuRadioItem : public nall::base_from_member, public MenuControl { public: MenuRadioItem& create(MenuRadioItemGroup &group, const char *text); void check(); bool checked(); MenuRadioItem(); - function on_tick; + nall::function on_tick; private: pFriends; pMenuRadioItem &p; }; -class MenuSeparator : public base_from_member, public MenuControl { +class MenuSeparator : public nall::base_from_member, public MenuControl { public: MenuSeparator& create(); MenuSeparator(); @@ -287,7 +307,7 @@ private: pMenuSeparator &p; }; -class FormControl : private base_from_member, public Widget { +class FormControl : private nall::base_from_member, public Widget { public: void resize(uint width, uint height); void focus(); @@ -306,7 +326,7 @@ private: pFormControl &p; }; -class Frame : private base_from_member, public FormControl { +class Frame : private nall::base_from_member, public FormControl { public: void create(uint style, uint width, uint height, const char *text = ""); void set_text(const char *text = ""); @@ -318,11 +338,11 @@ private: pFrame &p; }; -class Canvas : private base_from_member, public FormControl { +class Canvas : private nall::base_from_member, public FormControl { public: void create(uint style, uint width, uint height); void redraw(); - uint32* buffer(); + uint32_t* buffer(); Canvas(); @@ -331,7 +351,7 @@ private: pCanvas &p; }; -class Label : private base_from_member, public FormControl { +class Label : private nall::base_from_member, public FormControl { public: void create(uint style, uint width, uint height, const char *text = ""); void set_text(const char *text = ""); @@ -343,12 +363,12 @@ private: pLabel &p; }; -class Button : private base_from_member, public FormControl { +class Button : private nall::base_from_member, public FormControl { public: void create(uint style, uint width, uint height, const char *text = ""); void set_text(const char *text = ""); - function on_tick; + nall::function on_tick; Button(); @@ -357,7 +377,7 @@ private: pButton &p; }; -class Checkbox : private base_from_member, public FormControl { +class Checkbox : private nall::base_from_member, public FormControl { public: void create(uint style, uint width, uint height, const char *text = ""); void set_text(const char *text = ""); @@ -365,7 +385,7 @@ public: void uncheck(); bool checked(); - function on_tick; + nall::function on_tick; Checkbox(); @@ -374,14 +394,14 @@ private: pCheckbox &p; }; -class Radiobox : private base_from_member, public FormControl { +class Radiobox : private nall::base_from_member, public FormControl { public: void create(RadioboxGroup &group, uint style, uint width, uint height, const char *text = ""); void set_text(const char *text = ""); void check(); bool checked(); - function on_tick; + nall::function on_tick; Radiobox(); @@ -390,7 +410,7 @@ private: pRadiobox &p; }; -class Editbox : private base_from_member, public FormControl { +class Editbox : private nall::base_from_member, public FormControl { public: enum Style { Multiline = 1 << 1, @@ -416,7 +436,7 @@ private: pEditbox &p; }; -class Listbox : private base_from_member, public FormControl { +class Listbox : private nall::base_from_member, public FormControl { public: enum Style { Header = 1 << 1, @@ -439,8 +459,8 @@ public: void set_selection(int index); void reset(); - function on_change; - function on_activate; + nall::function on_change; + nall::function on_activate; Listbox(); @@ -449,7 +469,7 @@ private: pListbox &p; }; -class Combobox : private base_from_member, public FormControl { +class Combobox : private nall::base_from_member, public FormControl { public: void create(uint style, uint width, uint height, const char *text = ""); void add_item(const char *text); @@ -457,7 +477,7 @@ public: void set_selection(int index); void reset(); - function on_change; + nall::function on_change; Combobox(); @@ -466,7 +486,7 @@ private: pCombobox &p; }; -class Progressbar : private base_from_member, public FormControl { +class Progressbar : private nall::base_from_member, public FormControl { public: void create(uint style, uint width, uint height); uint get_progress(); @@ -479,7 +499,7 @@ private: pProgressbar &p; }; -class Slider : private base_from_member, public FormControl { +class Slider : private nall::base_from_member, public FormControl { public: enum Style { Horizontal = 0, @@ -490,7 +510,7 @@ public: uint get_position(); void set_position(uint position); - function on_change; + nall::function on_change; Slider(); @@ -501,6 +521,6 @@ private: #undef pFriends -} //namespace ns_miu +} //namespace libhiro -#endif //ifndef MIU_H +#endif //ifndef HIRO_H diff --git a/src/lib/miu.gtk/miu.gtk.button.cpp b/src/lib/hiro_gtk/button.cpp similarity index 89% rename from src/lib/miu.gtk/miu.gtk.button.cpp rename to src/lib/hiro_gtk/button.cpp index 06523dac..4c76fcd7 100644 --- a/src/lib/miu.gtk/miu.gtk.button.cpp +++ b/src/lib/hiro_gtk/button.cpp @@ -1,4 +1,4 @@ -void miu_pbutton_tick(pButton *p) { +void hiro_pbutton_tick(pButton *p) { if(p->self.on_tick) p->self.on_tick(Event(Event::Tick, 0, &p->self)); } @@ -6,7 +6,7 @@ void pButton::create(uint style, uint width, uint height, const char *text) { button = gtk_button_new_with_label(text ? text : ""); gtk_widget_set_size_request(button, width, height); gtk_widget_show(button); - g_signal_connect_swapped(G_OBJECT(button), "clicked", G_CALLBACK(miu_pbutton_tick), (gpointer)this); + g_signal_connect_swapped(G_OBJECT(button), "clicked", G_CALLBACK(hiro_pbutton_tick), (gpointer)this); } void pButton::set_text(const char *text) { diff --git a/src/lib/miu.gtk/miu.gtk.button.h b/src/lib/hiro_gtk/button.h similarity index 93% rename from src/lib/miu.gtk/miu.gtk.button.h rename to src/lib/hiro_gtk/button.h index 10bab078..0e0790f6 100644 --- a/src/lib/miu.gtk/miu.gtk.button.h +++ b/src/lib/hiro_gtk/button.h @@ -6,7 +6,7 @@ public: pButton(Button&); -/* internal */ + /* internal */ GtkWidget *button; GtkWidget* gtk_handle(); }; diff --git a/src/lib/miu.gtk/miu.gtk.canvas.cpp b/src/lib/hiro_gtk/canvas.cpp similarity index 73% rename from src/lib/miu.gtk/miu.gtk.canvas.cpp rename to src/lib/hiro_gtk/canvas.cpp index 42454289..5351bab4 100644 --- a/src/lib/miu.gtk/miu.gtk.canvas.cpp +++ b/src/lib/hiro_gtk/canvas.cpp @@ -1,9 +1,9 @@ -void miu_pcanvas_expose(pCanvas *p) { -uint32 *f = p->fbuffer; -uint32 *r = p->rbuffer; +void hiro_pcanvas_expose(pCanvas *p) { +uint32_t *f = p->fbuffer; +uint32_t *r = p->rbuffer; for(uint y = p->canvas->allocation.height; y; y--) { for(uint x = p->canvas->allocation.width; x; x--) { - uint32 p = *f++; + uint32_t p = *f++; *r++ = ((p << 16) & 0xff0000) + (p & 0x00ff00) + ((p >> 16) & 0x0000ff); } } @@ -17,12 +17,12 @@ uint32 *r = p->rbuffer; void pCanvas::create(uint style, uint width, uint height) { canvas = gtk_drawing_area_new(); resize(width, height); -GdkColor color; + GdkColor color; color.pixel = color.red = color.green = color.blue = 0; gtk_widget_modify_bg(canvas, GTK_STATE_NORMAL, &color); + gtk_widget_set_double_buffered(canvas, false); gtk_widget_show(canvas); - - g_signal_connect_swapped(G_OBJECT(canvas), "expose_event", G_CALLBACK(miu_pcanvas_expose), (gpointer)this); + g_signal_connect_swapped(G_OBJECT(canvas), "expose_event", G_CALLBACK(hiro_pcanvas_expose), (gpointer)this); } void pCanvas::redraw() { @@ -36,7 +36,7 @@ GdkRectangle rect; gdk_window_invalidate_rect(canvas->window, &rect, true); } -uint32* pCanvas::buffer() { +uint32_t* pCanvas::buffer() { return fbuffer; } @@ -48,19 +48,19 @@ pCanvas::pCanvas(Canvas &self_) : pFormControl(self_), self(self_) { } pCanvas::~pCanvas() { - safe_free(fbuffer); - safe_free(rbuffer); + if(fbuffer) free(fbuffer); + if(rbuffer) free(rbuffer); } /* internal */ void pCanvas::resize(uint width, uint height) { - safe_free(fbuffer); - safe_free(rbuffer); + if(fbuffer) free(fbuffer); + if(rbuffer) free(rbuffer); - bpitch = width * sizeof(uint32); - fbuffer = (uint32*)malloc(bpitch * height); - rbuffer = (uint32*)malloc(bpitch * height); + bpitch = width * sizeof(uint32_t); + fbuffer = (uint32_t*)malloc(bpitch * height); + rbuffer = (uint32_t*)malloc(bpitch * height); memset(fbuffer, 0, bpitch * height); memset(rbuffer, 0, bpitch * height); diff --git a/src/lib/miu.gtk/miu.gtk.canvas.h b/src/lib/hiro_gtk/canvas.h similarity index 56% rename from src/lib/miu.gtk/miu.gtk.canvas.h rename to src/lib/hiro_gtk/canvas.h index 5e334e93..08197897 100644 --- a/src/lib/miu.gtk/miu.gtk.canvas.h +++ b/src/lib/hiro_gtk/canvas.h @@ -2,17 +2,17 @@ class pCanvas : public pFormControl { public: void create(uint style, uint width, uint height); void redraw(); - uint32* buffer(); + uint32_t* buffer(); Canvas &self; pCanvas(Canvas&); ~pCanvas(); -/* internal */ + /* internal */ GtkWidget *canvas; -//GTK+ RGB drawing function draws in xBGR format, so two buffers are needed ... - uint32 *fbuffer; //one for the xRGB image - uint32 *rbuffer; //one for the xBGR image + //GTK+ RGB drawing function draws in xBGR format, so two buffers are needed ... + uint32_t *fbuffer; //one for the xRGB image + uint32_t *rbuffer; //one for the xBGR image uint bpitch; void resize(uint width, uint height); GtkWidget* gtk_handle(); diff --git a/src/lib/miu.gtk/miu.gtk.checkbox.cpp b/src/lib/hiro_gtk/checkbox.cpp similarity index 91% rename from src/lib/miu.gtk/miu.gtk.checkbox.cpp rename to src/lib/hiro_gtk/checkbox.cpp index 17012664..f7770d90 100644 --- a/src/lib/miu.gtk/miu.gtk.checkbox.cpp +++ b/src/lib/hiro_gtk/checkbox.cpp @@ -1,4 +1,4 @@ -void miu_pcheckbox_tick(pCheckbox *p) { +void hiro_pcheckbox_tick(pCheckbox *p) { if(p->self.on_tick) p->self.on_tick(Event(Event::Tick, p->checked(), &p->self)); } @@ -6,7 +6,7 @@ void pCheckbox::create(uint style, uint width, uint height, const char *text) { checkbox = gtk_check_button_new_with_label(text ? text : ""); gtk_widget_set_size_request(checkbox, width, height); gtk_widget_show(checkbox); - g_signal_connect_swapped(G_OBJECT(checkbox), "toggled", G_CALLBACK(miu_pcheckbox_tick), (gpointer)this); + g_signal_connect_swapped(G_OBJECT(checkbox), "toggled", G_CALLBACK(hiro_pcheckbox_tick), (gpointer)this); } void pCheckbox::set_text(const char *text) { diff --git a/src/lib/miu.gtk/miu.gtk.checkbox.h b/src/lib/hiro_gtk/checkbox.h similarity index 95% rename from src/lib/miu.gtk/miu.gtk.checkbox.h rename to src/lib/hiro_gtk/checkbox.h index c22b8496..bf3cbb3d 100644 --- a/src/lib/miu.gtk/miu.gtk.checkbox.h +++ b/src/lib/hiro_gtk/checkbox.h @@ -9,7 +9,7 @@ public: Checkbox &self; pCheckbox(Checkbox&); -/* internal */ + /* internal */ GtkWidget *checkbox; GtkWidget* gtk_handle(); }; diff --git a/src/lib/miu.gtk/miu.gtk.combobox.cpp b/src/lib/hiro_gtk/combobox.cpp similarity index 92% rename from src/lib/miu.gtk/miu.gtk.combobox.cpp rename to src/lib/hiro_gtk/combobox.cpp index f7d1012b..6166d0e5 100644 --- a/src/lib/miu.gtk/miu.gtk.combobox.cpp +++ b/src/lib/hiro_gtk/combobox.cpp @@ -1,4 +1,4 @@ -void miu_pcombobox_change(pCombobox *p) { +void hiro_pcombobox_change(pCombobox *p) { if(p->self.on_change) p->self.on_change(Event(Event::Change, p->get_selection(), &p->self)); } @@ -7,7 +7,7 @@ void pCombobox::create(uint style, uint width, uint height, const char *text) { gtk_widget_set_size_request(combobox, width, height); gtk_widget_show(combobox); - g_signal_connect_swapped(G_OBJECT(combobox), "changed", G_CALLBACK(miu_pcombobox_change), (gpointer)this); + g_signal_connect_swapped(G_OBJECT(combobox), "changed", G_CALLBACK(hiro_pcombobox_change), (gpointer)this); } void pCombobox::add_item(const char *text) { diff --git a/src/lib/miu.gtk/miu.gtk.combobox.h b/src/lib/hiro_gtk/combobox.h similarity index 95% rename from src/lib/miu.gtk/miu.gtk.combobox.h rename to src/lib/hiro_gtk/combobox.h index 7a209027..e69986f4 100644 --- a/src/lib/miu.gtk/miu.gtk.combobox.h +++ b/src/lib/hiro_gtk/combobox.h @@ -9,7 +9,7 @@ public: Combobox &self; pCombobox(Combobox&); -/* internal */ + /* internal */ GtkWidget *combobox; uint counter; GtkWidget* gtk_handle(); diff --git a/src/lib/miu.gtk/miu.gtk.editbox.cpp b/src/lib/hiro_gtk/editbox.cpp similarity index 100% rename from src/lib/miu.gtk/miu.gtk.editbox.cpp rename to src/lib/hiro_gtk/editbox.cpp diff --git a/src/lib/miu.gtk/miu.gtk.editbox.h b/src/lib/hiro_gtk/editbox.h similarity index 95% rename from src/lib/miu.gtk/miu.gtk.editbox.h rename to src/lib/hiro_gtk/editbox.h index 682f2ce1..325e4704 100644 --- a/src/lib/miu.gtk/miu.gtk.editbox.h +++ b/src/lib/hiro_gtk/editbox.h @@ -7,7 +7,7 @@ public: pEditbox(Editbox&); -/* internal */ + /* internal */ GtkWidget *scrollbox; GtkWidget *editbox; GtkTextBuffer *buffer; diff --git a/src/lib/miu.gtk/miu.gtk.formcontrol.cpp b/src/lib/hiro_gtk/formcontrol.cpp similarity index 100% rename from src/lib/miu.gtk/miu.gtk.formcontrol.cpp rename to src/lib/hiro_gtk/formcontrol.cpp diff --git a/src/lib/miu.gtk/miu.gtk.formcontrol.h b/src/lib/hiro_gtk/formcontrol.h similarity index 94% rename from src/lib/miu.gtk/miu.gtk.formcontrol.h rename to src/lib/hiro_gtk/formcontrol.h index b775632b..f0b025bc 100644 --- a/src/lib/miu.gtk/miu.gtk.formcontrol.h +++ b/src/lib/hiro_gtk/formcontrol.h @@ -10,6 +10,6 @@ public: FormControl &self; pFormControl(FormControl&); -/* internal */ + /* internal */ virtual GtkWidget* gtk_handle(); }; diff --git a/src/lib/miu.gtk/miu.gtk.frame.cpp b/src/lib/hiro_gtk/frame.cpp similarity index 100% rename from src/lib/miu.gtk/miu.gtk.frame.cpp rename to src/lib/hiro_gtk/frame.cpp diff --git a/src/lib/miu.gtk/miu.gtk.frame.h b/src/lib/hiro_gtk/frame.h similarity index 93% rename from src/lib/miu.gtk/miu.gtk.frame.h rename to src/lib/hiro_gtk/frame.h index 446f016e..d2770706 100644 --- a/src/lib/miu.gtk/miu.gtk.frame.h +++ b/src/lib/hiro_gtk/frame.h @@ -6,7 +6,7 @@ public: pFrame(Frame&); -/* internal */ + /* internal */ GtkWidget *frame; GtkWidget* gtk_handle(); }; diff --git a/src/lib/hiro_gtk/hiro.cpp b/src/lib/hiro_gtk/hiro.cpp new file mode 100644 index 00000000..3b64799e --- /dev/null +++ b/src/lib/hiro_gtk/hiro.cpp @@ -0,0 +1,121 @@ +#include "hiro.h" + +#include +using nall::min; +using nall::max; + +namespace libhiro { + +#include "keymap.cpp" +#include "widget.cpp" + #include "window.cpp" + #include "menucontrol.cpp" + #include "menugroup.cpp" + #include "menuitem.cpp" + #include "menucheckitem.cpp" + #include "menuradioitem.cpp" + #include "menuseparator.cpp" + #include "formcontrol.cpp" + #include "frame.cpp" + #include "canvas.cpp" + #include "label.cpp" + #include "button.cpp" + #include "checkbox.cpp" + #include "radiobox.cpp" + #include "editbox.cpp" + #include "listbox.cpp" + #include "combobox.cpp" + #include "progressbar.cpp" + #include "slider.cpp" + +void pHiro::init() { + //simulate passing argc, argv to gtk_init() + int argc = 1; + char **argv; + argv = (char**)malloc(1 * sizeof(char*)); + argv[0] = (char*)malloc(64 * sizeof(char)); + strcpy(argv[0], "./hiro"); + gtk_init(&argc, &argv); + free(argv[0]); + free(argv); +} + +void pHiro::term() { +} + +bool pHiro::run() { + gtk_main_iteration_do(false); + return pending(); +} + +bool pHiro::pending() { + return gtk_events_pending(); +} + +bool pHiro::file_load(Window *focus, char *filename, const char *filter, const char *path) { + if(!filename) return false; + strcpy(filename, ""); + + GtkWidget *dialog = gtk_file_chooser_dialog_new("Load File", + focus ? GTK_WINDOW(focus->p.gtk_handle()) : (GtkWindow*)0, + GTK_FILE_CHOOSER_ACTION_OPEN, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, + (const gchar*)0); + + if(path && *path) gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), path); + + if(gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { + char *fn = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); + strcpy(filename, fn); + g_free(fn); + } + + gtk_widget_destroy(dialog); + return strcmp(filename, ""); //return true if filename exists +} + +bool pHiro::file_save(Window *focus, char *filename, const char *filter, const char *path) { + if(!filename) return false; + strcpy(filename, ""); + + GtkWidget *dialog = gtk_file_chooser_dialog_new("Save File", + focus ? GTK_WINDOW(focus->p.gtk_handle()) : (GtkWindow*)0, + GTK_FILE_CHOOSER_ACTION_SAVE, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, + (const gchar*)0); + + if(path && *path) gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), path); + gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), TRUE); + + if(gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { + char *fn = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); + strcpy(filename, fn); + g_free(fn); + } + + gtk_widget_destroy(dialog); + return strcmp(filename, ""); //return true if filename exists +} + +uint pHiro::screen_width() { + return gdk_screen_width(); +} + +uint pHiro::screen_height() { + return gdk_screen_height(); +} + +pHiro& pHiro::handle() { + return hiro().p; +} + +pHiro::pHiro(Hiro &self_) : self(self_) { +} + +pHiro& phiro() { + return pHiro::handle(); +} + +} //namespace libhiro diff --git a/src/lib/hiro_gtk/hiro.h b/src/lib/hiro_gtk/hiro.h new file mode 100644 index 00000000..79160626 --- /dev/null +++ b/src/lib/hiro_gtk/hiro.h @@ -0,0 +1,56 @@ +#ifndef HIRO_GTK_H +#define HIRO_GTK_H + +#include +#include +#include + +namespace libhiro { + +#include "widget.h" + #include "window.h" + #include "menucontrol.h" + #include "menugroup.h" + #include "menuitem.h" + #include "menucheckitem.h" + #include "menuradioitem.h" + #include "menuseparator.h" + #include "formcontrol.h" + #include "frame.h" + #include "canvas.h" + #include "label.h" + #include "button.h" + #include "checkbox.h" + #include "radiobox.h" + #include "editbox.h" + #include "listbox.h" + #include "combobox.h" + #include "progressbar.h" + #include "slider.h" + +class pHiro { +public: + Hiro &self; + void init(); + void term(); + bool run(); + bool pending(); + + bool file_load(Window *focus, char *filename, const char *filter, const char *path); + bool file_save(Window *focus, char *filename, const char *filter, const char *path); + + uint screen_width(); + uint screen_height(); + + static pHiro& handle(); + pHiro(Hiro&); + + /* internal */ + uint16_t translate_key(uint key); +}; + +pHiro& phiro(); + +} //namespace libhiro + +#endif //ifndef HIRO_GTK_H diff --git a/src/lib/hiro_gtk/keymap.cpp b/src/lib/hiro_gtk/keymap.cpp new file mode 100644 index 00000000..ae7700a5 --- /dev/null +++ b/src/lib/hiro_gtk/keymap.cpp @@ -0,0 +1,188 @@ +uint16_t pHiro::translate_key(uint key) { + switch(key) { + case GDK_Escape: return keyboard::escape; + + case GDK_F1: return keyboard::f1; + case GDK_F2: return keyboard::f2; + case GDK_F3: return keyboard::f3; + case GDK_F4: return keyboard::f4; + case GDK_F5: return keyboard::f5; + case GDK_F6: return keyboard::f6; + case GDK_F7: return keyboard::f7; + case GDK_F8: return keyboard::f8; + case GDK_F9: return keyboard::f9; + case GDK_F10: return keyboard::f10; + case GDK_F11: return keyboard::f11; + case GDK_F12: return keyboard::f12; + + case GDK_Print: return keyboard::print_screen; + case GDK_Sys_Req: return keyboard::print_screen; + case GDK_Scroll_Lock: return keyboard::scroll_lock; + case GDK_Pause: return keyboard::pause; + case GDK_Break: return keyboard::pause; + + case GDK_grave: return keyboard::tilde; + case GDK_asciitilde: return keyboard::tilde; + + case GDK_1: return keyboard::num_1; + case GDK_2: return keyboard::num_2; + case GDK_3: return keyboard::num_3; + case GDK_4: return keyboard::num_4; + case GDK_5: return keyboard::num_5; + case GDK_6: return keyboard::num_6; + case GDK_7: return keyboard::num_7; + case GDK_8: return keyboard::num_8; + case GDK_9: return keyboard::num_9; + case GDK_0: return keyboard::num_0; + + case GDK_exclam: return keyboard::num_1; + case GDK_at: return keyboard::num_2; + case GDK_numbersign: return keyboard::num_3; + case GDK_dollar: return keyboard::num_4; + case GDK_percent: return keyboard::num_5; + case GDK_asciicircum: return keyboard::num_6; + case GDK_ampersand: return keyboard::num_7; + case GDK_asterisk: return keyboard::num_8; + case GDK_parenleft: return keyboard::num_9; + case GDK_parenright: return keyboard::num_0; + + case GDK_minus: return keyboard::dash; + case GDK_underscore: return keyboard::dash; + case GDK_equal: return keyboard::equal; + case GDK_plus: return keyboard::equal; + case GDK_BackSpace: return keyboard::backspace; + + case GDK_Insert: return keyboard::insert; + case GDK_Delete: return keyboard::delete_; + case GDK_Home: return keyboard::home; + case GDK_End: return keyboard::end; + case GDK_Page_Up: return keyboard::page_up; + case GDK_Page_Down: return keyboard::page_down; + + case GDK_a: return keyboard::a; + case GDK_b: return keyboard::b; + case GDK_c: return keyboard::c; + case GDK_d: return keyboard::d; + case GDK_e: return keyboard::e; + case GDK_f: return keyboard::f; + case GDK_g: return keyboard::g; + case GDK_h: return keyboard::h; + case GDK_i: return keyboard::i; + case GDK_j: return keyboard::j; + case GDK_k: return keyboard::k; + case GDK_l: return keyboard::l; + case GDK_m: return keyboard::m; + case GDK_n: return keyboard::n; + case GDK_o: return keyboard::o; + case GDK_p: return keyboard::p; + case GDK_q: return keyboard::q; + case GDK_r: return keyboard::r; + case GDK_s: return keyboard::s; + case GDK_t: return keyboard::t; + case GDK_u: return keyboard::u; + case GDK_v: return keyboard::v; + case GDK_w: return keyboard::w; + case GDK_x: return keyboard::x; + case GDK_y: return keyboard::y; + case GDK_z: return keyboard::z; + + case GDK_A: return keyboard::a; + case GDK_B: return keyboard::b; + case GDK_C: return keyboard::c; + case GDK_D: return keyboard::d; + case GDK_E: return keyboard::e; + case GDK_F: return keyboard::f; + case GDK_G: return keyboard::g; + case GDK_H: return keyboard::h; + case GDK_I: return keyboard::i; + case GDK_J: return keyboard::j; + case GDK_K: return keyboard::k; + case GDK_L: return keyboard::l; + case GDK_M: return keyboard::m; + case GDK_N: return keyboard::n; + case GDK_O: return keyboard::o; + case GDK_P: return keyboard::p; + case GDK_Q: return keyboard::q; + case GDK_R: return keyboard::r; + case GDK_S: return keyboard::s; + case GDK_T: return keyboard::t; + case GDK_U: return keyboard::u; + case GDK_V: return keyboard::v; + case GDK_W: return keyboard::w; + case GDK_X: return keyboard::x; + case GDK_Y: return keyboard::y; + case GDK_Z: return keyboard::z; + + case GDK_bracketleft: return keyboard::lbracket; + case GDK_bracketright: return keyboard::rbracket; + case GDK_backslash: return keyboard::backslash; + case GDK_semicolon: return keyboard::semicolon; + case GDK_apostrophe: return keyboard::apostrophe; + case GDK_comma: return keyboard::comma; + case GDK_period: return keyboard::period; + case GDK_slash: return keyboard::slash; + + case GDK_braceleft: return keyboard::lbracket; + case GDK_braceright: return keyboard::rbracket; + case GDK_bar: return keyboard::backslash; + case GDK_colon: return keyboard::semicolon; + case GDK_quotedbl: return keyboard::apostrophe; + case GDK_less: return keyboard::comma; + case GDK_greater: return keyboard::period; + case GDK_question: return keyboard::slash; + + case GDK_KP_1: return keyboard::pad_1; + case GDK_KP_2: return keyboard::pad_2; + case GDK_KP_3: return keyboard::pad_3; + case GDK_KP_4: return keyboard::pad_4; + case GDK_KP_5: return keyboard::pad_5; + case GDK_KP_6: return keyboard::pad_6; + case GDK_KP_7: return keyboard::pad_7; + case GDK_KP_8: return keyboard::pad_8; + case GDK_KP_9: return keyboard::pad_9; + case GDK_KP_0: return keyboard::pad_0; + case GDK_KP_Decimal: return keyboard::point; + + case GDK_KP_End: return keyboard::pad_1; + case GDK_KP_Down: return keyboard::pad_2; + case GDK_KP_Page_Down: return keyboard::pad_3; + case GDK_KP_Left: return keyboard::pad_4; + case GDK_KP_Begin: return keyboard::pad_5; + case GDK_KP_Right: return keyboard::pad_6; + case GDK_KP_Home: return keyboard::pad_7; + case GDK_KP_Up: return keyboard::pad_8; + case GDK_KP_Page_Up: return keyboard::pad_9; + case GDK_KP_Insert: return keyboard::pad_0; + case GDK_KP_Delete: return keyboard::point; + + case GDK_KP_Add: return keyboard::add; + case GDK_KP_Subtract: return keyboard::subtract; + case GDK_KP_Multiply: return keyboard::multiply; + case GDK_KP_Divide: return keyboard::divide; + case GDK_KP_Enter: return keyboard::enter; + + case GDK_Num_Lock: return keyboard::num_lock; + case GDK_Caps_Lock: return keyboard::caps_lock; + + case GDK_Up: return keyboard::up; + case GDK_Down: return keyboard::down; + case GDK_Left: return keyboard::left; + case GDK_Right: return keyboard::right; + + case GDK_Tab: return keyboard::tab; + case GDK_Return: return keyboard::return_; + case GDK_space: return keyboard::spacebar; + + case GDK_Control_L: return keyboard::lctrl; + case GDK_Control_R: return keyboard::rctrl; + case GDK_Alt_L: return keyboard::lalt; + case GDK_Alt_R: return keyboard::ralt; + case GDK_Shift_L: return keyboard::lshift; + case GDK_Shift_R: return keyboard::rshift; + case GDK_Super_L: return keyboard::lsuper; + case GDK_Super_R: return keyboard::rsuper; + case GDK_Menu: return keyboard::menu; + } + + return keyboard::none; +} diff --git a/src/lib/miu.gtk/miu.gtk.label.cpp b/src/lib/hiro_gtk/label.cpp similarity index 100% rename from src/lib/miu.gtk/miu.gtk.label.cpp rename to src/lib/hiro_gtk/label.cpp diff --git a/src/lib/miu.gtk/miu.gtk.label.h b/src/lib/hiro_gtk/label.h similarity index 93% rename from src/lib/miu.gtk/miu.gtk.label.h rename to src/lib/hiro_gtk/label.h index e08540ea..7faa91be 100644 --- a/src/lib/miu.gtk/miu.gtk.label.h +++ b/src/lib/hiro_gtk/label.h @@ -6,7 +6,7 @@ public: pLabel(Label&); -/* internal */ + /* internal */ GtkWidget *label; GtkWidget* gtk_handle(); }; diff --git a/src/lib/miu.gtk/miu.gtk.listbox.cpp b/src/lib/hiro_gtk/listbox.cpp similarity index 95% rename from src/lib/miu.gtk/miu.gtk.listbox.cpp rename to src/lib/hiro_gtk/listbox.cpp index f90e01c3..fd7d418f 100644 --- a/src/lib/miu.gtk/miu.gtk.listbox.cpp +++ b/src/lib/hiro_gtk/listbox.cpp @@ -1,9 +1,9 @@ -void miu_plistbox_change(pListbox *p) { +void hiro_plistbox_change(pListbox *p) { if(p->listbox_selection == p->get_selection()) return; if(p->self.on_change) p->self.on_change(Event(Event::Change, p->listbox_selection = p->get_selection(), &p->self)); } -void miu_plistbox_activate(pListbox *p) { +void hiro_plistbox_activate(pListbox *p) { if(p->self.on_activate) p->self.on_activate(Event(Event::Activate, p->listbox_selection = p->get_selection(), &p->self)); } @@ -26,7 +26,7 @@ lstring list; GType *v = (GType*)malloc(count(list) * sizeof(GType)); for(uint i = 0; i < count(list); i++) v[i] = G_TYPE_STRING; store = gtk_list_store_newv(count(list), v); - safe_free(v); + free(v); listbox = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store)); gtk_container_add(GTK_CONTAINER(scrollbox), listbox); @@ -39,7 +39,7 @@ GType *v = (GType*)malloc(count(list) * sizeof(GType)); gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(listbox), count(list) >= 2 ? true : false); for(uint i = 0; i < count(list); i++) { renderer = gtk_cell_renderer_text_new(); - column = gtk_tree_view_column_new_with_attributes(list[i], renderer, "text", i, 0); + column = gtk_tree_view_column_new_with_attributes(list[i], renderer, "text", i, (void*)0); column_list[column_list.size()] = column; gtk_tree_view_append_column(GTK_TREE_VIEW(listbox), column); } @@ -52,8 +52,8 @@ GType *v = (GType*)malloc(count(list) * sizeof(GType)); gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(listbox), header); autosize_columns(); - g_signal_connect_swapped(G_OBJECT(listbox), "cursor-changed", G_CALLBACK(miu_plistbox_change), (gpointer)this); - g_signal_connect_swapped(G_OBJECT(listbox), "row-activated", G_CALLBACK(miu_plistbox_activate), (gpointer)this); + g_signal_connect_swapped(G_OBJECT(listbox), "cursor-changed", G_CALLBACK(hiro_plistbox_change), (gpointer)this); + g_signal_connect_swapped(G_OBJECT(listbox), "row-activated", G_CALLBACK(hiro_plistbox_activate), (gpointer)this); } void pListbox::autosize_columns() { diff --git a/src/lib/miu.gtk/miu.gtk.listbox.h b/src/lib/hiro_gtk/listbox.h similarity index 97% rename from src/lib/miu.gtk/miu.gtk.listbox.h rename to src/lib/hiro_gtk/listbox.h index faeae4cf..b983cd23 100644 --- a/src/lib/miu.gtk/miu.gtk.listbox.h +++ b/src/lib/hiro_gtk/listbox.h @@ -12,7 +12,7 @@ public: Listbox &self; pListbox(Listbox&); -/* internal */ + /* internal */ GtkWidget *scrollbox; GtkWidget *listbox; GtkListStore *store; diff --git a/src/lib/miu.gtk/miu.gtk.menucheckitem.cpp b/src/lib/hiro_gtk/menucheckitem.cpp similarity index 88% rename from src/lib/miu.gtk/miu.gtk.menucheckitem.cpp rename to src/lib/hiro_gtk/menucheckitem.cpp index c185d497..1fc9fba8 100644 --- a/src/lib/miu.gtk/miu.gtk.menucheckitem.cpp +++ b/src/lib/hiro_gtk/menucheckitem.cpp @@ -1,11 +1,11 @@ -void miu_pmenucheckitem_tick(pMenuCheckItem *p) { +void hiro_pmenucheckitem_tick(pMenuCheckItem *p) { if(p->self.on_tick) p->self.on_tick(Event(Event::Tick, p->checked(), &p->self)); } void pMenuCheckItem::create(const char *text) { item = gtk_check_menu_item_new_with_label(text ? text : "?"); gtk_widget_show(item); - g_signal_connect_swapped(G_OBJECT(item), "toggled", G_CALLBACK(miu_pmenucheckitem_tick), (gpointer)this); + g_signal_connect_swapped(G_OBJECT(item), "toggled", G_CALLBACK(hiro_pmenucheckitem_tick), (gpointer)this); } void pMenuCheckItem::check(bool state) { diff --git a/src/lib/miu.gtk/miu.gtk.menucheckitem.h b/src/lib/hiro_gtk/menucheckitem.h similarity index 94% rename from src/lib/miu.gtk/miu.gtk.menucheckitem.h rename to src/lib/hiro_gtk/menucheckitem.h index a161249e..d54202aa 100644 --- a/src/lib/miu.gtk/miu.gtk.menucheckitem.h +++ b/src/lib/hiro_gtk/menucheckitem.h @@ -8,7 +8,7 @@ public: MenuCheckItem &self; pMenuCheckItem(MenuCheckItem&); -/* internal */ + /* internal */ GtkWidget *item; GtkWidget* gtk_handle(); }; diff --git a/src/lib/miu.gtk/miu.gtk.menucontrol.cpp b/src/lib/hiro_gtk/menucontrol.cpp similarity index 100% rename from src/lib/miu.gtk/miu.gtk.menucontrol.cpp rename to src/lib/hiro_gtk/menucontrol.cpp diff --git a/src/lib/miu.gtk/miu.gtk.menucontrol.h b/src/lib/hiro_gtk/menucontrol.h similarity index 92% rename from src/lib/miu.gtk/miu.gtk.menucontrol.h rename to src/lib/hiro_gtk/menucontrol.h index 0204eacd..e6ec2678 100644 --- a/src/lib/miu.gtk/miu.gtk.menucontrol.h +++ b/src/lib/hiro_gtk/menucontrol.h @@ -7,6 +7,6 @@ public: MenuControl &self; pMenuControl(MenuControl&); -/* internal */ + /* internal */ virtual GtkWidget* gtk_handle(); }; diff --git a/src/lib/miu.gtk/miu.gtk.menugroup.cpp b/src/lib/hiro_gtk/menugroup.cpp similarity index 100% rename from src/lib/miu.gtk/miu.gtk.menugroup.cpp rename to src/lib/hiro_gtk/menugroup.cpp diff --git a/src/lib/miu.gtk/miu.gtk.menugroup.h b/src/lib/hiro_gtk/menugroup.h similarity index 93% rename from src/lib/miu.gtk/miu.gtk.menugroup.h rename to src/lib/hiro_gtk/menugroup.h index 594ba51f..fee411dd 100644 --- a/src/lib/miu.gtk/miu.gtk.menugroup.h +++ b/src/lib/hiro_gtk/menugroup.h @@ -6,7 +6,7 @@ public: pMenuGroup(MenuGroup&); -/* internal */ + /* internal */ GtkWidget *group; GtkWidget *item; GtkWidget* gtk_handle(); diff --git a/src/lib/miu.gtk/miu.gtk.menuitem.cpp b/src/lib/hiro_gtk/menuitem.cpp similarity index 83% rename from src/lib/miu.gtk/miu.gtk.menuitem.cpp rename to src/lib/hiro_gtk/menuitem.cpp index 64699dba..5da5be8d 100644 --- a/src/lib/miu.gtk/miu.gtk.menuitem.cpp +++ b/src/lib/hiro_gtk/menuitem.cpp @@ -1,10 +1,10 @@ -void miu_pmenuitem_tick(pMenuItem *p) { +void hiro_pmenuitem_tick(pMenuItem *p) { if(p->self.on_tick) p->self.on_tick(Event(Event::Tick, 0, &p->self)); } void pMenuItem::create(const char *text) { item = gtk_menu_item_new_with_label(text ? text : ""); - g_signal_connect_swapped(G_OBJECT(item), "activate", G_CALLBACK(miu_pmenuitem_tick), (gpointer)this); + g_signal_connect_swapped(G_OBJECT(item), "activate", G_CALLBACK(hiro_pmenuitem_tick), (gpointer)this); gtk_widget_show(item); } diff --git a/src/lib/miu.gtk/miu.gtk.menuitem.h b/src/lib/hiro_gtk/menuitem.h similarity index 91% rename from src/lib/miu.gtk/miu.gtk.menuitem.h rename to src/lib/hiro_gtk/menuitem.h index 55d02bca..57d50126 100644 --- a/src/lib/miu.gtk/miu.gtk.menuitem.h +++ b/src/lib/hiro_gtk/menuitem.h @@ -5,7 +5,7 @@ public: MenuItem &self; pMenuItem(MenuItem&); -/* internal */ + /* internal */ GtkWidget *item; GtkWidget* gtk_handle(); }; diff --git a/src/lib/miu.gtk/miu.gtk.menuradioitem.cpp b/src/lib/hiro_gtk/menuradioitem.cpp similarity index 91% rename from src/lib/miu.gtk/miu.gtk.menuradioitem.cpp rename to src/lib/hiro_gtk/menuradioitem.cpp index 0e9a436b..873760f3 100644 --- a/src/lib/miu.gtk/miu.gtk.menuradioitem.cpp +++ b/src/lib/hiro_gtk/menuradioitem.cpp @@ -1,4 +1,4 @@ -void miu_pmenuradioitem_tick(pMenuRadioItem *p) { +void hiro_pmenuradioitem_tick(pMenuRadioItem *p) { //GTK+ sends two messages: one for the activated radio item, //and one for the deactivated radio item. ignore the latter. if(p->checked() && p->self.on_tick) p->self.on_tick(Event(Event::Tick, 0, &p->self)); @@ -11,7 +11,7 @@ void pMenuRadioItem::create(MenuRadioItemGroup &group, const char *text) { item = gtk_radio_menu_item_new_with_label_from_widget(GTK_RADIO_MENU_ITEM(group[0]->p.gtk_handle()), text ? text : ""); } gtk_widget_show(item); - g_signal_connect_swapped(G_OBJECT(item), "toggled", G_CALLBACK(miu_pmenuradioitem_tick), (gpointer)this); + g_signal_connect_swapped(G_OBJECT(item), "toggled", G_CALLBACK(hiro_pmenuradioitem_tick), (gpointer)this); } void pMenuRadioItem::check() { diff --git a/src/lib/miu.gtk/miu.gtk.menuradioitem.h b/src/lib/hiro_gtk/menuradioitem.h similarity index 93% rename from src/lib/miu.gtk/miu.gtk.menuradioitem.h rename to src/lib/hiro_gtk/menuradioitem.h index bd020cb2..56f9b585 100644 --- a/src/lib/miu.gtk/miu.gtk.menuradioitem.h +++ b/src/lib/hiro_gtk/menuradioitem.h @@ -7,7 +7,7 @@ public: MenuRadioItem &self; pMenuRadioItem(MenuRadioItem&); -/* internal */ + /* internal */ GtkWidget *item; GtkWidget* gtk_handle(); }; diff --git a/src/lib/miu.gtk/miu.gtk.menuseparator.cpp b/src/lib/hiro_gtk/menuseparator.cpp similarity index 100% rename from src/lib/miu.gtk/miu.gtk.menuseparator.cpp rename to src/lib/hiro_gtk/menuseparator.cpp diff --git a/src/lib/miu.gtk/miu.gtk.menuseparator.h b/src/lib/hiro_gtk/menuseparator.h similarity index 91% rename from src/lib/miu.gtk/miu.gtk.menuseparator.h rename to src/lib/hiro_gtk/menuseparator.h index 54d8d151..2218a770 100644 --- a/src/lib/miu.gtk/miu.gtk.menuseparator.h +++ b/src/lib/hiro_gtk/menuseparator.h @@ -5,7 +5,7 @@ public: pMenuSeparator(MenuSeparator&); -/* internal */ + /* internal */ GtkWidget *item; GtkWidget* gtk_handle(); }; diff --git a/src/lib/miu.gtk/miu.gtk.progressbar.cpp b/src/lib/hiro_gtk/progressbar.cpp similarity index 88% rename from src/lib/miu.gtk/miu.gtk.progressbar.cpp rename to src/lib/hiro_gtk/progressbar.cpp index 2cef9fc0..7aa07780 100644 --- a/src/lib/miu.gtk/miu.gtk.progressbar.cpp +++ b/src/lib/hiro_gtk/progressbar.cpp @@ -6,11 +6,11 @@ void pProgressbar::create(uint style, uint width, uint height) { uint pProgressbar::get_progress() { uint progress = (uint)(gtk_progress_bar_get_fraction(GTK_PROGRESS_BAR(progressbar)) * 100.0); - return max(0, min(progress, 100)); + return max(0U, min(progress, 100U)); } void pProgressbar::set_progress(uint progress) { - progress = max(0, min(progress, 100)); + progress = max(0U, min(progress, 100U)); gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progressbar), (double)progress / 100.0); } diff --git a/src/lib/miu.gtk/miu.gtk.progressbar.h b/src/lib/hiro_gtk/progressbar.h similarity index 94% rename from src/lib/miu.gtk/miu.gtk.progressbar.h rename to src/lib/hiro_gtk/progressbar.h index 251c47dc..60997c80 100644 --- a/src/lib/miu.gtk/miu.gtk.progressbar.h +++ b/src/lib/hiro_gtk/progressbar.h @@ -7,7 +7,7 @@ public: pProgressbar(Progressbar&); -/* internal */ + /* internal */ GtkWidget *progressbar; GtkWidget* gtk_handle(); }; diff --git a/src/lib/miu.gtk/miu.gtk.radiobox.cpp b/src/lib/hiro_gtk/radiobox.cpp similarity index 93% rename from src/lib/miu.gtk/miu.gtk.radiobox.cpp rename to src/lib/hiro_gtk/radiobox.cpp index 1e7ec75d..1dd1551c 100644 --- a/src/lib/miu.gtk/miu.gtk.radiobox.cpp +++ b/src/lib/hiro_gtk/radiobox.cpp @@ -1,4 +1,4 @@ -void miu_pradiobox_tick(pRadiobox *p) { +void hiro_pradiobox_tick(pRadiobox *p) { //GTK+ sends two messages: one for the activated radiobox, //and one for the deactivated radiobox. ignore the latter. if(p->checked() && p->self.on_tick) p->self.on_tick(Event(Event::Tick, 0, &p->self)); @@ -12,7 +12,7 @@ void pRadiobox::create(RadioboxGroup &group, uint style, uint width, uint height } gtk_widget_set_size_request(radiobox, width, height); gtk_widget_show(radiobox); - g_signal_connect_swapped(G_OBJECT(radiobox), "toggled", G_CALLBACK(miu_pradiobox_tick), (gpointer)this); + g_signal_connect_swapped(G_OBJECT(radiobox), "toggled", G_CALLBACK(hiro_pradiobox_tick), (gpointer)this); } void pRadiobox::set_text(const char *text) { diff --git a/src/lib/miu.gtk/miu.gtk.radiobox.h b/src/lib/hiro_gtk/radiobox.h similarity index 94% rename from src/lib/miu.gtk/miu.gtk.radiobox.h rename to src/lib/hiro_gtk/radiobox.h index ea45c369..8b5825d6 100644 --- a/src/lib/miu.gtk/miu.gtk.radiobox.h +++ b/src/lib/hiro_gtk/radiobox.h @@ -8,7 +8,7 @@ public: Radiobox &self; pRadiobox(Radiobox&); -/* internal */ + /* internal */ GtkWidget *radiobox; GtkWidget* gtk_handle(); }; diff --git a/src/lib/miu.gtk/miu.gtk.slider.cpp b/src/lib/hiro_gtk/slider.cpp similarity index 92% rename from src/lib/miu.gtk/miu.gtk.slider.cpp rename to src/lib/hiro_gtk/slider.cpp index c1f40b2c..d8e3c364 100644 --- a/src/lib/miu.gtk/miu.gtk.slider.cpp +++ b/src/lib/hiro_gtk/slider.cpp @@ -1,4 +1,4 @@ -void miu_pslider_change(pSlider *p) { +void hiro_pslider_change(pSlider *p) { if(p->slider_position == p->get_position()) return; if(p->self.on_change) p->self.on_change(Event(Event::Change, p->slider_position = p->get_position(), &p->self)); } @@ -13,7 +13,7 @@ void pSlider::create(uint style, uint width, uint height, uint length) { gtk_scale_set_draw_value(GTK_SCALE(slider), FALSE); gtk_widget_set_size_request(slider, width, height); gtk_widget_show(slider); - g_signal_connect_swapped(G_OBJECT(slider), "value-changed", G_CALLBACK(miu_pslider_change), (gpointer)this); + g_signal_connect_swapped(G_OBJECT(slider), "value-changed", G_CALLBACK(hiro_pslider_change), (gpointer)this); } uint pSlider::get_position() { diff --git a/src/lib/miu.gtk/miu.gtk.slider.h b/src/lib/hiro_gtk/slider.h similarity index 94% rename from src/lib/miu.gtk/miu.gtk.slider.h rename to src/lib/hiro_gtk/slider.h index 9b2d02c1..2583addb 100644 --- a/src/lib/miu.gtk/miu.gtk.slider.h +++ b/src/lib/hiro_gtk/slider.h @@ -7,7 +7,7 @@ public: Slider &self; pSlider(Slider&); -/* internal */ + /* internal */ GtkWidget *slider; uint slider_position; GtkWidget* gtk_handle(); diff --git a/src/lib/miu.gtk/miu.gtk.widget.cpp b/src/lib/hiro_gtk/widget.cpp similarity index 87% rename from src/lib/miu.gtk/miu.gtk.widget.cpp rename to src/lib/hiro_gtk/widget.cpp index 464351d0..694f26c8 100644 --- a/src/lib/miu.gtk/miu.gtk.widget.cpp +++ b/src/lib/hiro_gtk/widget.cpp @@ -11,7 +11,7 @@ bool pWidget::visible() { } uintptr_t pWidget::handle() { - return GDK_WINDOW_XWINDOW(gtk_handle()->window); + return GDK_WINDOW_XID(gtk_handle()->window); } pWidget::pWidget(Widget &self_) : self(self_) { diff --git a/src/lib/miu.gtk/miu.gtk.widget.h b/src/lib/hiro_gtk/widget.h similarity index 91% rename from src/lib/miu.gtk/miu.gtk.widget.h rename to src/lib/hiro_gtk/widget.h index dfdec8c1..f5233a6f 100644 --- a/src/lib/miu.gtk/miu.gtk.widget.h +++ b/src/lib/hiro_gtk/widget.h @@ -8,6 +8,6 @@ public: Widget &self; pWidget(Widget&); -/* internal */ + /* internal */ virtual GtkWidget* gtk_handle(); }; diff --git a/src/lib/hiro_gtk/window.cpp b/src/lib/hiro_gtk/window.cpp new file mode 100644 index 00000000..930e4586 --- /dev/null +++ b/src/lib/hiro_gtk/window.cpp @@ -0,0 +1,262 @@ +gint hiro_pwindow_close(pWindow *p) { +uintptr_t r = p->self.on_close ? p->self.on_close(Event(Event::Close, 0, &p->self)) : true; + return !bool(r); +} + +gint hiro_pwindow_keydown(GtkWidget *w, GdkEventKey *key, pWindow *p) { + if(p && p->self.on_keydown) p->self.on_keydown(Event(Event::KeyDown, phiro().translate_key(key->keyval), &p->self)); + return FALSE; +} + +gint hiro_pwindow_keyup(GtkWidget *w, GdkEventKey *key, pWindow *p) { + if(p && p->self.on_keyup) p->self.on_keyup(Event(Event::KeyUp, phiro().translate_key(key->keyval), &p->self)); + return FALSE; +} + +void pWindow::create(uint style, uint width, uint height, const char *text) { + window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_window_set_title(GTK_WINDOW(window), text ? text : ""); + gtk_window_set_resizable(GTK_WINDOW(window), false); + if(style & Window::AutoCenter) gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER_ALWAYS); + g_signal_connect_swapped(G_OBJECT(window), "delete_event", G_CALLBACK(hiro_pwindow_close), (gpointer)this); + g_signal_connect(G_OBJECT(window), "key_press_event", G_CALLBACK(hiro_pwindow_keydown), (gpointer)this); + g_signal_connect(G_OBJECT(window), "key_release_event", G_CALLBACK(hiro_pwindow_keyup), (gpointer)this); + + menucontainer = gtk_vbox_new(false, 0); + gtk_container_add(GTK_CONTAINER(window), menucontainer); + gtk_widget_show(menucontainer); + + menubar = gtk_menu_bar_new(); + gtk_box_pack_start(GTK_BOX(menucontainer), menubar, false, false, 0); + + formcontainer = gtk_fixed_new(); + gtk_widget_set_size_request(formcontainer, width, height); + gtk_box_pack_start(GTK_BOX(menucontainer), formcontainer, true, true, 0); + gtk_widget_show(formcontainer); + + //GTK+ statusbar background can be transparent, depending upon GTK+ theme + //therefore, pack statusbar inside an event box, which always has a background + //this allows pWindow::set_background_color() to change the window color, + //without affecting the statusbar color + statuscontainer = gtk_event_box_new(); + statusbar = gtk_statusbar_new(); + gtk_container_add(GTK_CONTAINER(statuscontainer), statusbar); + gtk_statusbar_set_has_resize_grip(GTK_STATUSBAR(statusbar), false); + gtk_box_pack_start(GTK_BOX(menucontainer), statuscontainer, false, false, 0); + gtk_widget_show(statuscontainer); + + state.is_fullscreen = false; + state.width = width; + state.height = height; +} + +void pWindow::close() { + gtk_widget_destroy(window); +} + +void pWindow::move(uint x, uint y) { + gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_NONE); + gtk_window_move(GTK_WINDOW(window), x, y); +} + +void pWindow::resize(uint width, uint height) { + gtk_widget_set_size_request(formcontainer, width, height); + state.width = width; + state.height = height; +} + +void pWindow::focus() { + gtk_window_present(GTK_WINDOW(window)); +} + +bool pWindow::focused() { + return gtk_window_is_active(GTK_WINDOW(window)); +} + +//gtk_window_(un/)fullscreen() alone does not work well on certain WMs, such as Openbox. +//sometimes, the window will not resize (but will move to the top left.) +//sometimes, the window decorations will not disappear. +//therefore, to be safe, perform some manual window adjustments as well + +void pWindow::fullscreen() { + if(state.is_fullscreen == true) return; + state.is_fullscreen = true; + + gtk_window_fullscreen(GTK_WINDOW(window)); + gtk_window_set_decorated(GTK_WINDOW(window), false); + gtk_widget_set_size_request(window, gdk_screen_width(), gdk_screen_height()); +} + +//note that the size of the window is bound to be at least the size of the formcontainer. +//this is why the window size is set to -1, -1 below, so that it becomes the minimum +//needed to display all of the formcontainer. + +void pWindow::unfullscreen() { + if(state.is_fullscreen == false) return; + state.is_fullscreen = false; + + gtk_widget_set_size_request(formcontainer, state.width, state.height); + gtk_widget_set_size_request(window, -1, -1); + gtk_window_set_decorated(GTK_WINDOW(window), true); + gtk_window_unfullscreen(GTK_WINDOW(window)); +} + +//gtk_widget_size_request() on a window immediately after gtk_window_(un/)fullscreen() +//is unreliable, as it will usually report the previous window size. +//therefore, calculate it manually by using state information. + +uint pWindow::get_width() { + if(state.is_fullscreen == false) return state.width; + return gdk_screen_width(); +} + +uint pWindow::get_height() { + if(state.is_fullscreen == false) return state.height; + uint height = gdk_screen_height(); + + //do not include menubar height in client area height + if(menu.visible()) { + GtkRequisition req; + gtk_widget_size_request(menubar, &req); + height -= req.height; + } + + //do not include statusbar height in client area height + if(status.visible()) { + GtkRequisition req; + gtk_widget_size_request(statusbar, &req); + height -= req.height; + } + + return height; +} + +void pWindow::set_background_color(uint8_t r, uint8_t g, uint8_t b) { +GdkColor color; + color.pixel = (r << 16) | (g << 8) | b; + color.red = (r << 8) | r; + color.green = (g << 8) | g; + color.blue = (b << 8) | b; + gtk_widget_modify_bg(window, GTK_STATE_NORMAL, &color); +} + +void pWindow::set_text(const char *text) { + gtk_window_set_title(GTK_WINDOW(window), text ? text : ""); +} + +void pWindow::attach(Window &window, uint x, uint y) { + window.p.owner = this; + + //GTK+ does not support attaching a window to another window, + //so instead reparent the container from the child window to + //the parent window, and reposition the child window's container + gtk_widget_hide(window.p.window); + gtk_widget_hide(window.p.formcontainer); + gtk_widget_reparent(window.p.formcontainer, formcontainer); + gtk_fixed_move(GTK_FIXED(formcontainer), window.p.formcontainer, x, y); + gtk_widget_show(window.p.formcontainer); +} + +void pWindow::attach(MenuGroup &menugroup) { + gtk_menu_bar_append(menubar, menugroup.p.item); + gtk_widget_show(menubar); +} + +void pWindow::attach(FormControl &formcontrol, uint x, uint y) { + gtk_fixed_put(GTK_FIXED(formcontainer), formcontrol.p.gtk_handle(), x, y); +} + +void pWindow::move(Window &window, uint x, uint y) { + gtk_fixed_move(GTK_FIXED(formcontainer), window.p.gtk_handle(), x, y); +} + +void pWindow::move(FormControl &formcontrol, uint x, uint y) { + gtk_fixed_move(GTK_FIXED(formcontainer), formcontrol.p.gtk_handle(), x, y); +} + +/* pWindow -> Menubar */ + +void pWindow::Menubar::show(bool state) { + p.menu_show(state); +} + +void pWindow::Menubar::hide() { + p.menu_hide(); +} + +bool pWindow::Menubar::visible() { + return p.menu_visible(); +} + +pWindow::Menubar::Menubar(pWindow &p_) : p(p_) { +} + +/* pWindow -> Statusbar */ + +void pWindow::Statusbar::set_text(const char *text) { + p.status_set_text(text); +} + +void pWindow::Statusbar::show(bool state) { + p.status_show(state); +} + +void pWindow::Statusbar::hide() { + p.status_hide(); +} + +bool pWindow::Statusbar::visible() { + return p.status_visible(); +} + +pWindow::Statusbar::Statusbar(pWindow &p_) : p(p_) { +} + +pWindow::pWindow(Window &self_) : pWidget(self_), self(self_), menu(*this), status(*this) { + owner = 0; + window = 0; + menubar = 0; + statusbar = 0; + menucontainer = 0; + formcontainer = 0; + statuscontainer = 0; + + state.is_fullscreen = false; + state.width = 0; + state.height = 0; +} + +/* internal */ + +GtkWidget* pWindow::gtk_handle() { + return owner ? formcontainer : window; +} + +void pWindow::menu_show(bool state) { + state ? gtk_widget_show(menubar) : gtk_widget_hide(menubar); +} + +void pWindow::menu_hide() { + menu_show(false); +} + +bool pWindow::menu_visible() { + return GTK_WIDGET_VISIBLE(menubar); +} + +void pWindow::status_set_text(const char *text) { + gtk_statusbar_pop(GTK_STATUSBAR(statusbar), 1); + gtk_statusbar_push(GTK_STATUSBAR(statusbar), 1, text ? text : ""); +} + +void pWindow::status_show(bool state) { + state ? gtk_widget_show(statusbar) : gtk_widget_hide(statusbar); +} + +void pWindow::status_hide() { + status_show(false); +} + +bool pWindow::status_visible() { + return GTK_WIDGET_VISIBLE(statusbar); +} diff --git a/src/lib/miu.gtk/miu.gtk.window.h b/src/lib/hiro_gtk/window.h similarity index 52% rename from src/lib/miu.gtk/miu.gtk.window.h rename to src/lib/hiro_gtk/window.h index 6b2c28a4..d1e5663a 100644 --- a/src/lib/miu.gtk/miu.gtk.window.h +++ b/src/lib/hiro_gtk/window.h @@ -8,25 +8,61 @@ public: bool focused(); void fullscreen(); void unfullscreen(); - void set_background_color(uint8 r, uint8 g, uint8 b); + uint get_width(); + uint get_height(); + void set_background_color(uint8_t r, uint8_t g, uint8_t b); void set_text(const char *text = ""); void attach(Window &window, uint x, uint y); void attach(MenuGroup &menugroup); void attach(FormControl &formcontrol, uint x, uint y); void move(Window &window, uint x, uint y); void move(FormControl &formcontrol, uint x, uint y); - void menu_show(bool state = true); - void menu_hide(); - bool menu_visible(); + + class Statusbar { + public: + void set_text(const char *text = ""); + void show(bool = true); + void hide(); + bool visible(); + + pWindow &p; + Statusbar(pWindow&); + } status; + + class Menubar { + public: + void show(bool = true); + void hide(); + bool visible(); + + pWindow &p; + Menubar(pWindow&); + } menu; Window &self; pWindow(Window&); -/* internal */ + /* internal */ pWindow *owner; //0 = no owner (default) GtkWidget *window; GtkWidget *menubar; + GtkWidget *statusbar; GtkWidget *menucontainer; GtkWidget *formcontainer; + GtkWidget *statuscontainer; GtkWidget* gtk_handle(); + struct { + bool is_fullscreen; + uint width; + uint height; + } state; + + void menu_show(bool = true); + void menu_hide(); + bool menu_visible(); + + void status_set_text(const char *text = ""); + void status_show(bool = true); + void status_hide(); + bool status_visible(); }; diff --git a/src/lib/miu.win/miu.win.button.cpp b/src/lib/hiro_win/button.cpp similarity index 75% rename from src/lib/miu.win/miu.win.button.cpp rename to src/lib/hiro_win/button.cpp index 618b70a3..8347f1b5 100644 --- a/src/lib/miu.win/miu.win.button.cpp +++ b/src/lib/hiro_win/button.cpp @@ -1,9 +1,9 @@ void pButton::create(uint style, uint width, uint height, const char *text) { hwnd = CreateWindow("BUTTON", text ? text : "", WS_CHILD | WS_VISIBLE, 0, 0, width, height, - miu().p.default_hwnd, (HMENU)instance, GetModuleHandle(0), 0); + phiro().default_hwnd, (HMENU)instance, GetModuleHandle(0), 0); SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)this); - SendMessage(hwnd, WM_SETFONT, (WPARAM)miu().p.default_font, 0); + SendMessage(hwnd, WM_SETFONT, (WPARAM)phiro().default_font, 0); } void pButton::set_text(const char *text) { diff --git a/src/lib/miu.win/miu.win.button.h b/src/lib/hiro_win/button.h similarity index 100% rename from src/lib/miu.win/miu.win.button.h rename to src/lib/hiro_win/button.h diff --git a/src/lib/miu.win/miu.win.canvas.cpp b/src/lib/hiro_win/canvas.cpp similarity index 79% rename from src/lib/miu.win/miu.win.canvas.cpp rename to src/lib/hiro_win/canvas.cpp index 5431934d..0abf990f 100644 --- a/src/lib/miu.win/miu.win.canvas.cpp +++ b/src/lib/hiro_win/canvas.cpp @@ -1,7 +1,7 @@ void pCanvas::create(uint style, uint width, uint height) { - hwnd = CreateWindow("miu_window", "", WS_CHILD, + hwnd = CreateWindow("hiro_window", "", WS_CHILD, 0, 0, width, height, - miu().p.default_hwnd, (HMENU)instance, GetModuleHandle(0), 0); + phiro().default_hwnd, (HMENU)instance, GetModuleHandle(0), 0); SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)this); resize(width, height); ShowWindow(hwnd, SW_NORMAL); @@ -10,7 +10,7 @@ void pCanvas::create(uint style, uint width, uint height) { void pCanvas::redraw() { } -uint32* pCanvas::buffer() { +uint32_t* pCanvas::buffer() { return ibuffer; } @@ -25,7 +25,7 @@ pCanvas::pCanvas(Canvas &self_) : pFormControl(self_), self(self_) { } pCanvas::~pCanvas() { - safe_free(ibuffer); + if(ibuffer) free(ibuffer); } /* internal */ @@ -38,12 +38,12 @@ PAINTSTRUCT ps; } void pCanvas::resize(uint width, uint height) { - safe_free(ibuffer); + if(ibuffer) free(ibuffer); - ipitch = width * sizeof(uint32); + ipitch = width * sizeof(uint32_t); iwidth = width; iheight = height; - ibuffer = (uint32*)malloc(ipitch * height); + ibuffer = (uint32_t*)malloc(ipitch * height); memset(ibuffer, 0, ipitch * height); bmi.bmiHeader.biWidth = width; diff --git a/src/lib/miu.win/miu.win.canvas.h b/src/lib/hiro_win/canvas.h similarity index 82% rename from src/lib/miu.win/miu.win.canvas.h rename to src/lib/hiro_win/canvas.h index 9b39f6fb..2bc478ff 100644 --- a/src/lib/miu.win/miu.win.canvas.h +++ b/src/lib/hiro_win/canvas.h @@ -2,15 +2,15 @@ class pCanvas : public pFormControl { public: void create(uint style, uint width, uint height); void redraw(); - uint32* buffer(); + uint32_t* buffer(); Canvas &self; pCanvas(Canvas&); ~pCanvas(); -/* internal */ + /* internal */ BITMAPINFO bmi; - uint32 *ibuffer; + uint32_t *ibuffer; uint ipitch, iwidth, iheight; void blit(); void resize(uint width, uint height); diff --git a/src/lib/miu.win/miu.win.checkbox.cpp b/src/lib/hiro_win/checkbox.cpp similarity index 84% rename from src/lib/miu.win/miu.win.checkbox.cpp rename to src/lib/hiro_win/checkbox.cpp index db7caf3b..07d040b2 100644 --- a/src/lib/miu.win/miu.win.checkbox.cpp +++ b/src/lib/hiro_win/checkbox.cpp @@ -1,8 +1,8 @@ void pCheckbox::create(uint style, uint width, uint height, const char *text) { hwnd = CreateWindow("BUTTON", text ? text : "", WS_CHILD | WS_VISIBLE | BS_CHECKBOX, 0, 0, width, height, - miu().p.default_hwnd, (HMENU)instance, GetModuleHandle(0), 0); - SendMessage(hwnd, WM_SETFONT, (WPARAM)miu().p.default_font, 0); + phiro().default_hwnd, (HMENU)instance, GetModuleHandle(0), 0); + SendMessage(hwnd, WM_SETFONT, (WPARAM)phiro().default_font, 0); } void pCheckbox::set_text(const char *text) { diff --git a/src/lib/miu.win/miu.win.checkbox.h b/src/lib/hiro_win/checkbox.h similarity index 100% rename from src/lib/miu.win/miu.win.checkbox.h rename to src/lib/hiro_win/checkbox.h diff --git a/src/lib/miu.win/miu.win.combobox.cpp b/src/lib/hiro_win/combobox.cpp similarity index 85% rename from src/lib/miu.win/miu.win.combobox.cpp rename to src/lib/hiro_win/combobox.cpp index 458d416b..bcd3b020 100644 --- a/src/lib/miu.win/miu.win.combobox.cpp +++ b/src/lib/hiro_win/combobox.cpp @@ -2,8 +2,8 @@ void pCombobox::create(uint style, uint width, uint height, const char *text) { hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, "COMBOBOX", "", WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST | CBS_HASSTRINGS, 0, 0, width, 200, - miu().p.default_hwnd, (HMENU)instance, GetModuleHandle(0), 0); - SendMessage(hwnd, WM_SETFONT, (WPARAM)miu().p.default_font, 0); + phiro().default_hwnd, (HMENU)instance, GetModuleHandle(0), 0); + SendMessage(hwnd, WM_SETFONT, (WPARAM)phiro().default_font, 0); } void pCombobox::add_item(const char *text) { diff --git a/src/lib/miu.win/miu.win.combobox.h b/src/lib/hiro_win/combobox.h similarity index 94% rename from src/lib/miu.win/miu.win.combobox.h rename to src/lib/hiro_win/combobox.h index f7b7713d..06e48e75 100644 --- a/src/lib/miu.win/miu.win.combobox.h +++ b/src/lib/hiro_win/combobox.h @@ -9,6 +9,6 @@ public: pCombobox(Combobox&); -/* internal */ + /* internal */ int combobox_selection; }; diff --git a/src/lib/miu.win/miu.win.editbox.cpp b/src/lib/hiro_win/editbox.cpp similarity index 53% rename from src/lib/miu.win/miu.win.editbox.cpp rename to src/lib/hiro_win/editbox.cpp index 76388572..079e0761 100644 --- a/src/lib/miu.win/miu.win.editbox.cpp +++ b/src/lib/hiro_win/editbox.cpp @@ -1,25 +1,25 @@ void pEditbox::create(uint style, uint width, uint height, const char *text) { -bool multiline = style & Editbox::Multiline; -bool readonly = style & Editbox::Readonly; -uint vscroll = (style & Editbox::VerticalScrollAlways) ? WS_VSCROLL : - (style & Editbox::VerticalScrollNever) ? 0 : - ES_AUTOVSCROLL; -uint hscroll = (style & Editbox::HorizontalScrollAlways) ? WS_HSCROLL : - (style & Editbox::HorizontalScrollNever) ? 0 : - ES_AUTOHSCROLL; + bool multiline = style & Editbox::Multiline; + bool readonly = style & Editbox::Readonly; + uint vscroll = (style & Editbox::VerticalScrollAlways) ? WS_VSCROLL : + (style & Editbox::VerticalScrollNever) ? 0 : + ES_AUTOVSCROLL; + uint hscroll = (style & Editbox::HorizontalScrollAlways) ? WS_HSCROLL : + (style & Editbox::HorizontalScrollNever) ? 0 : + ES_AUTOHSCROLL; hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "", WS_CHILD | WS_VISIBLE | vscroll | hscroll | (multiline == true ? ES_MULTILINE : 0) | (readonly == true ? ES_READONLY : 0), 0, 0, width, height, - miu().p.default_hwnd, (HMENU)instance, GetModuleHandle(0), 0); - SendMessage(hwnd, WM_SETFONT, (WPARAM)miu().p.default_font, 0); + phiro().default_hwnd, (HMENU)instance, GetModuleHandle(0), 0); + SendMessage(hwnd, WM_SETFONT, (WPARAM)phiro().default_font, 0); set_text(text); } void pEditbox::set_text(const char *text) { -string temp = text ? text : ""; + string temp = text ? text : ""; replace(temp, "\r", ""); replace(temp, "\n", "\r\n"); SetWindowText(hwnd, temp); @@ -27,7 +27,7 @@ string temp = text ? text : ""; uint pEditbox::get_text(char *text, uint length) { GetWindowText(hwnd, text, length); -string temp = text; + string temp = text; replace(temp, "\r", ""); strcpy(text, temp); return strlen(text); diff --git a/src/lib/miu.win/miu.win.editbox.h b/src/lib/hiro_win/editbox.h similarity index 100% rename from src/lib/miu.win/miu.win.editbox.h rename to src/lib/hiro_win/editbox.h diff --git a/src/lib/miu.win/miu.win.formcontrol.cpp b/src/lib/hiro_win/formcontrol.cpp similarity index 100% rename from src/lib/miu.win/miu.win.formcontrol.cpp rename to src/lib/hiro_win/formcontrol.cpp diff --git a/src/lib/miu.win/miu.win.formcontrol.h b/src/lib/hiro_win/formcontrol.h similarity index 94% rename from src/lib/miu.win/miu.win.formcontrol.h rename to src/lib/hiro_win/formcontrol.h index 7d4e119a..e2faeaf6 100644 --- a/src/lib/miu.win/miu.win.formcontrol.h +++ b/src/lib/hiro_win/formcontrol.h @@ -11,6 +11,6 @@ public: FormControl &self; pFormControl(FormControl&); -/* internal */ + /* internal */ HWND hwnd; }; diff --git a/src/lib/miu.win/miu.win.frame.cpp b/src/lib/hiro_win/frame.cpp similarity index 73% rename from src/lib/miu.win/miu.win.frame.cpp rename to src/lib/hiro_win/frame.cpp index e7386977..73c75c1c 100644 --- a/src/lib/miu.win/miu.win.frame.cpp +++ b/src/lib/hiro_win/frame.cpp @@ -1,8 +1,8 @@ void pFrame::create(uint style, uint width, uint height, const char *text) { hwnd = CreateWindow("BUTTON", text ? text : "", WS_CHILD | WS_VISIBLE | BS_GROUPBOX, 0, 0, width, height, - miu().p.default_hwnd, (HMENU)instance, GetModuleHandle(0), 0); - SendMessage(hwnd, WM_SETFONT, (WPARAM)miu().p.default_font, 0); + phiro().default_hwnd, (HMENU)instance, GetModuleHandle(0), 0); + SendMessage(hwnd, WM_SETFONT, (WPARAM)phiro().default_font, 0); } void pFrame::set_text(const char *text) { diff --git a/src/lib/miu.win/miu.win.frame.h b/src/lib/hiro_win/frame.h similarity index 100% rename from src/lib/miu.win/miu.win.frame.h rename to src/lib/hiro_win/frame.h diff --git a/src/lib/miu.win/miu.win.cpp b/src/lib/hiro_win/hiro.cpp similarity index 74% rename from src/lib/miu.win/miu.win.cpp rename to src/lib/hiro_win/hiro.cpp index 81025313..0c677f4c 100644 --- a/src/lib/miu.win/miu.win.cpp +++ b/src/lib/hiro_win/hiro.cpp @@ -1,33 +1,36 @@ -#include "miu.win.h" -#include "../miu.cpp" +#include "hiro.h" -namespace ns_miu { +#include +using nall::min; +using nall::max; -long __stdcall pmiu_wndproc(HWND, UINT, WPARAM, LPARAM); +namespace libhiro { -#include "miu.win.keymap.cpp" -#include "miu.win.widget.cpp" - #include "miu.win.window.cpp" - #include "miu.win.menucontrol.cpp" - #include "miu.win.menugroup.cpp" - #include "miu.win.menuitem.cpp" - #include "miu.win.menucheckitem.cpp" - #include "miu.win.menuradioitem.cpp" - #include "miu.win.menuseparator.cpp" - #include "miu.win.formcontrol.cpp" - #include "miu.win.frame.cpp" - #include "miu.win.canvas.cpp" - #include "miu.win.label.cpp" - #include "miu.win.button.cpp" - #include "miu.win.checkbox.cpp" - #include "miu.win.radiobox.cpp" - #include "miu.win.editbox.cpp" - #include "miu.win.listbox.cpp" - #include "miu.win.combobox.cpp" - #include "miu.win.progressbar.cpp" - #include "miu.win.slider.cpp" +LRESULT CALLBACK phiro_wndproc(HWND, UINT, WPARAM, LPARAM); -void pMiu::init() { +#include "keymap.cpp" +#include "widget.cpp" + #include "window.cpp" + #include "menucontrol.cpp" + #include "menugroup.cpp" + #include "menuitem.cpp" + #include "menucheckitem.cpp" + #include "menuradioitem.cpp" + #include "menuseparator.cpp" + #include "formcontrol.cpp" + #include "frame.cpp" + #include "canvas.cpp" + #include "label.cpp" + #include "button.cpp" + #include "checkbox.cpp" + #include "radiobox.cpp" + #include "editbox.cpp" + #include "listbox.cpp" + #include "combobox.cpp" + #include "progressbar.cpp" + #include "slider.cpp" + +void pHiro::init() { WNDCLASS wc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; @@ -35,23 +38,23 @@ WNDCLASS wc; wc.hCursor = LoadCursor(0, IDC_ARROW); wc.hIcon = LoadIcon(0, IDI_APPLICATION); wc.hInstance = GetModuleHandle(0); - wc.lpfnWndProc = pmiu_wndproc; - wc.lpszClassName = "miu_window"; + wc.lpfnWndProc = phiro_wndproc; + wc.lpszClassName = "hiro_window"; wc.lpszMenuName = 0; wc.style = CS_HREDRAW | CS_VREDRAW; RegisterClass(&wc); InitCommonControls(); - default_hwnd = CreateWindow("miu_window", "", WS_POPUP, 0, 0, 640, 480, 0, 0, GetModuleHandle(0), 0); + default_hwnd = CreateWindow("hiro_window", "", WS_POPUP, 0, 0, 640, 480, 0, 0, GetModuleHandle(0), 0); default_font = create_font("Tahoma", 9); black_brush = CreateSolidBrush(RGB(0, 0, 0)); } -void pMiu::term() { +void pHiro::term() { DeleteObject(black_brush); } -bool pMiu::run() { +bool pHiro::run() { MSG msg; if(PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); @@ -60,12 +63,12 @@ MSG msg; return pending(); } -bool pMiu::pending() { +bool pHiro::pending() { MSG msg; return PeekMessage(&msg, 0, 0, 0, PM_NOREMOVE); } -bool pMiu::file_load(Window *focus, char *filename, const char *filter, const char *path) { +bool pHiro::file_load(Window *focus, char *filename, const char *filter, const char *path) { string dir, f; strcpy(dir, path ? path : ""); replace(dir, "/", "\\"); @@ -106,7 +109,7 @@ OPENFILENAME ofn; return GetOpenFileName(&ofn); } -bool pMiu::file_save(Window *focus, char *filename, const char *filter, const char *path) { +bool pHiro::file_save(Window *focus, char *filename, const char *filter, const char *path) { string dir, f; strcpy(dir, path ? path : ""); replace(dir, "/", "\\"); @@ -147,37 +150,37 @@ OPENFILENAME ofn; return GetSaveFileName(&ofn); } -uint pMiu::screen_width() { +uint pHiro::screen_width() { return GetSystemMetrics(SM_CXSCREEN); } -uint pMiu::screen_height() { +uint pHiro::screen_height() { return GetSystemMetrics(SM_CYSCREEN); } -pMiu& pMiu::handle() { - return miu().p; +pHiro& pHiro::handle() { + return hiro().p; } -pMiu::pMiu(Miu &self_) : self(self_) { +pHiro::pHiro(Hiro &self_) : self(self_) { } -pMiu& pmiu() { - return pMiu::handle(); +pHiro& phiro() { + return pHiro::handle(); } /* internal */ -HFONT pMiu::create_font(const char *name, uint size) { -HDC hdc = GetDC(0); -HFONT font = CreateFont(-MulDiv(size, GetDeviceCaps(hdc, LOGPIXELSY), 72), +HFONT pHiro::create_font(const char *name, uint size) { + HDC hdc = GetDC(0); + HFONT font = CreateFont(-MulDiv(size, GetDeviceCaps(hdc, LOGPIXELSY), 72), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, name); ReleaseDC(0, hdc); return font; } -Widget* pMiu::get_widget(uint instance) { -Widget *widget = 0; +Widget* pHiro::get_widget(uint instance) { + Widget *widget = 0; for(uint i = 0; i < widget_list.size(); i++) { if(widget_list[i]->p.instance != instance) continue; widget = widget_list[i]; @@ -186,14 +189,29 @@ Widget *widget = 0; return widget; } -long __stdcall pmiu_wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { - return pmiu().wndproc(hwnd, msg, wparam, lparam); +LRESULT CALLBACK phiro_wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { + return phiro().wndproc(hwnd, msg, wparam, lparam); } -long pMiu::wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { -pWidget *p = (pWidget*)GetWindowLongPtr(hwnd, GWLP_USERDATA); +LRESULT pHiro::wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { + pWidget *p = (pWidget*)GetWindowLongPtr(hwnd, GWLP_USERDATA); switch(msg) { + case WM_SYSCOMMAND: { + switch(wparam) { + //TODO: write hiro API to allow this to be toggled. + //for now, screensaver and monitorpower events are disabled always. + case SC_SCREENSAVE: + case SC_MONITORPOWER: + return FALSE; + } + } break; + + case WM_SIZE: { + if(!p || p->self.type != Widget::WindowType) break; + SendMessage(((pWindow*)p)->hstatus, WM_SIZE, 0, 0); //the control itself auto-sizes after receiving WM_SIZE + } break; + case WM_CLOSE: { if(!p || p->self.type != Widget::WindowType) break; Window &w = ((pWindow*)p)->self; @@ -223,7 +241,7 @@ pWidget *p = (pWidget*)GetWindowLongPtr(hwnd, GWLP_USERDATA); if(!p) break; HBRUSH brush = 0; if(p->self.type == Widget::WindowType) brush = ((pWindow*)p)->background; - if(p->self.type == Widget::CanvasType) brush = pmiu().black_brush; + if(p->self.type == Widget::CanvasType) brush = phiro().black_brush; if(!brush) break; RECT rc; GetClientRect(hwnd, &rc); @@ -315,4 +333,4 @@ pWidget *p = (pWidget*)GetWindowLongPtr(hwnd, GWLP_USERDATA); return DefWindowProc(hwnd, msg, wparam, lparam); } -} //namespace ns_miu +} //namespace libhiro diff --git a/src/lib/hiro_win/hiro.h b/src/lib/hiro_win/hiro.h new file mode 100644 index 00000000..f16c0ab4 --- /dev/null +++ b/src/lib/hiro_win/hiro.h @@ -0,0 +1,73 @@ +#ifndef HIRO_WIN_H +#define HIRO_WIN_H + +#undef WINVER +#undef _WIN32_WINNT +#undef _WIN32_IE +#undef NOMINMAX + +#define WINVER 0x0501 +#define _WIN32_WINNT 0x0501 +#define _WIN32_IE 0x0600 +#define NOMINMAX + +#include +#include + +namespace libhiro { + +#include "widget.h" + #include "window.h" + #include "menucontrol.h" + #include "menugroup.h" + #include "menuitem.h" + #include "menucheckitem.h" + #include "menuradioitem.h" + #include "menuseparator.h" + #include "formcontrol.h" + #include "frame.h" + #include "canvas.h" + #include "label.h" + #include "button.h" + #include "checkbox.h" + #include "radiobox.h" + #include "editbox.h" + #include "listbox.h" + #include "combobox.h" + #include "progressbar.h" + #include "slider.h" + +class pHiro { +public: + Hiro &self; + void init(); + void term(); + bool run(); + bool pending(); + + bool file_load(Window *focus, char *filename, const char *filter, const char *path); + bool file_save(Window *focus, char *filename, const char *filter, const char *path); + + uint screen_width(); + uint screen_height(); + + static pHiro& handle(); + pHiro(Hiro&); + + /* internal */ + HWND default_hwnd; //default parent window for all windowless controls + HFONT default_font; //default font for all controls + HBRUSH black_brush; //used for Canvas background + HFONT create_font(const char *name, uint size); + + array widget_list; + Widget* get_widget(uint instance); + LRESULT wndproc(HWND, UINT, WPARAM, LPARAM); + uint16_t translate_key(uint key); +}; + +pHiro& phiro(); + +} //namsepace libhiro + +#endif //ifndef HIRO_WIN_H diff --git a/src/lib/hiro_win/keymap.cpp b/src/lib/hiro_win/keymap.cpp new file mode 100644 index 00000000..5437f5bb --- /dev/null +++ b/src/lib/hiro_win/keymap.cpp @@ -0,0 +1,67 @@ +uint16_t pHiro::translate_key(uint key) { + switch(key) { + case VK_ESCAPE: return keyboard::escape; + + case VK_F1: return keyboard::f1; + case VK_F2: return keyboard::f2; + case VK_F3: return keyboard::f3; + case VK_F4: return keyboard::f4; + case VK_F5: return keyboard::f5; + case VK_F6: return keyboard::f6; + case VK_F7: return keyboard::f7; + case VK_F8: return keyboard::f8; + case VK_F9: return keyboard::f9; + case VK_F10: return keyboard::f10; + case VK_F11: return keyboard::f11; + case VK_F12: return keyboard::f12; + + case VK_TAB: return keyboard::tab; + case VK_RETURN: return keyboard::return_; + case VK_SPACE: return keyboard::spacebar; + + case '0': return keyboard::num_0; + case '1': return keyboard::num_1; + case '2': return keyboard::num_2; + case '3': return keyboard::num_3; + case '4': return keyboard::num_4; + case '5': return keyboard::num_5; + case '6': return keyboard::num_6; + case '7': return keyboard::num_7; + case '8': return keyboard::num_8; + case '9': return keyboard::num_9; + + case 'A': return keyboard::a; + case 'B': return keyboard::b; + case 'C': return keyboard::c; + case 'D': return keyboard::d; + case 'E': return keyboard::e; + case 'F': return keyboard::f; + case 'G': return keyboard::g; + case 'H': return keyboard::h; + case 'I': return keyboard::i; + case 'J': return keyboard::j; + case 'K': return keyboard::k; + case 'L': return keyboard::l; + case 'M': return keyboard::m; + case 'N': return keyboard::n; + case 'O': return keyboard::o; + case 'P': return keyboard::p; + case 'Q': return keyboard::q; + case 'R': return keyboard::r; + case 'S': return keyboard::s; + case 'T': return keyboard::t; + case 'U': return keyboard::u; + case 'V': return keyboard::v; + case 'W': return keyboard::w; + case 'X': return keyboard::x; + case 'Y': return keyboard::y; + case 'Z': return keyboard::z; + + case VK_UP: return keyboard::up; + case VK_DOWN: return keyboard::down; + case VK_LEFT: return keyboard::left; + case VK_RIGHT: return keyboard::right; + } + + return keyboard::none; +} diff --git a/src/lib/miu.win/miu.win.label.cpp b/src/lib/hiro_win/label.cpp similarity index 72% rename from src/lib/miu.win/miu.win.label.cpp rename to src/lib/hiro_win/label.cpp index 48d34ea7..3860c163 100644 --- a/src/lib/miu.win/miu.win.label.cpp +++ b/src/lib/hiro_win/label.cpp @@ -1,8 +1,8 @@ void pLabel::create(uint style, uint width, uint height, const char *text) { hwnd = CreateWindow("STATIC", text ? text : "", WS_CHILD | WS_VISIBLE, 0, 0, width, height, - miu().p.default_hwnd, (HMENU)instance, GetModuleHandle(0), 0); - SendMessage(hwnd, WM_SETFONT, (WPARAM)miu().p.default_font, 0); + phiro().default_hwnd, (HMENU)instance, GetModuleHandle(0), 0); + SendMessage(hwnd, WM_SETFONT, (WPARAM)phiro().default_font, 0); } void pLabel::set_text(const char *text) { diff --git a/src/lib/miu.win/miu.win.label.h b/src/lib/hiro_win/label.h similarity index 100% rename from src/lib/miu.win/miu.win.label.h rename to src/lib/hiro_win/label.h diff --git a/src/lib/miu.win/miu.win.listbox.cpp b/src/lib/hiro_win/listbox.cpp similarity index 95% rename from src/lib/miu.win/miu.win.listbox.cpp rename to src/lib/hiro_win/listbox.cpp index b97fb647..242f858b 100644 --- a/src/lib/miu.win/miu.win.listbox.cpp +++ b/src/lib/hiro_win/listbox.cpp @@ -10,8 +10,8 @@ uint vscroll = (style & Listbox::VerticalScrollAlways) ? WS_VSCROLL : WS_CHILD | WS_VISIBLE | LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_NOSORTHEADER | vscroll | hscroll | (header ? 0 : LVS_NOCOLUMNHEADER), 0, 0, width, height, - miu().p.default_hwnd, (HMENU)instance, GetModuleHandle(0), 0); - SendMessage(hwnd, WM_SETFONT, (WPARAM)miu().p.default_font, 0); + phiro().default_hwnd, (HMENU)instance, GetModuleHandle(0), 0); + SendMessage(hwnd, WM_SETFONT, (WPARAM)phiro().default_font, 0); ListView_SetExtendedListViewStyle(hwnd, LVS_EX_FULLROWSELECT); lstring list; diff --git a/src/lib/miu.win/miu.win.listbox.h b/src/lib/hiro_win/listbox.h similarity index 96% rename from src/lib/miu.win/miu.win.listbox.h rename to src/lib/hiro_win/listbox.h index e36b3a4d..ab60f45a 100644 --- a/src/lib/miu.win/miu.win.listbox.h +++ b/src/lib/hiro_win/listbox.h @@ -12,6 +12,6 @@ public: pListbox(Listbox&); -/* internal */ + /* internal */ uint column_count; }; diff --git a/src/lib/miu.win/miu.win.menucheckitem.cpp b/src/lib/hiro_win/menucheckitem.cpp similarity index 100% rename from src/lib/miu.win/miu.win.menucheckitem.cpp rename to src/lib/hiro_win/menucheckitem.cpp diff --git a/src/lib/miu.win/miu.win.menucheckitem.h b/src/lib/hiro_win/menucheckitem.h similarity index 100% rename from src/lib/miu.win/miu.win.menucheckitem.h rename to src/lib/hiro_win/menucheckitem.h diff --git a/src/lib/miu.win/miu.win.menucontrol.cpp b/src/lib/hiro_win/menucontrol.cpp similarity index 95% rename from src/lib/miu.win/miu.win.menucontrol.cpp rename to src/lib/hiro_win/menucontrol.cpp index 9e118af3..ffea43a6 100644 --- a/src/lib/miu.win/miu.win.menucontrol.cpp +++ b/src/lib/hiro_win/menucontrol.cpp @@ -21,5 +21,5 @@ pMenuControl::pMenuControl(MenuControl &self_) : pWidget(self_), self(self_) { } pMenuControl::~pMenuControl() { - safe_free(text); + if(text) free(text); } diff --git a/src/lib/miu.win/miu.win.menucontrol.h b/src/lib/hiro_win/menucontrol.h similarity index 92% rename from src/lib/miu.win/miu.win.menucontrol.h rename to src/lib/hiro_win/menucontrol.h index 5dc179b9..806a57cb 100644 --- a/src/lib/miu.win/miu.win.menucontrol.h +++ b/src/lib/hiro_win/menucontrol.h @@ -8,7 +8,7 @@ public: pMenuControl(MenuControl&); virtual ~pMenuControl(); -/* internal */ + /* internal */ HMENU parent; char *text; }; diff --git a/src/lib/miu.win/miu.win.menugroup.cpp b/src/lib/hiro_win/menugroup.cpp similarity index 100% rename from src/lib/miu.win/miu.win.menugroup.cpp rename to src/lib/hiro_win/menugroup.cpp diff --git a/src/lib/miu.win/miu.win.menugroup.h b/src/lib/hiro_win/menugroup.h similarity index 91% rename from src/lib/miu.win/miu.win.menugroup.h rename to src/lib/hiro_win/menugroup.h index da3bdaed..783ed800 100644 --- a/src/lib/miu.win/miu.win.menugroup.h +++ b/src/lib/hiro_win/menugroup.h @@ -6,6 +6,6 @@ public: pMenuGroup(MenuGroup&); -/* internal */ + /* internal */ HMENU group; }; diff --git a/src/lib/miu.win/miu.win.menuitem.cpp b/src/lib/hiro_win/menuitem.cpp similarity index 100% rename from src/lib/miu.win/miu.win.menuitem.cpp rename to src/lib/hiro_win/menuitem.cpp diff --git a/src/lib/miu.win/miu.win.menuitem.h b/src/lib/hiro_win/menuitem.h similarity index 100% rename from src/lib/miu.win/miu.win.menuitem.h rename to src/lib/hiro_win/menuitem.h diff --git a/src/lib/miu.win/miu.win.menuradioitem.cpp b/src/lib/hiro_win/menuradioitem.cpp similarity index 100% rename from src/lib/miu.win/miu.win.menuradioitem.cpp rename to src/lib/hiro_win/menuradioitem.cpp diff --git a/src/lib/miu.win/miu.win.menuradioitem.h b/src/lib/hiro_win/menuradioitem.h similarity index 93% rename from src/lib/miu.win/miu.win.menuradioitem.h rename to src/lib/hiro_win/menuradioitem.h index 2776ff64..406663c6 100644 --- a/src/lib/miu.win/miu.win.menuradioitem.h +++ b/src/lib/hiro_win/menuradioitem.h @@ -7,7 +7,7 @@ public: MenuRadioItem &self; pMenuRadioItem(MenuRadioItem&); -/* internal */ + /* internal */ MenuRadioItemGroup group; bool create_checked; }; diff --git a/src/lib/miu.win/miu.win.menuseparator.cpp b/src/lib/hiro_win/menuseparator.cpp similarity index 100% rename from src/lib/miu.win/miu.win.menuseparator.cpp rename to src/lib/hiro_win/menuseparator.cpp diff --git a/src/lib/miu.win/miu.win.menuseparator.h b/src/lib/hiro_win/menuseparator.h similarity index 100% rename from src/lib/miu.win/miu.win.menuseparator.h rename to src/lib/hiro_win/menuseparator.h diff --git a/src/lib/miu.win/miu.win.progressbar.cpp b/src/lib/hiro_win/progressbar.cpp similarity index 79% rename from src/lib/miu.win/miu.win.progressbar.cpp rename to src/lib/hiro_win/progressbar.cpp index 6518b28e..171342db 100644 --- a/src/lib/miu.win/miu.win.progressbar.cpp +++ b/src/lib/hiro_win/progressbar.cpp @@ -1,18 +1,18 @@ void pProgressbar::create(uint style, uint width, uint height) { hwnd = CreateWindow(PROGRESS_CLASS, "", WS_CHILD | WS_VISIBLE | PBS_SMOOTH, 0, 0, width, height, - miu().p.default_hwnd, (HMENU)instance, GetModuleHandle(0), 0); + phiro().default_hwnd, (HMENU)instance, GetModuleHandle(0), 0); SendMessage(hwnd, PBM_SETRANGE, 0, MAKELPARAM(0, 100)); SendMessage(hwnd, PBM_SETSTEP, MAKEWPARAM(1, 0), 0); } uint pProgressbar::get_progress() { uint progress = SendMessage(hwnd, PBM_GETPOS, 0, 0); - return max(0, min(progress, 100)); + return max(0U, min(progress, 100U)); } void pProgressbar::set_progress(uint progress) { - progress = max(0, min(progress, 100)); + progress = max(0U, min(progress, 100U)); SendMessage(hwnd, PBM_SETPOS, (WPARAM)progress, 0); } diff --git a/src/lib/miu.win/miu.win.progressbar.h b/src/lib/hiro_win/progressbar.h similarity index 100% rename from src/lib/miu.win/miu.win.progressbar.h rename to src/lib/hiro_win/progressbar.h diff --git a/src/lib/miu.win/miu.win.radiobox.cpp b/src/lib/hiro_win/radiobox.cpp similarity index 85% rename from src/lib/miu.win/miu.win.radiobox.cpp rename to src/lib/hiro_win/radiobox.cpp index f857db1d..66233dab 100644 --- a/src/lib/miu.win/miu.win.radiobox.cpp +++ b/src/lib/hiro_win/radiobox.cpp @@ -1,8 +1,8 @@ void pRadiobox::create(RadioboxGroup &group_, uint style, uint width, uint height, const char *text) { group = group_; hwnd = CreateWindow("BUTTON", text ? text : "", WS_CHILD | WS_VISIBLE | BS_RADIOBUTTON, - 0, 0, width, height, miu().p.default_hwnd, (HMENU)instance, GetModuleHandle(0), 0); - SendMessage(hwnd, WM_SETFONT, (WPARAM)miu().p.default_font, 0); + 0, 0, width, height, phiro().default_hwnd, (HMENU)instance, GetModuleHandle(0), 0); + SendMessage(hwnd, WM_SETFONT, (WPARAM)phiro().default_font, 0); if(group[0] == &self) check(); } diff --git a/src/lib/miu.win/miu.win.radiobox.h b/src/lib/hiro_win/radiobox.h similarity index 94% rename from src/lib/miu.win/miu.win.radiobox.h rename to src/lib/hiro_win/radiobox.h index 40dae4f7..48af9162 100644 --- a/src/lib/miu.win/miu.win.radiobox.h +++ b/src/lib/hiro_win/radiobox.h @@ -8,6 +8,6 @@ public: Radiobox &self; pRadiobox(Radiobox&); -/* internal */ + /* internal */ RadioboxGroup group; }; diff --git a/src/lib/miu.win/miu.win.slider.cpp b/src/lib/hiro_win/slider.cpp similarity index 92% rename from src/lib/miu.win/miu.win.slider.cpp rename to src/lib/hiro_win/slider.cpp index e41ad000..dca64aea 100644 --- a/src/lib/miu.win/miu.win.slider.cpp +++ b/src/lib/hiro_win/slider.cpp @@ -5,7 +5,7 @@ void pSlider::create(uint style, uint width, uint height, uint length) { WS_CHILD | WS_VISIBLE | TBS_NOTICKS | TBS_BOTH | (style & Slider::Vertical ? TBS_VERT : TBS_HORZ), 0, 0, width, height, - miu().p.default_hwnd, (HMENU)instance, GetModuleHandle(0), 0); + phiro().default_hwnd, (HMENU)instance, GetModuleHandle(0), 0); SendMessage(hwnd, TBM_SETRANGE, (WPARAM)true, (LPARAM)MAKELONG(0, length - 1)); SendMessage(hwnd, TBM_SETPAGESIZE, 0, (LPARAM)(length >> 3)); SendMessage(hwnd, TBM_SETPOS, (WPARAM)true, (LPARAM)0); diff --git a/src/lib/miu.win/miu.win.slider.h b/src/lib/hiro_win/slider.h similarity index 93% rename from src/lib/miu.win/miu.win.slider.h rename to src/lib/hiro_win/slider.h index 17b11e57..f87ec97a 100644 --- a/src/lib/miu.win/miu.win.slider.h +++ b/src/lib/hiro_win/slider.h @@ -7,6 +7,6 @@ public: pSlider(Slider&); -/* internal */ + /* internal */ uint slider_position; }; diff --git a/src/lib/miu.win/miu.win.widget.cpp b/src/lib/hiro_win/widget.cpp similarity index 93% rename from src/lib/miu.win/miu.win.widget.cpp rename to src/lib/hiro_win/widget.cpp index ea6b74a5..1e8c15a9 100644 --- a/src/lib/miu.win/miu.win.widget.cpp +++ b/src/lib/hiro_win/widget.cpp @@ -14,7 +14,7 @@ uintptr_t pWidget::handle() { pWidget::pWidget(Widget &self_) : self(self_) { instance = instance_counter++; - miu().p.widget_list.add(&self); + phiro().widget_list.add(&self); } pWidget::~pWidget() { diff --git a/src/lib/hiro_win/widget.h b/src/lib/hiro_win/widget.h new file mode 100644 index 00000000..a23b6bd9 --- /dev/null +++ b/src/lib/hiro_win/widget.h @@ -0,0 +1,19 @@ +class pWidget { +public: + Widget &self; + virtual void show(bool = true); + virtual void hide(); + virtual bool visible(); + virtual uintptr_t handle(); + + pWidget(Widget&); + virtual ~pWidget(); + + /* internal */ + + //Windows API controls often require a unique ID for each control to identify it. + //Simulate this with an instance counter, so that each Widget has a unique ID. + //In each pWidget() constructor, instance = instance_counter++; is called. + static uint instance_counter; + uint instance; +}; diff --git a/src/lib/miu.win/miu.win.window.cpp b/src/lib/hiro_win/window.cpp similarity index 68% rename from src/lib/miu.win/miu.win.window.cpp rename to src/lib/hiro_win/window.cpp index 460a37d1..d6de842f 100644 --- a/src/lib/miu.win/miu.win.window.cpp +++ b/src/lib/hiro_win/window.cpp @@ -4,16 +4,18 @@ void pWindow::create(uint style, uint width_, uint height_, const char *text) { RECT rc; SystemParametersInfo(SPI_GETWORKAREA, 0, &rc, 0); - hwnd = CreateWindowEx(0, "miu_window", text ? text : "", + hwnd = CreateWindowEx(0, "hiro_window", text ? text : "", WS_POPUP | WS_SYSMENU | WS_CAPTION | WS_MINIMIZEBOX, rc.left, rc.top, width_, height_, 0, 0, GetModuleHandle(0), 0); - hwndr = CreateWindowEx(0, "miu_window", text ? text : "", + hwndr = CreateWindowEx(0, "hiro_window", text ? text : "", WS_POPUP | WS_SYSMENU | WS_CAPTION | WS_MINIMIZEBOX, rc.left, rc.top, width_, height_, 0, 0, GetModuleHandle(0), 0); + hmenu = CreateMenu(); + hstatus = CreateWindowEx(0, STATUSCLASSNAME, "", + WS_CHILD, 0, 0, 0, 0, hwnd, 0, GetModuleHandle(0), 0); SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)this); - menu = CreateMenu(); resize(width_, height_); } @@ -49,6 +51,12 @@ RECT rc; width_ += width_ - (rc.right - rc.left); height_ += height_ - (rc.bottom - rc.top); + if(status.visible()) { + //statusbar does not count as part of window client area width, height + GetClientRect(hstatus, &rc); + height_ += rc.bottom - rc.top; + } + int x = (GetSystemMetrics(SM_CXSCREEN) - width_) / 2; int y = (GetSystemMetrics(SM_CYSCREEN) - height_) / 2; @@ -100,7 +108,23 @@ void pWindow::unfullscreen() { resize(width, height); } -void pWindow::set_background_color(uint8 r, uint8 g, uint8 b) { +uint pWindow::get_width() { + RECT rc; + GetClientRect(hwnd, &rc); + return rc.right - rc.left; +} + +uint pWindow::get_height() { + RECT rc; + GetClientRect(hwnd, &rc); + if(status.visible() == false) return rc.bottom - rc.top; + //do not include statusbar in client area height + RECT src; + GetClientRect(hstatus, &src); + return (rc.bottom - rc.top) - (src.bottom - src.top); +} + +void pWindow::set_background_color(uint8_t r, uint8_t g, uint8_t b) { if(background) DeleteObject(background); background = CreateSolidBrush(RGB(r, g, b)); } @@ -125,7 +149,7 @@ RECT rc; } void pWindow::attach(MenuGroup &menugroup) { - AppendMenu(menu, MF_STRING | MF_POPUP, (uint)menugroup.p.group, menugroup.p.text); + AppendMenu(hmenu, MF_STRING | MF_POPUP, (uint)menugroup.p.group, menugroup.p.text); if(menu_visible() == false) menu_show(); } @@ -142,11 +166,69 @@ void pWindow::move(FormControl &formcontrol, uint x, uint y) { SetWindowPos(formcontrol.p.hwnd, 0, x, y, 0, 0, SWP_NOSIZE | SWP_NOZORDER); } +/* pWindow -> Menubar */ + +void pWindow::Menubar::show(bool state) { + p.menu_show(state); +} + +void pWindow::Menubar::hide() { + p.menu_hide(); +} + +bool pWindow::Menubar::visible() { + return p.menu_visible(); +} + +pWindow::Menubar::Menubar(pWindow &p_) : p(p_) { +} + +/* pWindow -> Statusbar */ + +void pWindow::Statusbar::set_text(const char *text) { + p.status_set_text(text); +} + +void pWindow::Statusbar::show(bool state) { + p.status_show(state); +} + +void pWindow::Statusbar::hide() { + p.status_hide(); +} + +bool pWindow::Statusbar::visible() { + return p.status_visible(); +} + +pWindow::Statusbar::Statusbar(pWindow &p_) : p(p_) { +} + +pWindow::pWindow(Window &self_) : pWidget(self_), self(self_), menu(*this), status(*this) { + hwnd = 0; + hwndr = 0; + hmenu = 0; + background = 0; + is_fullscreen = false; + auto_center = false; + width = 0; + height = 0; +} + +pWindow::~pWindow() { + if(background) DeleteObject(background); +} + +/* internal */ + +uintptr_t pWindow::handle() { + return (uintptr_t)hwnd; +} + void pWindow::menu_show(bool state) { - if(!menu) return; if(state) { - SetMenu(hwnd, menu); - SetMenu(hwndr, menu); + SetMenu(hwnd, hmenu); + SetMenu(hwndr, hmenu); } else { SetMenu(hwnd, 0); SetMenu(hwndr, 0); @@ -159,25 +241,22 @@ void pWindow::menu_hide() { } bool pWindow::menu_visible() { - if(!menu) return false; return GetMenu(hwnd); } -uintptr_t pWindow::handle() { - return (uintptr_t)hwnd; +void pWindow::status_set_text(const char *text) { + SendMessage(hstatus, SB_SETTEXT, 0, (LPARAM)text); } -pWindow::pWindow(Window &self_) : pWidget(self_), self(self_) { - hwnd = 0; - hwndr = 0; - menu = 0; - background = 0; - is_fullscreen = false; - auto_center = false; - width = 0; - height = 0; +void pWindow::status_show(bool state) { + ShowWindow(hstatus, state ? SW_SHOWNORMAL : SW_HIDE); + resize(width, height); } -pWindow::~pWindow() { - if(background) DeleteObject(background); +void pWindow::status_hide() { + status_show(false); +} + +bool pWindow::status_visible() { + return GetWindowLong(hstatus, GWL_STYLE) & WS_VISIBLE; } diff --git a/src/lib/miu.win/miu.win.window.h b/src/lib/hiro_win/window.h similarity index 59% rename from src/lib/miu.win/miu.win.window.h rename to src/lib/hiro_win/window.h index eeefebc2..71693fbe 100644 --- a/src/lib/miu.win/miu.win.window.h +++ b/src/lib/hiro_win/window.h @@ -1,6 +1,5 @@ class pWindow : public pWidget { public: - Window &self; void create(uint style, uint width, uint height, const char *text = ""); void close(); void move(uint x, uint y); @@ -9,31 +8,63 @@ public: bool focused(); void fullscreen(); void unfullscreen(); - void set_background_color(uint8 r, uint8 g, uint8 b); + uint get_width(); + uint get_height(); + void set_background_color(uint8_t r, uint8_t g, uint8_t b); void set_text(const char *text = ""); void attach(Window &window, uint x, uint y); void attach(MenuGroup &menugroup); void attach(FormControl &formcontrol, uint x, uint y); void move(Window &window, uint x, uint y); void move(FormControl &formcontrol, uint x, uint y); - void menu_show(bool = true); - void menu_hide(); - bool menu_visible(); - uintptr_t handle(); + class Statusbar { + public: + void set_text(const char *text = ""); + void show(bool = true); + void hide(); + bool visible(); + + pWindow &p; + Statusbar(pWindow&); + } status; + + class Menubar { + public: + void show(bool = true); + void hide(); + bool visible(); + + pWindow &p; + Menubar(pWindow&); + } menu; + + Window &self; pWindow(Window&); ~pWindow(); -/* internal */ + /* internal */ HWND hwnd; HWND hwndr; //hidden window, used as resize assistant - HMENU menu; + HMENU hmenu; + HWND hstatus; HBRUSH background; bool is_fullscreen; bool auto_center; uint width, height; + uintptr_t handle(); + void show(bool = true); void hide(); bool visible(); + + void menu_show(bool = true); + void menu_hide(); + bool menu_visible(); + + void status_set_text(const char *text = ""); + void status_show(bool = true); + void status_hide(); + bool status_visible(); }; diff --git a/src/lib/libco.c b/src/lib/libco.c new file mode 100644 index 00000000..0e7d3761 --- /dev/null +++ b/src/lib/libco.c @@ -0,0 +1,21 @@ +/* + libco + auto-selection module + license: public domain +*/ + +#if defined(__GNUC__) && defined(__i386__) + #include "libco/x86.c" +#elif defined(__GNUC__) && defined(__amd64__) && !defined(__MINGW64__) + #include "libco/x86-64.c" +#elif defined(__MINGW64__) + #include "libco/fiber.c" +#elif defined(__GNUC__) + #include "libco/sjlj.c" +#elif defined(_MSC_VER) && defined(_M_IX86) + #include "libco/x86.c" +#elif defined(_MSC_VER) && defined(_M_AMD64) + #include "libco/fiber.c" +#else + #error "libco: unsupported processor, compiler or operating system" +#endif diff --git a/src/lib/libco.h b/src/lib/libco.h index 74cf8bc6..d8348c4e 100644 --- a/src/lib/libco.h +++ b/src/lib/libco.h @@ -1,37 +1,34 @@ /* libco - version: 0.11 (2007-12-11) + version: 0.13 rc2 (2008-01-28) license: public domain */ #ifndef LIBCO_H #define LIBCO_H +#ifdef LIBCO_C + #ifdef LIBCO_MP + #define thread_local __thread + #else + #define thread_local + #endif +#endif + #ifdef __cplusplus extern "C" { #endif -#if defined(__i386__) - #if defined(__GNUC__) - #define calltype __attribute__((fastcall)) - #elif defined(_MSC_VER) - #define calltype __fastcall - #endif -#else - #define calltype -#endif - typedef void* cothread_t; -cothread_t calltype co_active(); -cothread_t calltype co_create(unsigned int heapsize, void (*coentry)()); -void calltype co_delete(cothread_t cothread); -void calltype co_switch(cothread_t cothread); - -#undef calltype +cothread_t co_active(); +cothread_t co_create(unsigned int, void (*)(void)); +void co_delete(cothread_t); +void co_switch(cothread_t); #ifdef __cplusplus -} //extern "C" +} #endif -#endif //ifndef LIBCO_H +/* ifndef LIBCO_H */ +#endif diff --git a/src/lib/libco/fiber.c b/src/lib/libco/fiber.c new file mode 100644 index 00000000..d1b39586 --- /dev/null +++ b/src/lib/libco/fiber.c @@ -0,0 +1,51 @@ +/* + libco.win (2008-01-28) + authors: Nach, byuu + license: public domain +*/ + +#define LIBCO_C +#include "../libco.h" +#define WINVER 0x0400 +#define _WIN32_WINNT 0x0400 +#define WIN32_LEAN_AND_MEAN +#include + +#ifdef __cplusplus +extern "C" { +#endif + +static thread_local cothread_t co_active_ = 0; + +static void __stdcall co_thunk(void *coentry) { + ((void (*)(void))coentry)(); +} + +cothread_t co_active() { + if(!co_active_) { + ConvertThreadToFiber(0); + co_active_ = GetCurrentFiber(); + } + return co_active_; +} + +cothread_t co_create(unsigned int heapsize, void (*coentry)(void)) { + if(!co_active_) { + ConvertThreadToFiber(0); + co_active_ = GetCurrentFiber(); + } + return (cothread_t)CreateFiber(heapsize, co_thunk, (void*)coentry); +} + +void co_delete(cothread_t cothread) { + DeleteFiber(cothread); +} + +void co_switch(cothread_t cothread) { + co_active_ = cothread; + SwitchToFiber(cothread); +} + +#ifdef __cplusplus +} +#endif diff --git a/src/lib/libco/libco.ucontext.cpp b/src/lib/libco/libco.ucontext.cpp deleted file mode 100644 index da236326..00000000 --- a/src/lib/libco/libco.ucontext.cpp +++ /dev/null @@ -1,80 +0,0 @@ -/* - libco.ucontext (2007-09-08) - author: byuu - license: public domain -*/ - -#include -#include -#include "../libco.h" - -//WARNING: the overhead of POSIX ucontext is very high, -//averaging ~450x that of standard subroutine calls. -//(tested on FreeBSD 6.2-RELEASE) -//By contrast, on the same system, libco_x86's overhead -//is ~7.25x standard subroutine calls; or fifty times faster. -// -//This library only exists for two reasons: -//1 - as an initial test for the viability of a ucontext implementation -//2 - to demonstrate the power and speed of libco over existing implementations, -// such as pth (which defaults to wrapping ucontext on unix targets) -// -//Use this library only as a *last resort* - -struct cothread_struct { - ucontext_t cohandle; - void (*coentry)(); -}; - -cothread_t __co_active = 0, __co_primary = 0; -void co_entrypoint(cothread_t cothread); -void co_init(); - -/***** - * library functions - *****/ - -cothread_t co_active() { - if(__co_primary == 0)co_init(); - return __co_active; -} - -cothread_t co_create(unsigned int heapsize, void (*coentry)()) { - if(__co_primary == 0)co_init(); -cothread_struct *thread = (cothread_struct*)malloc(sizeof(cothread_struct)); - thread->coentry = coentry; - getcontext(&thread->cohandle); - heapsize += 512; - thread->cohandle.uc_stack.ss_sp = (char*)malloc(heapsize); - thread->cohandle.uc_stack.ss_size = heapsize; - makecontext(&thread->cohandle, (void (*)())co_entrypoint, 1, thread); - return (cothread_t)thread; -} - -void co_delete(cothread_t cothread) { -cothread_struct *thread = (cothread_struct*)cothread; - free(thread->cohandle.uc_stack.ss_sp); - free(thread); -} - -void co_switch(cothread_t cothread) { -cothread_struct *active = (cothread_struct*)__co_active; -cothread_struct *swap = (cothread_struct*)cothread; - __co_active = cothread; - swapcontext(&active->cohandle, &swap->cohandle); -} - -/***** - * internal functions - *****/ - -void co_entrypoint(cothread_t cothread) { - ((cothread_struct*)cothread)->coentry(); -} - -void co_init() { -cothread_struct *thread = (cothread_struct*)malloc(sizeof(cothread_struct)); - thread->coentry = 0; - getcontext(&thread->cohandle); - __co_active = __co_primary = (cothread_t)thread; -} diff --git a/src/lib/libco/libco.win.cpp b/src/lib/libco/libco.win.cpp deleted file mode 100644 index f0d16626..00000000 --- a/src/lib/libco/libco.win.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/* - libco.win (2007-09-08) - author: byuu - license: public domain -*/ - -#define WINVER 0x0400 -#define _WIN32_WINNT 0x0400 -#include -#include "../libco.h" - -struct cothread_struct { - void *cohandle; - void (*coentry)(); -}; - -cothread_t __co_active = 0, __co_primary = 0; - -void __stdcall co_entryproc(void*); -cothread_t co_init(); - -/***** - * library functions - *****/ - -cothread_t co_active() { - if(__co_primary == 0)co_init(); - return __co_active; -} - -cothread_t co_create(unsigned int heapsize, void (*coentry)()) { - if(__co_primary == 0)co_init(); -cothread_struct *s = (cothread_struct*)malloc(sizeof(cothread_struct)); - s->coentry = coentry; - s->cohandle = CreateFiber(heapsize + 512, co_entryproc, (void*)s); - return (cothread_t)s; -} - -void co_delete(cothread_t cothread) { -cothread_struct *s = (cothread_struct*)cothread; - DeleteFiber(s->cohandle); - free(cothread); -} - -void co_switch(cothread_t cothread) { - __co_active = cothread; -cothread_struct *s = (cothread_struct*)cothread; - SwitchToFiber(s->cohandle); -} - -/***** - * internal functions - *****/ - -void __stdcall co_entryproc(void *cothread) { - ((cothread_struct*)cothread)->coentry(); -} - -cothread_t co_init() { - ConvertThreadToFiber(0); -cothread_struct *s = (cothread_struct*)malloc(sizeof(cothread_struct)); - s->coentry = 0; - s->cohandle = GetCurrentFiber(); - __co_active = __co_primary = (cothread_t)s; - return __co_active; -} diff --git a/src/lib/libco/libco.x86-64.asm b/src/lib/libco/libco.x86-64.asm deleted file mode 100644 index 051987f0..00000000 --- a/src/lib/libco/libco.x86-64.asm +++ /dev/null @@ -1,146 +0,0 @@ -;***** -;libco.x86-64 (2007-12-11) -;author: byuu -;license: public domain -; -;cross-platform x86-64 implementation of libco -;thanks to Aaron Giles and Joel Yliluoma for various optimizations -;thanks to Lucas Newman and Vas Crabb for assistance with OS X support -; -;[ABI compatibility] -;- SystemV ( http://refspecs.freestandards.org/elf/x86_64-SysV-psABI.pdf ) -;- gcc; mac os x; x86-64 -;- gcc; linux; x86-64 -;- gcc; freebsd; x86-64 -; -;[nonvolatile registers] -;- rsp, rbp, rbx, r12, r13, r14, r15 -; -;[volatile registers] -;- rax, rcx, rdx, r8, r9, r10, r11, rdi, rsi -;- st0 - st7 -;- xmm0 - xmm15 -;***** - -;***** -;linker-specific name decorations -;***** - -%ifdef OSX -%define malloc _malloc -%define free _free - -%define co_active _co_active -%define co_create _co_create -%define co_delete _co_delete -%define co_switch _co_switch -%endif - -bits 64 - -section .bss - -align 8 -co_primary_buffer resb 512 - -section .data - -align 8 -co_active_context dq co_primary_buffer - -section .text - -extern malloc -extern free - -global co_active -global co_create -global co_delete -global co_switch - -;***** -;extern "C" cothread_t co_active(); -;return = rax -;***** - -align 16 -co_active: - mov rax,[co_active_context wrt rip] - ret - -;***** -;extern "C" cothread_t co_create(unsigned int heapsize, void (*coentry)()); -;rdi = heapsize -;rsi = coentry -;return = rax -;***** - -align 16 -co_create: -;create heap space (stack + context) - add rdi,512 ;allocate extra memory for contextual info - - push rdi ;backup volatile registers before malloc call - push rsi - - sub rsp,8 ;SSE 16-byte stack alignment - call malloc ;rax = malloc(rdi) - add rsp,8 - - pop rsi ;restore volatile registers - pop rdi - - add rdi,rax ;set rdi to point to top of stack heap - and rdi,-16 ;force 16-byte alignment of stack heap - -;store thread entry point + registers, so that first call to co_switch will execute coentry - mov qword[rdi-8],0 ;crash if entry point returns - mov qword[rdi-16],rsi ;entry point - mov qword[rdi-24],0 ;r15 - mov qword[rdi-32],0 ;r14 - mov qword[rdi-40],0 ;r13 - mov qword[rdi-48],0 ;r12 - mov qword[rdi-56],0 ;rbx - mov qword[rdi-64],0 ;rbp - sub rdi,64 - -;initialize context memory heap and return - mov [rax],rdi ;*cothread_t = stack heap pointer (rsp) - ret ;return allocated memory block as thread handle - -;***** -;extern "C" void co_delete(cothread_t cothread); -;rdi = cothread -;***** - -align 16 -co_delete: - jmp free ;free(rdi) - -;***** -;extern "C" void co_switch(cothread_t cothread); -;rdi = cothread -;***** - -align 16 -co_switch: - mov rax,[co_active_context wrt rip] ;backup current context - mov [co_active_context wrt rip],rdi ;set new active context - - push rbp - push rbx - push r12 - push r13 - push r14 - push r15 - mov [rax],rsp - - mov rsp,[rdi] - pop r15 - pop r14 - pop r13 - pop r12 - pop rbx - pop rbp - - ret diff --git a/src/lib/libco/libco.x86.asm b/src/lib/libco/libco.x86.asm deleted file mode 100644 index f151c4a8..00000000 --- a/src/lib/libco/libco.x86.asm +++ /dev/null @@ -1,155 +0,0 @@ -;***** -;libco.x86 (2007-12-11) -;author: byuu -;license: public domain -; -;cross-platform x86 implementation of libco -;thanks to Aaron Giles and Joel Yliluoma for various optimizations -;thanks to Lucas Newman and Vas Crabb for assistance with OS X support -; -;[ABI compatibility] -;- visual c++; windows; x86 -;- mingw; windows; x86 -;- gcc; mac os x; x86 -;- gcc; linux; x86 -;- gcc; freebsd; x86 -; -;[nonvolatile registers] -;- esp, ebp, edi, esi, ebx -; -;[volatile registers] -;- eax, ecx, edx -;- st0 - st7 -;- xmm0 - xmm15 -;***** - -;***** -;linker-specific name decorations -;***** - -%ifdef WIN -%define malloc _malloc -%define free _free - -%define co_active @co_active@0 -%define co_create @co_create@8 -%define co_delete @co_delete@4 -%define co_switch @co_switch@4 -%endif - -%ifdef OSX -%define malloc _malloc -%define free _free - -%define co_active _co_active -%define co_create _co_create -%define co_delete _co_delete -%define co_switch _co_switch -%endif - -bits 32 - -section .bss - -align 4 -co_primary_buffer resb 512 - -section .data - -align 4 -co_active_context dd co_primary_buffer - -section .text - -extern malloc -extern free - -global co_active -global co_create -global co_delete -global co_switch - -;***** -;extern "C" cothread_t fastcall co_active(); -;return = eax -;***** - -align 16 -co_active: - mov eax,[co_active_context] - ret - -;***** -;extern "C" cothread_t fastcall co_create(unsigned int heapsize, void (*coentry)()); -;ecx = heapsize -;edx = coentry -;return = eax -;***** - -align 16 -co_create: -;create heap space (stack + context) - add ecx,512 ;allocate extra memory for contextual info - - push ecx ;backup volatile registers before malloc call - push edx - - push ecx - call malloc ;eax = malloc(ecx) - add esp,4 - - pop edx ;restore volatile registers - pop ecx - - add ecx,eax ;set edx to point to top of stack heap - and ecx,-16 ;force 16-byte alignment of stack heap - -;store thread entry point + registers, so that first call to co_switch will execute coentry - mov dword[ecx-4],0 ;crash if entry point returns - mov dword[ecx-8],edx ;entry point - mov dword[ecx-12],0 ;ebp - mov dword[ecx-16],0 ;esi - mov dword[ecx-20],0 ;edi - mov dword[ecx-24],0 ;ebx - sub ecx,24 - -;initialize context memory heap and return - mov [eax],ecx ;*cothread_t = stack heap pointer (esp) - ret ;return allocated memory block as thread handle - -;***** -;extern "C" void fastcall co_delete(cothread_t cothread); -;ecx = cothread -;***** - -align 16 -co_delete: - sub esp,8 ;SSE 16-byte stack alignment - push ecx - call free ;free(ecx) - add esp,4+8 - ret - -;***** -;extern "C" void fastcall co_switch(cothread_t cothread); -;ecx = cothread -;***** - -align 16 -co_switch: - mov eax,[co_active_context] ;backup current context - mov [co_active_context],ecx ;set new active context - - push ebp - push esi - push edi - push ebx - mov [eax],esp - - mov esp,[ecx] - pop ebx - pop edi - pop esi - pop ebp - - ret diff --git a/src/lib/libco/libco.ppc.s b/src/lib/libco/ppc.s similarity index 100% rename from src/lib/libco/libco.ppc.s rename to src/lib/libco/ppc.s diff --git a/src/lib/libco/libco.ppc64.s b/src/lib/libco/ppc64.s similarity index 100% rename from src/lib/libco/libco.ppc64.s rename to src/lib/libco/ppc64.s diff --git a/src/lib/libco/sjlj.c b/src/lib/libco/sjlj.c new file mode 100644 index 00000000..86b2ea26 --- /dev/null +++ b/src/lib/libco/sjlj.c @@ -0,0 +1,102 @@ +/* + libco.sjlj (2008-01-28) + author: Nach + license: public domain +*/ + +/* + * Note this was designed for UNIX systems. Based on ideas expressed in a paper + * by Ralf Engelschall. + * For SJLJ on other systems, one would want to rewrite springboard() and + * co_create() and hack the jmb_buf stack pointer. + */ + +#define LIBCO_C +#include "../libco.h" +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + sigjmp_buf context; + void (*coentry)(void); + void *stack; +} cothread_struct; + +static thread_local cothread_struct co_primary; +static thread_local cothread_struct *creating, *co_running = 0; + +static void springboard(int ignored) { + if(sigsetjmp(creating->context, 0)) { + co_running->coentry(); + } +} + +cothread_t co_active() { + if(!co_running) co_running = &co_primary; + return (cothread_t)co_running; +} + +cothread_t co_create(unsigned int size, void (*coentry)(void)) { + if(!co_running) co_running = &co_primary; + + cothread_struct *thread = (cothread_struct*)malloc(sizeof(cothread_struct)); + if(thread) { + struct sigaction handler; + struct sigaction old_handler; + + stack_t stack; + stack_t old_stack; + + thread->coentry = thread->stack = 0; + + stack.ss_flags = 0; + stack.ss_size = size; + thread->stack = stack.ss_sp = malloc(size); + if(stack.ss_sp && !sigaltstack(&stack, &old_stack)) { + handler.sa_handler = springboard; + handler.sa_flags = SA_ONSTACK; + sigemptyset(&handler.sa_mask); + creating = thread; + + if(!sigaction(SIGUSR1, &handler, &old_handler)) { + if(!raise(SIGUSR1)) { + thread->coentry = coentry; + } + sigaltstack(&old_stack, 0); + sigaction(SIGUSR1, &old_handler, 0); + } + } + + if(thread->coentry != coentry) { + co_delete(thread); + thread = 0; + } + } + + return (cothread_t)thread; +} + +void co_delete(cothread_t cothread) { + if(cothread) { + if(((cothread_struct*)cothread)->stack) { + free(((cothread_struct*)cothread)->stack); + } + free(cothread); + } +} + +void co_switch(cothread_t cothread) { + if(!sigsetjmp(co_running->context, 0)) { + co_running = (cothread_struct*)cothread; + siglongjmp(co_running->context, 1); + } +} + +#ifdef __cplusplus +} +#endif diff --git a/src/lib/libco/ucontext.c b/src/lib/libco/ucontext.c new file mode 100644 index 00000000..47766e64 --- /dev/null +++ b/src/lib/libco/ucontext.c @@ -0,0 +1,67 @@ +/* + libco.ucontext (2008-01-28) + author: Nach + license: public domain +*/ + +/* + * WARNING: the overhead of POSIX ucontext is very high, + * assembly versions of libco or libco_sjlj should be much faster + * + * This library only exists for two reasons: + * 1 - as an initial test for the viability of a ucontext implementation + * 2 - to demonstrate the power and speed of libco over existing implementations, + * such as pth (which defaults to wrapping ucontext on unix targets) + * + * Use this library only as a *last resort* + */ + +#define LIBCO_C +#include "../libco.h" +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +static thread_local ucontext_t co_primary; +static thread_local ucontext_t *co_running = 0; + +cothread_t co_active() { + if(!co_running) co_running = &co_primary; + return (cothread_t)co_running; +} + +cothread_t co_create(unsigned int heapsize, void (*coentry)(void)) { + if(!co_running) co_running = &co_primary; + ucontext_t *thread = (ucontext_t*)malloc(sizeof(ucontext_t)); + if(thread) { + if((!getcontext(thread) && !(thread->uc_stack.ss_sp = 0)) && (thread->uc_stack.ss_sp = malloc(heapsize))) { + thread->uc_link = co_running; + thread->uc_stack.ss_size = heapsize; + makecontext(thread, coentry, 0); + } else { + co_delete((cothread_t)thread); + thread = 0; + } + } + return (cothread_t)thread; +} + +void co_delete(cothread_t cothread) { + if(cothread) { + if(((ucontext_t*)cothread)->uc_stack.ss_sp) { free(((ucontext_t*)cothread)->uc_stack.ss_sp); } + free(cothread); + } +} + +void co_switch(cothread_t cothread) { + ucontext_t *old_thread = co_running; + co_running = (ucontext_t*)cothread; + swapcontext(old_thread, co_running); +} + +#ifdef __cplusplus +} +#endif diff --git a/src/lib/libco/x86-64.c b/src/lib/libco/x86-64.c new file mode 100644 index 00000000..e1e8c7f3 --- /dev/null +++ b/src/lib/libco/x86-64.c @@ -0,0 +1,81 @@ +/* + libco.x86-64 (2008-01-28) + author: byuu + license: public domain +*/ + +#define LIBCO_C +#include "../libco.h" +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +static thread_local long co_active_buffer[32]; +static thread_local cothread_t co_active_ = 0; + +static void crash() { + assert(0); /* called only if cothread_t entrypoint returns */ +} + +cothread_t co_active() { + if(!co_active_) co_active_ = &co_active_buffer; + return co_active_; +} + +cothread_t co_create(unsigned int size, void (*entrypoint)(void)) { + cothread_t handle; + assert(sizeof(long) == 8); + if(!co_active_) co_active_ = &co_active_buffer; + size += 128; /* allocate additional space for storage */ + size &= ~15; /* align stack to 16-byte boundary */ + + if(handle = (cothread_t)calloc(size, 1)) { + long *p = (long*)((char*)handle + size); /* seek to top of stack */ + *--p = (long)crash; /* crash if entrypoint returns */ + *--p = (long)entrypoint; /* start of function */ + *(long*)handle = (long)p; /* stack pointer */ + } + + return handle; +} + +void co_delete(cothread_t handle) { + free(handle); +} + +void co_switch(cothread_t to) { + register long stack = *(long*)to; /* stack[0] = "to" thread entry point */ + register cothread_t from = co_active_; + co_active_ = to; + + __asm__ __volatile__( + "movq %%rsp,(%1) \n\t" /* save old stack pointer */ + "movq (%0),%%rsp \n\t" /* load new stack pointer */ + "addq $8,%%rsp \n\t" /* "pop" return address off stack */ + + "movq %%rbp, 8(%1) \n\t" /* backup non-volatile registers */ + "movq %%rbx,16(%1) \n\t" + "movq %%r12,24(%1) \n\t" + "movq %%r13,32(%1) \n\t" + "movq %%r14,40(%1) \n\t" + "movq %%r15,48(%1) \n\t" + + "movq 8(%0),%%rbp \n\t" /* restore non-volatile registers */ + "movq 16(%0),%%rbx \n\t" + "movq 24(%0),%%r12 \n\t" + "movq 32(%0),%%r13 \n\t" + "movq 40(%0),%%r14 \n\t" + "movq 48(%0),%%r15 \n\t" + + "jmp *(%2) \n\t" /* jump into "to" thread */ + : /* no outputs */ + : "r" (to), "r" (from), "r" (stack) + ); +} + +#ifdef __cplusplus +} +#endif diff --git a/src/lib/libco/x86.c b/src/lib/libco/x86.c new file mode 100644 index 00000000..18af8ac4 --- /dev/null +++ b/src/lib/libco/x86.c @@ -0,0 +1,110 @@ +/* + libco.x86 (2008-01-28) + author: byuu + license: public domain +*/ + +#define LIBCO_C +#include "../libco.h" +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +static thread_local long co_active_buffer[32]; +static thread_local cothread_t co_active_ = 0; + +static void crash() { + assert(0); /* called only if cothread_t entrypoint returns */ +} + +cothread_t co_active() { + if(!co_active_) co_active_ = &co_active_buffer; + return co_active_; +} + +cothread_t co_create(unsigned int size, void (*entrypoint)(void)) { + cothread_t handle; + assert(sizeof(long) == 4); + if(!co_active_) co_active_ = &co_active_buffer; + size += 128; /* allocate additional space for storage */ + size &= ~15; /* align stack to 16-byte boundary */ + + if(handle = (cothread_t)calloc(size, 1)) { + long *p = (long*)((char*)handle + size); /* seek to top of stack */ + *--p = (long)crash; /* crash if entrypoint returns */ + *--p = (long)entrypoint; /* start of function */ + *(long*)handle = (long)p; /* stack pointer */ + } + + return handle; +} + +void co_delete(cothread_t handle) { + free(handle); +} + +#if defined(__GNUC__) + +void co_switch(cothread_t to) { + register long stack = *(long*)to; /* stack[0] = "to" thread entry point */ + register cothread_t from = co_active_; + co_active_ = to; + + __asm__ __volatile__( + "movl %%esp,(%1) \n\t" /* save old stack pointer */ + "movl (%0),%%esp \n\t" /* load new stack pointer */ + "addl $4,%%esp \n\t" /* "pop" return address off stack */ + + "movl %%ebp, 4(%1) \n\t" /* backup non-volatile registers */ + "movl %%esi, 8(%1) \n\t" + "movl %%edi,12(%1) \n\t" + "movl %%ebx,16(%1) \n\t" + + "movl 4(%0),%%ebp \n\t" /* restore non-volatile registers */ + "movl 8(%0),%%esi \n\t" + "movl 12(%0),%%edi \n\t" + "movl 16(%0),%%ebx \n\t" + + "jmp *(%2) \n\t" /* jump into "to" thread */ + : /* no outputs */ + : "r" (to), "r" (from), "r" (stack) + ); +} + +#elif defined(_MSC_VER) + +__declspec(naked) __declspec(noinline) +static void __fastcall co_swap(register cothread_t to, register cothread_t from) { + /* ecx = to, edx = from */ + __asm { + mov [edx],esp + mov esp,[ecx] + pop eax + + mov [edx+ 4],ebp + mov [edx+ 8],esi + mov [edx+12],edi + mov [edx+16],ebx + + mov ebp,[ecx+ 4] + mov esi,[ecx+ 8] + mov edi,[ecx+12] + mov ebx,[ecx+16] + + jmp eax + } +} + +void co_switch(cothread_t handle) { + register cothread_t co_prev_ = co_active_; + co_swap(co_active_ = handle, co_prev_); +} + +#endif + +#ifdef __cplusplus +} +#endif diff --git a/src/lib/miu.gtk/miu.gtk.cpp b/src/lib/miu.gtk/miu.gtk.cpp deleted file mode 100644 index f5391c13..00000000 --- a/src/lib/miu.gtk/miu.gtk.cpp +++ /dev/null @@ -1,118 +0,0 @@ -#include "miu.gtk.h" -#include "../miu.cpp" - -namespace ns_miu { - -#include "miu.gtk.keymap.cpp" -#include "miu.gtk.widget.cpp" - #include "miu.gtk.window.cpp" - #include "miu.gtk.menucontrol.cpp" - #include "miu.gtk.menugroup.cpp" - #include "miu.gtk.menuitem.cpp" - #include "miu.gtk.menucheckitem.cpp" - #include "miu.gtk.menuradioitem.cpp" - #include "miu.gtk.menuseparator.cpp" - #include "miu.gtk.formcontrol.cpp" - #include "miu.gtk.frame.cpp" - #include "miu.gtk.canvas.cpp" - #include "miu.gtk.label.cpp" - #include "miu.gtk.button.cpp" - #include "miu.gtk.checkbox.cpp" - #include "miu.gtk.radiobox.cpp" - #include "miu.gtk.editbox.cpp" - #include "miu.gtk.listbox.cpp" - #include "miu.gtk.combobox.cpp" - #include "miu.gtk.progressbar.cpp" - #include "miu.gtk.slider.cpp" - -void pMiu::init() { -//simulate passing argc, argv to gtk_init() -int argc = 1; -char **argv; - argv = (char**)malloc(1 * sizeof(char*)); - argv[0] = (char*)malloc(64 * sizeof(char)); - strcpy(argv[0], "./miu"); - gtk_init(&argc, &argv); - safe_free(argv[0]); - safe_free(argv); -} - -void pMiu::term() { -} - -bool pMiu::run() { - gtk_main_iteration_do(false); - return pending(); -} - -bool pMiu::pending() { - return gtk_events_pending(); -} - -bool pMiu::file_load(Window *focus, char *filename, const char *filter, const char *path) { - if(!filename) return false; - strcpy(filename, ""); - -GtkWidget *dialog = gtk_file_chooser_dialog_new("Load File", - focus ? GTK_WINDOW(focus->p.gtk_handle()) : (GtkWindow*)0, - GTK_FILE_CHOOSER_ACTION_OPEN, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, - (const gchar*)0); - - if(path && *path) gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), path); - - if(gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { - char *fn = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); - strcpy(filename, fn); - g_free(fn); - } - - gtk_widget_destroy(dialog); - return strcmp(filename, ""); //return true if filename exists -} - -bool pMiu::file_save(Window *focus, char *filename, const char *filter, const char *path) { - if(!filename) return false; - strcpy(filename, ""); - -GtkWidget *dialog = gtk_file_chooser_dialog_new("Save File", - focus ? GTK_WINDOW(focus->p.gtk_handle()) : (GtkWindow*)0, - GTK_FILE_CHOOSER_ACTION_SAVE, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, - (const gchar*)0); - - if(path && *path) gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), path); - gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), TRUE); - - if(gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { - char *fn = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); - strcpy(filename, fn); - g_free(fn); - } - - gtk_widget_destroy(dialog); - return strcmp(filename, ""); //return true if filename exists -} - -uint pMiu::screen_width() { - return gdk_screen_width(); -} - -uint pMiu::screen_height() { - return gdk_screen_height(); -} - -pMiu& pMiu::handle() { - return miu().p; -} - -pMiu::pMiu(Miu &self_) : self(self_) { -} - -pMiu& pmiu() { - return pMiu::handle(); -} - -} //namespace ns_miu diff --git a/src/lib/miu.gtk/miu.gtk.h b/src/lib/miu.gtk/miu.gtk.h deleted file mode 100644 index 9aba9374..00000000 --- a/src/lib/miu.gtk/miu.gtk.h +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef MIU_GTK_H -#define MIU_GTK_H - -#include "../miu.h" - -#include -#include -#include - -namespace ns_miu { - -#include "miu.gtk.widget.h" - #include "miu.gtk.window.h" - #include "miu.gtk.menucontrol.h" - #include "miu.gtk.menugroup.h" - #include "miu.gtk.menuitem.h" - #include "miu.gtk.menucheckitem.h" - #include "miu.gtk.menuradioitem.h" - #include "miu.gtk.menuseparator.h" - #include "miu.gtk.formcontrol.h" - #include "miu.gtk.frame.h" - #include "miu.gtk.canvas.h" - #include "miu.gtk.label.h" - #include "miu.gtk.button.h" - #include "miu.gtk.checkbox.h" - #include "miu.gtk.radiobox.h" - #include "miu.gtk.editbox.h" - #include "miu.gtk.listbox.h" - #include "miu.gtk.combobox.h" - #include "miu.gtk.progressbar.h" - #include "miu.gtk.slider.h" - -class pMiu { -public: - Miu &self; - void init(); - void term(); - bool run(); - bool pending(); - - bool file_load(Window *focus, char *filename, const char *filter, const char *path); - bool file_save(Window *focus, char *filename, const char *filter, const char *path); - - uint screen_width(); - uint screen_height(); - - static pMiu& handle(); - pMiu(Miu&); - -/* internal */ - uint16 translate_key(uint key); -}; - -pMiu& pmiu(); - -} //namespace ns_miu - -#endif //ifndef MIU_GTK_H diff --git a/src/lib/miu.gtk/miu.gtk.keymap.cpp b/src/lib/miu.gtk/miu.gtk.keymap.cpp deleted file mode 100644 index 621f8e0f..00000000 --- a/src/lib/miu.gtk/miu.gtk.keymap.cpp +++ /dev/null @@ -1,188 +0,0 @@ -uint16 pMiu::translate_key(uint key) { - switch(key) { - case GDK_Escape: return keymap::esc; - - case GDK_F1: return keymap::f1; - case GDK_F2: return keymap::f2; - case GDK_F3: return keymap::f3; - case GDK_F4: return keymap::f4; - case GDK_F5: return keymap::f5; - case GDK_F6: return keymap::f6; - case GDK_F7: return keymap::f7; - case GDK_F8: return keymap::f8; - case GDK_F9: return keymap::f9; - case GDK_F10: return keymap::f10; - case GDK_F11: return keymap::f11; - case GDK_F12: return keymap::f12; - - case GDK_Print: return keymap::print_screen; - case GDK_Sys_Req: return keymap::sys_req; - case GDK_Scroll_Lock: return keymap::scroll_lock; - case GDK_Pause: return keymap::pause; - case GDK_Break: return keymap::brk; - - case GDK_grave: return keymap::grave; - case GDK_asciitilde: return keymap::tilde; - - case GDK_1: return keymap::num_1; - case GDK_2: return keymap::num_2; - case GDK_3: return keymap::num_3; - case GDK_4: return keymap::num_4; - case GDK_5: return keymap::num_5; - case GDK_6: return keymap::num_6; - case GDK_7: return keymap::num_7; - case GDK_8: return keymap::num_8; - case GDK_9: return keymap::num_9; - case GDK_0: return keymap::num_0; - - case GDK_exclam: return keymap::exclamation; - case GDK_at: return keymap::at; - case GDK_numbersign: return keymap::pound; - case GDK_dollar: return keymap::dollar; - case GDK_percent: return keymap::percent; - case GDK_asciicircum: return keymap::power; - case GDK_ampersand: return keymap::ampersand; - case GDK_asterisk: return keymap::asterisk; - case GDK_parenleft: return keymap::lparenthesis; - case GDK_parenright: return keymap::rparenthesis; - - case GDK_minus: return keymap::minus; - case GDK_underscore: return keymap::underscore; - case GDK_equal: return keymap::equal; - case GDK_plus: return keymap::plus; - case GDK_BackSpace: return keymap::backspace; - - case GDK_Insert: return keymap::ins; - case GDK_Delete: return keymap::del; - case GDK_Home: return keymap::home; - case GDK_End: return keymap::end; - case GDK_Page_Up: return keymap::page_up; - case GDK_Page_Down: return keymap::page_down; - - case GDK_a: return keymap::a; - case GDK_b: return keymap::b; - case GDK_c: return keymap::c; - case GDK_d: return keymap::d; - case GDK_e: return keymap::e; - case GDK_f: return keymap::f; - case GDK_g: return keymap::g; - case GDK_h: return keymap::h; - case GDK_i: return keymap::i; - case GDK_j: return keymap::j; - case GDK_k: return keymap::k; - case GDK_l: return keymap::l; - case GDK_m: return keymap::m; - case GDK_n: return keymap::n; - case GDK_o: return keymap::o; - case GDK_p: return keymap::p; - case GDK_q: return keymap::q; - case GDK_r: return keymap::r; - case GDK_s: return keymap::s; - case GDK_t: return keymap::t; - case GDK_u: return keymap::u; - case GDK_v: return keymap::v; - case GDK_w: return keymap::w; - case GDK_x: return keymap::x; - case GDK_y: return keymap::y; - case GDK_z: return keymap::z; - - case GDK_A: return keymap::A; - case GDK_B: return keymap::B; - case GDK_C: return keymap::C; - case GDK_D: return keymap::D; - case GDK_E: return keymap::E; - case GDK_F: return keymap::F; - case GDK_G: return keymap::G; - case GDK_H: return keymap::H; - case GDK_I: return keymap::I; - case GDK_J: return keymap::J; - case GDK_K: return keymap::K; - case GDK_L: return keymap::L; - case GDK_M: return keymap::M; - case GDK_N: return keymap::N; - case GDK_O: return keymap::O; - case GDK_P: return keymap::P; - case GDK_Q: return keymap::Q; - case GDK_R: return keymap::R; - case GDK_S: return keymap::S; - case GDK_T: return keymap::T; - case GDK_U: return keymap::U; - case GDK_V: return keymap::V; - case GDK_W: return keymap::W; - case GDK_X: return keymap::X; - case GDK_Y: return keymap::Y; - case GDK_Z: return keymap::Z; - - case GDK_bracketleft: return keymap::lbracket; - case GDK_bracketright: return keymap::rbracket; - case GDK_backslash: return keymap::backslash; - case GDK_semicolon: return keymap::semicolon; - case GDK_apostrophe: return keymap::apostrophe; - case GDK_comma: return keymap::comma; - case GDK_period: return keymap::period; - case GDK_slash: return keymap::slash; - - case GDK_braceleft: return keymap::lbrace; - case GDK_braceright: return keymap::rbrace; - case GDK_bar: return keymap::pipe; - case GDK_colon: return keymap::colon; - case GDK_quotedbl: return keymap::quote; - case GDK_less: return keymap::lcaret; - case GDK_greater: return keymap::rcaret; - case GDK_question: return keymap::question; - - case GDK_KP_1: return keymap::kp_1; - case GDK_KP_2: return keymap::kp_2; - case GDK_KP_3: return keymap::kp_3; - case GDK_KP_4: return keymap::kp_4; - case GDK_KP_5: return keymap::kp_5; - case GDK_KP_6: return keymap::kp_6; - case GDK_KP_7: return keymap::kp_7; - case GDK_KP_8: return keymap::kp_8; - case GDK_KP_9: return keymap::kp_9; - case GDK_KP_0: return keymap::kp_0; - case GDK_KP_Decimal: return keymap::kp_decimal; - - case GDK_KP_End: return keymap::kp_end; - case GDK_KP_Down: return keymap::kp_down; - case GDK_KP_Page_Down: return keymap::kp_page_down; - case GDK_KP_Left: return keymap::kp_left; - case GDK_KP_Begin: return keymap::kp_center; - case GDK_KP_Right: return keymap::kp_right; - case GDK_KP_Home: return keymap::kp_home; - case GDK_KP_Up: return keymap::kp_up; - case GDK_KP_Page_Up: return keymap::kp_page_up; - case GDK_KP_Insert: return keymap::kp_insert; - case GDK_KP_Delete: return keymap::kp_delete; - - case GDK_KP_Add: return keymap::kp_plus; - case GDK_KP_Subtract: return keymap::kp_minus; - case GDK_KP_Multiply: return keymap::kp_mul; - case GDK_KP_Divide: return keymap::kp_div; - case GDK_KP_Enter: return keymap::kp_enter; - - case GDK_Num_Lock: return keymap::num_lock; - case GDK_Caps_Lock: return keymap::caps_lock; - - case GDK_Up: return keymap::up; - case GDK_Down: return keymap::down; - case GDK_Left: return keymap::left; - case GDK_Right: return keymap::right; - - case GDK_Tab: return keymap::tab; - case GDK_Return: return keymap::enter; - case GDK_space: return keymap::space; - - case GDK_Control_L: return keymap::lctrl; - case GDK_Control_R: return keymap::rctrl; - case GDK_Alt_L: return keymap::lalt; - case GDK_Alt_R: return keymap::ralt; - case GDK_Shift_L: return keymap::lshift; - case GDK_Shift_R: return keymap::rshift; - case GDK_Super_L: return keymap::lsuper; - case GDK_Super_R: return keymap::rsuper; - case GDK_Menu: return keymap::menu; - } - - return keymap::none; -} diff --git a/src/lib/miu.gtk/miu.gtk.window.cpp b/src/lib/miu.gtk/miu.gtk.window.cpp deleted file mode 100644 index 5fd71962..00000000 --- a/src/lib/miu.gtk/miu.gtk.window.cpp +++ /dev/null @@ -1,135 +0,0 @@ -gint miu_pwindow_close(pWindow *p) { -uintptr_t r = p->self.on_close ? p->self.on_close(Event(Event::Close, 0, &p->self)) : true; - return !bool(r); -} - -gint miu_pwindow_keydown(GtkWidget *w, GdkEventKey *key, pWindow *p) { - if(p && p->self.on_keydown) p->self.on_keydown(Event(Event::KeyDown, pmiu().translate_key(key->keyval), &p->self)); - return FALSE; -} - -gint miu_pwindow_keyup(GtkWidget *w, GdkEventKey *key, pWindow *p) { - if(p && p->self.on_keyup) p->self.on_keyup(Event(Event::KeyUp, pmiu().translate_key(key->keyval), &p->self)); - return FALSE; -} - -void pWindow::create(uint style, uint width, uint height, const char *text) { - window = gtk_window_new(GTK_WINDOW_TOPLEVEL); - gtk_window_set_title(GTK_WINDOW(window), text ? text : ""); - gtk_window_set_resizable(GTK_WINDOW(window), false); - if(style & Window::AutoCenter) gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER_ALWAYS); - g_signal_connect_swapped(G_OBJECT(window), "delete_event", G_CALLBACK(miu_pwindow_close), (gpointer)this); - g_signal_connect(G_OBJECT(window), "key_press_event", G_CALLBACK(miu_pwindow_keydown), (gpointer)this); - g_signal_connect(G_OBJECT(window), "key_release_event", G_CALLBACK(miu_pwindow_keyup), (gpointer)this); - - menucontainer = gtk_vbox_new(false, 0); - gtk_container_add(GTK_CONTAINER(window), menucontainer); - gtk_widget_show(menucontainer); - - menubar = gtk_menu_bar_new(); - gtk_box_pack_start(GTK_BOX(menucontainer), menubar, false, false, 0); - - formcontainer = gtk_fixed_new(); - gtk_widget_set_size_request(formcontainer, width, height); - gtk_box_pack_end(GTK_BOX(menucontainer), formcontainer, true, true, 0); - gtk_widget_show(formcontainer); -} - -void pWindow::close() { - gtk_widget_destroy(window); -} - -void pWindow::move(uint x, uint y) { - gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_NONE); - gtk_window_move(GTK_WINDOW(window), x, y); -} - -void pWindow::resize(uint width, uint height) { - gtk_widget_set_size_request(formcontainer, width, height); -} - -void pWindow::focus() { - gtk_window_present(GTK_WINDOW(window)); -} - -bool pWindow::focused() { - return gtk_window_is_active(GTK_WINDOW(window)); -} - -void pWindow::fullscreen() { - gtk_window_fullscreen(GTK_WINDOW(window)); -} - -void pWindow::unfullscreen() { - gtk_window_unfullscreen(GTK_WINDOW(window)); -} - -void pWindow::set_background_color(uint8 r, uint8 g, uint8 b) { -GdkColor color; - color.pixel = (r << 16) | (g << 8) | b; - color.red = (r << 8) | r; - color.green = (g << 8) | g; - color.blue = (b << 8) | b; - gtk_widget_modify_bg(window, GTK_STATE_NORMAL, &color); - gtk_widget_modify_bg(formcontainer, GTK_STATE_NORMAL, &color); -} - -void pWindow::set_text(const char *text) { - gtk_window_set_title(GTK_WINDOW(window), text ? text : ""); -} - -void pWindow::attach(Window &window, uint x, uint y) { - window.p.owner = this; -//GTK+ does not support attaching a window to another window, -//so instead reparent the container from the child window to -//the parent window, and reposition the child window's container - gtk_widget_hide(window.p.window); - gtk_widget_hide(window.p.formcontainer); - gtk_widget_reparent(window.p.formcontainer, formcontainer); - gtk_fixed_move(GTK_FIXED(formcontainer), window.p.formcontainer, x, y); - gtk_widget_show(window.p.formcontainer); -} - -void pWindow::attach(MenuGroup &menugroup) { - gtk_menu_bar_append(menubar, menugroup.p.item); - gtk_widget_show(menubar); -} - -void pWindow::attach(FormControl &formcontrol, uint x, uint y) { - gtk_fixed_put(GTK_FIXED(formcontainer), formcontrol.p.gtk_handle(), x, y); -} - -void pWindow::move(Window &window, uint x, uint y) { - gtk_fixed_move(GTK_FIXED(formcontainer), window.p.gtk_handle(), x, y); -} - -void pWindow::move(FormControl &formcontrol, uint x, uint y) { - gtk_fixed_move(GTK_FIXED(formcontainer), formcontrol.p.gtk_handle(), x, y); -} - -void pWindow::menu_show(bool state) { - if(!menubar) return; - state ? gtk_widget_show(menubar) : gtk_widget_hide(menubar); -} - -void pWindow::menu_hide() { - menu_show(false); -} - -bool pWindow::menu_visible() { - return GTK_WIDGET_VISIBLE(menubar); -} - -pWindow::pWindow(Window &self_) : pWidget(self_), self(self_) { - owner = 0; - window = 0; - menubar = 0; - menucontainer = 0; - formcontainer = 0; -} - -/* internal */ - -GtkWidget* pWindow::gtk_handle() { - return owner ? formcontainer : window; -} diff --git a/src/lib/miu.win/miu.win.h b/src/lib/miu.win/miu.win.h deleted file mode 100644 index 5cf41e29..00000000 --- a/src/lib/miu.win/miu.win.h +++ /dev/null @@ -1,73 +0,0 @@ -#ifndef MIU_WIN_H -#define MIU_WIN_H - -#undef WINVER -#undef _WIN32_WINNT -#undef _WIN32_IE - -#define WINVER 0x0501 -#define _WIN32_WINNT 0x0501 -#define _WIN32_IE 0x0600 - -#include -#include - -#include "../miu.h" - -namespace ns_miu { - -#include "miu.win.widget.h" - #include "miu.win.window.h" - #include "miu.win.menucontrol.h" - #include "miu.win.menugroup.h" - #include "miu.win.menuitem.h" - #include "miu.win.menucheckitem.h" - #include "miu.win.menuradioitem.h" - #include "miu.win.menuseparator.h" - #include "miu.win.formcontrol.h" - #include "miu.win.frame.h" - #include "miu.win.canvas.h" - #include "miu.win.label.h" - #include "miu.win.button.h" - #include "miu.win.checkbox.h" - #include "miu.win.radiobox.h" - #include "miu.win.editbox.h" - #include "miu.win.listbox.h" - #include "miu.win.combobox.h" - #include "miu.win.progressbar.h" - #include "miu.win.slider.h" - -class pMiu { -public: - Miu &self; - void init(); - void term(); - bool run(); - bool pending(); - - bool file_load(Window *focus, char *filename, const char *filter, const char *path); - bool file_save(Window *focus, char *filename, const char *filter, const char *path); - - uint screen_width(); - uint screen_height(); - - static pMiu& handle(); - pMiu(Miu&); - -/* internal */ - HWND default_hwnd; //default parent window for all windowless controls - HFONT default_font; //default font for all controls - HBRUSH black_brush; //used for Canvas background - HFONT create_font(const char *name, uint size); - - array widget_list; - Widget* get_widget(uint instance); - long wndproc(HWND, UINT, WPARAM, LPARAM); - uint16 translate_key(uint key); -}; - -pMiu& pmiu(); - -} //namsepace ns_miu - -#endif //ifndef MIU_WIN_H diff --git a/src/lib/miu.win/miu.win.keymap.cpp b/src/lib/miu.win/miu.win.keymap.cpp deleted file mode 100644 index 221a2894..00000000 --- a/src/lib/miu.win/miu.win.keymap.cpp +++ /dev/null @@ -1,67 +0,0 @@ -uint16 pMiu::translate_key(uint key) { - switch(key) { - case VK_ESCAPE: return keymap::esc; - - case VK_F1: return keymap::f1; - case VK_F2: return keymap::f2; - case VK_F3: return keymap::f3; - case VK_F4: return keymap::f4; - case VK_F5: return keymap::f5; - case VK_F6: return keymap::f6; - case VK_F7: return keymap::f7; - case VK_F8: return keymap::f8; - case VK_F9: return keymap::f9; - case VK_F10: return keymap::f10; - case VK_F11: return keymap::f11; - case VK_F12: return keymap::f12; - - case VK_TAB: return keymap::tab; - case VK_RETURN: return keymap::enter; - case VK_SPACE: return keymap::space; - - case '0': return keymap::num_0; - case '1': return keymap::num_1; - case '2': return keymap::num_2; - case '3': return keymap::num_3; - case '4': return keymap::num_4; - case '5': return keymap::num_5; - case '6': return keymap::num_6; - case '7': return keymap::num_7; - case '8': return keymap::num_8; - case '9': return keymap::num_9; - - case 'A': return keymap::a; - case 'B': return keymap::b; - case 'C': return keymap::c; - case 'D': return keymap::d; - case 'E': return keymap::e; - case 'F': return keymap::f; - case 'G': return keymap::g; - case 'H': return keymap::h; - case 'I': return keymap::i; - case 'J': return keymap::j; - case 'K': return keymap::k; - case 'L': return keymap::l; - case 'M': return keymap::m; - case 'N': return keymap::n; - case 'O': return keymap::o; - case 'P': return keymap::p; - case 'Q': return keymap::q; - case 'R': return keymap::r; - case 'S': return keymap::s; - case 'T': return keymap::t; - case 'U': return keymap::u; - case 'V': return keymap::v; - case 'W': return keymap::w; - case 'X': return keymap::x; - case 'Y': return keymap::y; - case 'Z': return keymap::z; - - case VK_UP: return keymap::up; - case VK_DOWN: return keymap::down; - case VK_LEFT: return keymap::left; - case VK_RIGHT: return keymap::right; - } - - return keymap::none; -} diff --git a/src/lib/miu.win/miu.win.widget.h b/src/lib/miu.win/miu.win.widget.h deleted file mode 100644 index 5354a262..00000000 --- a/src/lib/miu.win/miu.win.widget.h +++ /dev/null @@ -1,19 +0,0 @@ -class pWidget { -public: - Widget &self; - virtual void show(bool = true); - virtual void hide(); - virtual bool visible(); - virtual uintptr_t handle(); - - pWidget(Widget&); - virtual ~pWidget(); - -/* internal */ - -//Windows API controls often require a unique ID for each control to identify it -//Simulate this with an instance counter, so that each Widget has a unique ID -//In each pWidget() constructor, instance = instance_counter++; is called - static uint instance_counter; - uint instance; -}; diff --git a/src/lib/nall/Makefile.string b/src/lib/nall/Makefile.string new file mode 100644 index 00000000..0de1db25 --- /dev/null +++ b/src/lib/nall/Makefile.string @@ -0,0 +1,63 @@ +# Makefile.string +# author: byuu +# license: public domain + +[A-Z] = A B C D E F G H I J K L M N O P Q R S T U V W X Y Z +[a-z] = a b c d e f g h i j k l m n o p q r s t u v w x y z +[0-9] = 0 1 2 3 4 5 6 7 8 9 +[markup] = ` ~ ! @ \# $$ % ^ & * ( ) - _ = + [ { ] } \ | ; : ' " , < . > / ? +[all] = $([A-Z]) $([a-z]) $([0-9]) $([markup]) +[space] := +[space] += + +##### +# function strtr(source, from, to) +##### +strtr = \ + $(eval __temp := $1) \ + $(strip \ + $(foreach c, \ + $(join $(addsuffix :,$2),$3), \ + $(eval __temp := \ + $(subst $(word 1,$(subst :, ,$c)),$(word 2,$(subst :, ,$c)),$(__temp)) \ + ) \ + ) \ + $(__temp) \ + ) + +##### +# function strupper(source) +##### +strupper = $(call strtr,$1,$([a-z]),$([A-Z])) + +##### +# function strlower(source) +##### +strlower = $(call strtr,$1,$([A-Z]),$([a-z])) + +##### +# function strlen(source) +##### +strlen = \ + $(eval __temp := $(subst $([space]),_,$1)) \ + $(words \ + $(strip \ + $(foreach c, \ + $([all]), \ + $(eval __temp := \ + $(subst $c,$c ,$(__temp)) \ + ) \ + ) \ + $(__temp) \ + ) \ + ) + +##### +# function streq(source) +##### +streq = $(if $(filter-out xx,x$(subst $1,,$2)$(subst $2,,$1)x),,1) + +##### +# function strne(source) +##### +strne = $(if $(filter-out xx,x$(subst $1,,$2)$(subst $2,,$1)x),1,) diff --git a/src/lib/nall/algorithm.hpp b/src/lib/nall/algorithm.hpp new file mode 100644 index 00000000..f63d27be --- /dev/null +++ b/src/lib/nall/algorithm.hpp @@ -0,0 +1,21 @@ +#ifndef NALL_ALGORITHM_HPP +#define NALL_ALGORITHM_HPP + +namespace nall { + +#undef min +#undef max + +template +T min(const T& t, const U& u) { + return t < u ? t : u; +} + +template +T max(const T& t, const U& u) { + return t > u ? t : u; +} + +} //namespace nall + +#endif //ifndef NALL_ALGORITHM_HPP diff --git a/src/lib/nall/any.hpp b/src/lib/nall/any.hpp new file mode 100644 index 00000000..a4417e00 --- /dev/null +++ b/src/lib/nall/any.hpp @@ -0,0 +1,76 @@ +#ifndef NALL_ANY_HPP +#define NALL_ANY_HPP + +#include +#include +#include + +namespace nall { + +class any { +public: + bool empty() const { return container; } + const std::type_info& type() const { return container ? container->type() : typeid(void); } + + template any& operator=(const T& value_) { + typedef typename static_if< + is_array::value, + typename remove_extent::type>::type*, + T + >::type auto_t; + + if(type() == typeid(auto_t)) { + static_cast*>(container)->value = (auto_t)value_; + } else { + if(container) delete container; + container = new holder((auto_t)value_); + } + + return *this; + } + + any() : container(0) {} + template any(const T& value_) : container(0) { operator=(value_); } + +private: + struct placeholder { + virtual const std::type_info& type() const = 0; + } *container; + + template struct holder : placeholder { + T value; + const std::type_info& type() const { return typeid(T); } + holder(const T& value_) : value(value_) {} + }; + + template friend T any_cast(any&); + template friend T any_cast(const any&); + template friend T* any_cast(any*); + template friend const T* any_cast(const any*); +}; + +template T any_cast(any &value) { + typedef typename remove_reference::type nonref; + if(value.type() != typeid(nonref)) throw; + return static_cast*>(value.container)->value; +} + +template T any_cast(const any &value) { + typedef const typename remove_reference::type nonref; + if(value.type() != typeid(nonref)) throw; + return static_cast*>(value.container)->value; +} + +template T* any_cast(any *value) { + if(!value || value->type() != typeid(T)) return 0; + return &static_cast*>(value->container)->value; +} + +template const T* any_cast(const any *value) { + if(!value || value->type() != typeid(T)) return 0; + return &static_cast*>(value->container)->value; +} + +} //namespace nall + +#endif //ifndef NALL_ANY_HPP diff --git a/src/lib/barray.h b/src/lib/nall/array.hpp similarity index 67% rename from src/lib/barray.h rename to src/lib/nall/array.hpp index 62cf32ad..84215c83 100644 --- a/src/lib/barray.h +++ b/src/lib/nall/array.hpp @@ -1,17 +1,16 @@ -/* - barray : version 0.10 ~byuu (2007-11-29) - license: public domain -*/ +#ifndef NALL_ARRAY_HPP +#define NALL_ARRAY_HPP -#ifndef BARRAY_H -#define BARRAY_H +#include + +namespace nall { template class array { protected: T *pool; - uint poolsize, buffersize; + unsigned poolsize, buffersize; - uint findsize(uint size) { + unsigned findsize(unsigned size) const { if(size <= 0x100) return 0x100; if(size <= 0x400) return 0x400; if(size <= 0x1000) return 0x1000; @@ -24,16 +23,19 @@ protected: } public: - uint size() { return buffersize; } - uint capacity() { return poolsize; } + unsigned size() const { return buffersize; } + unsigned capacity() const { return poolsize; } void reset() { - safe_free(pool); + if(pool) { + free(pool); + pool = 0; + } poolsize = 0; buffersize = 0; } - void reserve(uint size) { + void reserve(unsigned size) { if(size == poolsize) return; if(size < poolsize) buffersize = size; @@ -41,7 +43,7 @@ public: poolsize = size; } - T* get(uint size = 0) { + T* get(unsigned size = 0) { if(size > buffersize) resize(size); if(size > buffersize) throw "array[] out of bounds"; return pool; @@ -55,7 +57,7 @@ public: memset(pool, 0, sizeof(T) * buffersize); } - void resize(uint size) { + void resize(unsigned size) { reserve(findsize(size)); buffersize = size; } @@ -69,7 +71,7 @@ public: ~array() { reset(); } array& operator=(array &source) { - safe_free(pool); + if(pool) free(pool); buffersize = source.buffersize; poolsize = source.poolsize; pool = (T*)realloc(pool, sizeof(T) * poolsize); //allocate entire pool size ... @@ -82,6 +84,13 @@ public: if(index >= buffersize) throw "array[] out of bounds"; return pool[index]; } + + inline const T& operator[](int index) const { + if(index >= buffersize) throw "array[] out of bounds"; + return pool[index]; + } }; -#endif //ifndef BARRAY_H +} //namespace nall + +#endif //ifndef NALL_ARRAY_HPP diff --git a/src/lib/nall/bit.hpp b/src/lib/nall/bit.hpp new file mode 100644 index 00000000..e46757db --- /dev/null +++ b/src/lib/nall/bit.hpp @@ -0,0 +1,28 @@ +#ifndef NALL_BIT_HPP +#define NALL_BIT_HPP + +namespace nall { + +template inline unsigned uclamp(const unsigned x) { +enum { y = (1U << bits) - 1 }; + return y + ((x - y) & -(x < y)); //min(x, y); +} + +template inline unsigned uclip(const unsigned x) { +enum { m = (1U << bits) - 1 }; + return (x & m); +} + +template inline signed sclamp(const signed x) { +enum { b = 1U << (bits - 1), m = (1U << (bits - 1)) - 1 }; + return (x > m) ? m : (x < -b) ? -b : x; +} + +template inline signed sclip(const signed x) { +enum { b = 1U << (bits - 1), m = (1U << bits) - 1 }; + return ((x & m) ^ b) - b; +} + +} //namespace nall + +#endif //ifndef NALL_BIT_HPP diff --git a/src/lib/nall/config.hpp b/src/lib/nall/config.hpp new file mode 100644 index 00000000..cb17b161 --- /dev/null +++ b/src/lib/nall/config.hpp @@ -0,0 +1,186 @@ +#ifndef NALL_CONFIG_HPP +#define NALL_CONFIG_HPP + +#include +#include +#include + +namespace nall { + +class setting; + +class configuration { +public: + array list; + + bool load(const char *fn) const; + bool save(const char *fn) const; + void add(setting *setting_) { list.add(setting_); } +}; + +class setting { +public: + enum setting_type { + integral_type, + string_type, + } type; + + const char *name; + const char *description; + + virtual void set(const char *input) = 0; + virtual void get(string &output) const = 0; + virtual void get_default(string &output) const = 0; +}; + +class integral_setting : public setting { +public: + enum integral_type { + boolean, + decimal, + hex, + } type; + + intmax_t value; + intmax_t default_value; + + void set(const char *input) { + if(type == boolean) { value = !strcmp(input, "true"); } + if(type == decimal) { value = strdec(input); } + if(type == hex) { value = strhex(input); } + } + + void get(string &output) const { + if(type == boolean) { output = value ? "true" : "false"; } + if(type == decimal) { output = strdec(value); } + if(type == hex) { output = string() << "0x" << strhex(value); } + } + + void get_default(string &output) const { + if(type == boolean) { output = default_value ? "true" : "false"; } + if(type == decimal) { output = strdec(default_value); } + if(type == hex) { output = string() << "0x" << strhex(default_value); } + } + + operator intmax_t() const { return value; } + integral_setting& operator=(intmax_t value_) { value = value_; return *this; } + + integral_setting(const char *name_, const char *description_, integral_type type_, intmax_t value_) { + initialize(name_, description_, type_, value_); + } + + integral_setting(configuration &parent, const char *name_, const char *description_, integral_type type_, intmax_t value_) { + initialize(name_, description_, type_, value_); + parent.add(this); + } + +private: + void initialize(const char *name_, const char *description_, integral_type type_, intmax_t value_) { + setting::type = setting::integral_type; + name = name_; + description = description_; + type = type_; + value = default_value = value_; + } +}; + +class string_setting : public setting { +public: + string value; + string default_value; + + void set(const char *input) { value = input; trim(value(), "\""); } + void get(string &output) const { output = string() << "\"" << value << "\""; } + void get_default(string &output) const { output = string() << "\"" << default_value << "\""; } + + operator const char*() const { return value; } + string_setting& operator=(const char *value_) { value = value_; return *this; } + bool operator==(const char *value_) const { return value == value_; } + bool operator!=(const char *value_) const { return value != value_; } + + string_setting(const char *name_, const char *description_, const char *value_) { + initialize(name_, description_, value_); + } + + string_setting(configuration &parent, const char *name_, const char *description_, const char *value_) { + initialize(name_, description_, value_); + parent.add(this); + } + +private: + void initialize(const char *name_, const char *description_, const char *value_) { + setting::type = setting::string_type; + name = name_; + description = description_; + value = default_value = value_; + } +}; + +inline bool configuration::load(const char *fn) const { + FILE *fp = fopen(fn, "rb"); + if(!fp) return false; + + string data; + lstring line, part, subpart; + + //load the config file into memory + fseek(fp, 0, SEEK_END); + int size = ftell(fp); + fseek(fp, 0, SEEK_SET); + char *buffer = (char*)malloc(size + 1); + fread(buffer, 1, size, fp); + fclose(fp); + buffer[size] = 0; + strcpy(data, buffer); + free(buffer); + + //split the file into lines + replace(data, "\r\n", "\n"); + qreplace(data, "\t", ""); + qreplace(data, " ", ""); + split(line, "\n", data); + + for(unsigned i = 0; i < count(line); i++) { + if(strlen(line[i]) == 0) continue; + if(strbegin(line[i], "#")) continue; + + qsplit(part, "=", line[i]); + for(unsigned l = 0; l < list.size(); l++) { + if(part[0] == list[l]->name) { + list[l]->set(part[1]); + break; + } + } + } + + return true; +} + +inline bool configuration::save(const char *fn) const { + FILE *fp = fopen(fn, "wb"); + if(!fp) return false; + + for(unsigned i = 0; i < list.size(); i++) { + string data; + lstring line, part, subpart; + strcpy(data, list[i]->description); + replace(data, "\r\n", "\n"); + split(line, "\n", data); + for(unsigned l = 0; l < count(line); l++) { + if(line[l] != "") fprintf(fp, "# %s\r\n", (const char*)line[l]); + } + + string default_, value_; + list[i]->get_default(default_); + fprintf(fp, "# (default = %s)\r\n", (const char*)default_); + list[i]->get(value_); + fprintf(fp, "%s = %s\r\n\r\n", list[i]->name, (const char*)value_); + } + + fclose(fp); + return true; +} + +} //namespace nall + +#endif //ifndef NALL_CONFIG_HPP diff --git a/src/lib/nall/file.hpp b/src/lib/nall/file.hpp new file mode 100644 index 00000000..53140968 --- /dev/null +++ b/src/lib/nall/file.hpp @@ -0,0 +1,189 @@ +#ifndef NALL_FILE_HPP +#define NALL_FILE_HPP + +#include +#include +#include + +#include + +namespace nall { + +class file : noncopyable { +public: + enum FileMode { mode_read, mode_write, mode_readwrite, mode_writeread }; + enum SeekMode { seek_absolute, seek_relative }; + + uint8_t read() { + if(!fp) return 0xff; //file not open + if(file_mode == mode_write) return 0xff; //reads not permitted + if(file_offset >= file_size) return 0xff; //cannot read past end of file + buffer_sync(); + return buffer[(file_offset++) & buffer_mask]; + } + + uintmax_t readl(unsigned length = 1) { + uintmax_t data = 0; + for(int i = length - 1; i >= 0; i--) { + data |= (uintmax_t)read() << (i << 3); + } + return data; + } + + uintmax_t readm(unsigned length = 1) { + uintmax_t data = 0; + while(length--) { + data <<= 8; + data |= read(); + } + return data; + } + + void read(uint8_t *buffer, unsigned length) { + while(length--) *buffer++ = read(); + } + + void write(uint8_t data) { + if(!fp) return; //file not open + if(file_mode == mode_read) return; //writes not permitted + buffer_sync(); + buffer[(file_offset++) & buffer_mask] = data; + buffer_dirty = true; + if(file_offset > file_size) file_size = file_offset; + } + + void writel(uintmax_t data, unsigned length = 1) { + while(length--) { + write(data); + data >>= 8; + } + } + + void writem(uintmax_t data, unsigned length = 1) { + for(int i = length - 1; i >= 0; i--) { + write(data >> (i << 3)); + } + } + + void write(const uint8_t *buffer, unsigned length) { + while(length--) write(*buffer++); + } + + void flush() { + buffer_flush(); + fflush(fp); + } + + void seek(int offset, SeekMode mode = seek_absolute) { + if(!fp) return; //file not open + buffer_flush(); + + uintmax_t req_offset = file_offset; + switch(mode) { + case seek_absolute: req_offset = offset; break; + case seek_relative: req_offset += offset; break; + } + + if(req_offset < 0) req_offset = 0; //cannot seek before start of file + if(req_offset > file_size) { + if(file_mode == mode_read) { //cannot seek past end of file + req_offset = file_size; + } else { //pad file to requested location + file_offset = file_size; + while(file_size < req_offset) write(0x00); + } + } + + file_offset = req_offset; + } + + int offset() { + if(!fp) return -1; //file not open + return file_offset; + } + + int size() { + if(!fp) return -1; //file not open + return file_size; + } + + bool end() { + if(!fp) return true; //file not open + return file_offset >= file_size; + } + + bool open(const char *fn, FileMode mode) { + if(fp) return false; + switch(file_mode = mode) { + case mode_read: fp = fopen(fn, "rb"); break; + case mode_write: fp = fopen(fn, "wb+"); break; //need read permission for buffering + case mode_readwrite: fp = fopen(fn, "rb+"); break; + case mode_writeread: fp = fopen(fn, "wb+"); break; + } + if(!fp) return false; + buffer_offset = -1; //invalidate buffer + file_offset = 0; + fseek(fp, 0, SEEK_END); + file_size = ftell(fp); + fseek(fp, 0, SEEK_SET); + return true; + } + + void close() { + if(!fp) return; + buffer_flush(); + fclose(fp); + fp = 0; + } + + file() { + memset(buffer, 0, sizeof buffer); + buffer_offset = -1; + buffer_dirty = false; + fp = 0; + file_offset = 0; + file_size = 0; + file_mode = mode_read; + } + + ~file() { + close(); + } + +private: + enum { buffer_size = 1 << 12, buffer_mask = buffer_size - 1 }; + char buffer[buffer_size]; + int buffer_offset; + bool buffer_dirty; + FILE *fp; + unsigned file_offset; + unsigned file_size; + FileMode file_mode; + + void buffer_sync() { + if(!fp) return; //file not open + if(buffer_offset != (file_offset & ~buffer_mask)) { + buffer_flush(); + buffer_offset = file_offset & ~buffer_mask; + fseek(fp, buffer_offset, SEEK_SET); + unsigned length = (buffer_offset + buffer_size) <= file_size ? buffer_size : (file_size & buffer_mask); + if(length) fread(buffer, 1, length, fp); + } + } + + void buffer_flush() { + if(!fp) return; //file not open + if(file_mode == mode_read) return; //buffer cannot be written to + if(buffer_offset < 0) return; //buffer unused + if(buffer_dirty == false) return; //buffer unmodified since read + fseek(fp, buffer_offset, SEEK_SET); + unsigned length = (buffer_offset + buffer_size) <= file_size ? buffer_size : (file_size & buffer_mask); + if(length) fwrite(buffer, 1, length, fp); + buffer_offset = -1; //invalidate buffer + buffer_dirty = false; + } +}; + +} //namespace nall + +#endif //ifndef NALL_FILE_HPP diff --git a/src/lib/bfunction.h b/src/lib/nall/function.hpp similarity index 84% rename from src/lib/bfunction.h rename to src/lib/nall/function.hpp index ce602a8d..2e10b6ea 100644 --- a/src/lib/bfunction.h +++ b/src/lib/nall/function.hpp @@ -1,16 +1,15 @@ -/* - bfunction : version 0.06 ~byuu (2007-10-14) - license: public domain -*/ - -#ifndef BFUNCTION_H -#define BFUNCTION_H +#ifndef NALL_FUNCTION_HPP +#define NALL_FUNCTION_HPP + +#include //prologue #define TN typename - -template class function; + +namespace nall { +template class function; +} //parameters = 0 @@ -19,7 +18,7 @@ template class function; #define PL #define CL -#include "bfunction.h" +#include "function.hpp" //parameters = 1 @@ -28,7 +27,7 @@ template class function; #define PL P1 p1 #define CL p1 -#include "bfunction.h" +#include "function.hpp" //parameters = 2 @@ -37,7 +36,7 @@ template class function; #define PL P1 p1, P2 p2 #define CL p1, p2 -#include "bfunction.h" +#include "function.hpp" //parameters = 3 @@ -46,7 +45,7 @@ template class function; #define PL P1 p1, P2 p2, P3 p3 #define CL p1, p2, p3 -#include "bfunction.h" +#include "function.hpp" //parameters = 4 @@ -55,7 +54,7 @@ template class function; #define PL P1 p1, P2 p2, P3 p3, P4 p4 #define CL p1, p2, p3, p4 -#include "bfunction.h" +#include "function.hpp" //parameters = 5 @@ -64,7 +63,7 @@ template class function; #define PL P1 p1, P2 p2, P3 p3, P4 p4, P5 p5 #define CL p1, p2, p3, p4, p5 -#include "bfunction.h" +#include "function.hpp" //parameters = 6 @@ -73,7 +72,7 @@ template class function; #define PL P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6 #define CL p1, p2, p3, p4, p5, p6 -#include "bfunction.h" +#include "function.hpp" //parameters = 7 @@ -82,7 +81,7 @@ template class function; #define PL P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7 #define CL p1, p2, p3, p4, p5, p6, p7 -#include "bfunction.h" +#include "function.hpp" //parameters = 8 @@ -91,16 +90,18 @@ template class function; #define PL P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8 #define CL p1, p2, p3, p4, p5, p6, p7, p8 -#include "bfunction.h" +#include "function.hpp" //epilogue #undef TN -#define BFUNCTION_TH +#define NALL_FUNCTION_T -#elif !defined(BFUNCTION_TH) +#elif !defined(NALL_FUNCTION_T) -//function implementation template class +//function implementation template class + +namespace nall { template class function { @@ -173,11 +174,13 @@ function bind(R (C::*fn)(PL), C *obj) { template function bind(R (C::*fn)(PL) const, C *obj) { return function(fn, obj); -} +} + +} //namespace nall #undef cat #undef TL #undef PL #undef CL -#endif +#endif //ifndef NALL_FUNCTION_HPP diff --git a/src/lib/nall/input.hpp b/src/lib/nall/input.hpp new file mode 100644 index 00000000..b4e660b3 --- /dev/null +++ b/src/lib/nall/input.hpp @@ -0,0 +1,134 @@ +#ifndef NALL_INPUT_HPP +#define NALL_INPUT_HPP + +#include +#include +#include + +#include +#include + +namespace nall { + +struct keyboard { + enum { + none, + escape, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, + print_screen, scroll_lock, pause, tilde, + num_1, num_2, num_3, num_4, num_5, num_6, num_7, num_8, num_9, num_0, + dash, equal, backspace, + insert, delete_, home, end, page_up, page_down, + a, b, c, d, e, f, g, h, i, j, k, l, m, + n, o, p, q, r, s, t, u, v, w, x, y, z, + lbracket, rbracket, backslash, semicolon, apostrophe, comma, period, slash, + pad_1, pad_2, pad_3, pad_4, pad_5, pad_6, pad_7, pad_8, pad_9, pad_0, + point, enter, add, subtract, multiply, divide, + num_lock, caps_lock, + up, down, left, right, + tab, return_, spacebar, + lctrl, rctrl, lalt, ralt, lshift, rshift, lsuper, rsuper, menu, + limit, + }; +}; + +template struct joypad { + enum { + none = joypad::limit, + up, down, left, right, + button_00, button_01, button_02, button_03, + button_04, button_05, button_06, button_07, + button_08, button_09, button_10, button_11, + button_12, button_13, button_14, button_15, + limit, + }; +}; + +template<> struct joypad<-1> { + enum { + none, + up, down, left, right, + button_00, button_01, button_02, button_03, + button_04, button_05, button_06, button_07, + button_08, button_09, button_10, button_11, + button_12, button_13, button_14, button_15, + length = button_15 - none + 1, //number of syms per joypad + limit = keyboard::limit, //start joypad syms immediately after keyboard syms + }; + + static uint16_t index(int joypad_number, int joypad_enum) { + if(joypad_number < 0 || joypad_number > 15) return keyboard::none; + return limit + joypad_number * length + joypad_enum; + } +}; + +enum { input_limit = joypad<15>::limit }; + +static static_assert keyboard_length_assert; //error if keyboard syms spill into joypad syms + +static const char keyboard_table[][64] = { + "none", + "escape", "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9", "f10", "f11", "f12", + "print_screen", "scroll_lock", "pause", "tilde", + "num_1", "num_2", "num_3", "num_4", "num_5", "num_6", "num_7", "num_8", "num_9", "num_0", + "dash", "equal", "backspace", + "insert", "delete", "home", "end", "page_up", "page_down", + "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", + "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", + "lbracket", "rbracket", "backslash", "semicolon", "apostrophe", "comma", "period", "slash", + "pad_1", "pad_2", "pad_3", "pad_4", "pad_5", "pad_6", "pad_7", "pad_8", "pad_9", "pad_0", + "point", "enter", "add", "subtract", "multiply", "divide", + "num_lock", "caps_lock", + "up", "down", "left", "right", + "tab", "return", "spacebar", + "lctrl", "rctrl", "lalt", "ralt", "lshift", "rshift", "lsuper", "rsuper", "menu", + "limit", +}; + +static const char* input_find(uint16_t key) { + if(key < keyboard::limit) return keyboard_table[key]; + static char buffer[64]; + for(uint16_t j = 0; j < 16; j++) { + if(key == joypad<>::index(j, joypad<>::up)) { sprintf(buffer, "joypad%0.2d.up", j); return buffer; } + if(key == joypad<>::index(j, joypad<>::down)) { sprintf(buffer, "joypad%0.2d.down", j); return buffer; } + if(key == joypad<>::index(j, joypad<>::left)) { sprintf(buffer, "joypad%0.2d.left", j); return buffer; } + if(key == joypad<>::index(j, joypad<>::right)) { sprintf(buffer, "joypad%0.2d.right", j); return buffer; } + if(key >= joypad<>::index(j, joypad<>::button_00) + && key <= joypad<>::index(j, joypad<>::button_15)) { + sprintf(buffer, "joypad%0.2d.button_%0.2d", j, key - joypad<>::index(j, joypad<>::button_00)); + return buffer; + } + } + return keyboard_table[0]; //"none" +} + +static char* input_find(char *out, uint16_t key) { + strcpy(out, input_find(key)); + return out; +} + +static uint16_t input_find(const char *key) { + for(uint16_t i = 0; i < keyboard::limit; i++) { + if(!strcmp(keyboard_table[i], key)) return i; + } + + if(memcmp(key, "joypad", 6)) return keyboard::none; + key += 6; + if(!*key || !*(key + 1)) return keyboard::none; + uint8_t j = (*key - '0') * 10 + (*(key + 1) - '0'); + if(j > 15) return keyboard::none; + key += 2; + if(!strcmp(key, ".up")) return joypad<>::index(j, joypad<>::up); + if(!strcmp(key, ".down")) return joypad<>::index(j, joypad<>::down); + if(!strcmp(key, ".left")) return joypad<>::index(j, joypad<>::left); + if(!strcmp(key, ".right")) return joypad<>::index(j, joypad<>::right); + if(memcmp(key, ".button_", 8)) return keyboard::none; + key += 8; + if(!*key || !*(key + 1)) return keyboard::none; + uint8_t button = (*key - '0') * 10 + (*(key + 1) - '0'); + if(button > 15) return keyboard::none; + return joypad<>::index(j, joypad<>::button_00 + button); +} + +} //namespace nall + +#endif //ifndef NALL_INPUT_HPP diff --git a/src/lib/nall/new.hpp b/src/lib/nall/new.hpp new file mode 100644 index 00000000..62bf64fb --- /dev/null +++ b/src/lib/nall/new.hpp @@ -0,0 +1,27 @@ +#ifndef NALL_NEW_HPP +#define NALL_NEW_HPP + +#include +#include +#include + +namespace nall { + +struct zeromemory_t {}; +static zeromemory_t zeromemory; + +} //namespace nall + +inline void* operator new[](size_t size, const nall::zeromemory_t&) throw(std::bad_alloc) { + void *p = new uint8_t[size]; + memset(p, 0, size); + return p; +} + +inline void* operator new[](size_t size, const std::nothrow_t&, const nall::zeromemory_t&) throw() { + void *p = new(std::nothrow) uint8_t[size]; + if(p) memset(p, 0, size); + return p; +} + +#endif //ifndef NALL_NEW_HPP diff --git a/src/lib/nall/sort.hpp b/src/lib/nall/sort.hpp new file mode 100644 index 00000000..09f5f214 --- /dev/null +++ b/src/lib/nall/sort.hpp @@ -0,0 +1,40 @@ +#ifndef NALL_SORT_HPP +#define NALL_SORT_HPP + +namespace nall { + +template inline void swap(T &x, T &y) { +T z = x; + x = y; + y = z; +} + +template +void sort(T list[], unsigned length) { + for(unsigned d = 0; d < length; d++) { + unsigned min = d; + for(unsigned s = d + 1; s < length; s++) { + if(list[s] < list[min]) { min = s; } + } + if(min != d) { + swap(list[d], list[min]); + } + } +} + +template +void sort(T list[], unsigned length, Tcmp comparator) { + for(unsigned d = 0; d < length; d++) { + unsigned min = d; + for(unsigned s = d + 1; s < length; s++) { + if(comparator(list[s], list[min]) == true) { min = s; } + } + if(min != d) { + swap(list[d], list[min]); + } + } +} + +} //namespace nall + +#endif //ifndef NALL_SORT_HPP diff --git a/src/lib/nall/static.hpp b/src/lib/nall/static.hpp new file mode 100644 index 00000000..14e42bac --- /dev/null +++ b/src/lib/nall/static.hpp @@ -0,0 +1,21 @@ +#ifndef NALL_STATIC_HPP +#define NALL_STATIC_HPP + +namespace nall { + +template struct static_assert; +template<> struct static_assert {}; + +template +struct static_if { + typedef true_type type; +}; + +template +struct static_if { + typedef false_type type; +}; + +} //namespace nall + +#endif //ifndef NALL_STATIC_HPP diff --git a/src/lib/nall/stdint.hpp b/src/lib/nall/stdint.hpp new file mode 100644 index 00000000..ba58bda2 --- /dev/null +++ b/src/lib/nall/stdint.hpp @@ -0,0 +1,46 @@ +#ifndef NALL_STDINT_HPP +#define NALL_STDINT_HPP + +#include + +#if defined(_MSC_VER) + typedef signed char int8_t; + typedef signed short int16_t; + typedef signed int int32_t; + typedef signed long long int64_t; + typedef int64_t intmax_t; + #if defined(_WIN64) + typedef int64_t intptr_t; + #else + typedef int32_t intptr_t; + #endif + + typedef unsigned char uint8_t; + typedef unsigned short uint16_t; + typedef unsigned int uint32_t; + typedef unsigned long long uint64_t; + typedef uint64_t uintmax_t; + #if defined(_WIN64) + typedef uint64_t uintptr_t; + #else + typedef uint32_t uintptr_t; + #endif +#else + #include +#endif + +namespace nall { + +static static_assert int8_t_assert; +static static_assert int16_t_assert; +static static_assert int32_t_assert; +static static_assert int64_t_assert; + +static static_assert uint8_t_assert; +static static_assert uint16_t_assert; +static static_assert uint32_t_assert; +static static_assert uint64_t_assert; + +} //namespace nall + +#endif //ifndef NALL_STDINT_HPP diff --git a/src/lib/nall/string.cpp b/src/lib/nall/string.cpp new file mode 100644 index 00000000..bdfd33a8 --- /dev/null +++ b/src/lib/nall/string.cpp @@ -0,0 +1,16 @@ +#ifndef NALL_STRING_CPP +#define NALL_STRING_CPP + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif //ifndef NALL_STRING_CPP diff --git a/src/lib/nall/string.hpp b/src/lib/nall/string.hpp new file mode 100644 index 00000000..edca9699 --- /dev/null +++ b/src/lib/nall/string.hpp @@ -0,0 +1,120 @@ +#ifndef NALL_STRING_HPP +#define NALL_STRING_HPP + +#include +#include +#include +#include +#include + +//compare +char chrlower(char c); +char chrupper(char c); +int stricmp(const char *dest, const char *src); +int strpos(const char *str, const char *key); +int qstrpos(const char *str, const char *key); +bool strbegin(const char *str, const char *key); +bool stribegin(const char *str, const char *key); +bool strend(const char *str, const char *key); +bool striend(const char *str, const char *key); + +//convert +char* strlower(char *str); +char* strupper(char *str); +char* strtr(char *dest, const char *before, const char *after); +uintmax_t strhex(const char *str); +intmax_t strdec(const char *str); +uintmax_t strbin(const char *str); +double strdouble(const char *str); +size_t strhex(char *str, uintmax_t value, size_t length = 0); +size_t strdec(char *str, intmax_t value, size_t length = 0); +size_t strbin(char *str, uintmax_t value, size_t length = 0); +size_t strdouble(char *str, double value, size_t length = 0); + +//match +bool match(const char *pattern, const char *str); + +//math +bool strint (const char *str, int &result); +bool strmath(const char *str, int &result); + +//strl +size_t strlcpy(char *dest, const char *src, size_t length); +size_t strlcat(char *dest, const char *src, size_t length); + +//trim +char* ltrim(char *str, const char *key = " "); +char* rtrim(char *str, const char *key = " "); +char* trim (char *str, const char *key = " "); +char* ltrim_once(char *str, const char *key = " "); +char* rtrim_once(char *str, const char *key = " "); +char* trim_once (char *str, const char *key = " "); + +namespace nall { + +class string { +public: + char *data; + size_t size; + + void reserve(size_t size_); + + operator int() const; + operator const char*() const; + char* operator()(); + char& operator[](int); + + string& operator=(int num); + string& operator=(double num); + string& operator=(const char *str); + string& operator=(const string &str); + string& operator<<(int num); + string& operator<<(const char *str); + string& operator<<(const string& str); + + bool operator==(const char *str) const; + bool operator!=(const char *str) const; + bool operator< (const char *str) const; + bool operator<=(const char *str) const; + bool operator> (const char *str) const; + bool operator>=(const char *str) const; + + string(); + string(int num); + string(double num); + string(const char *source); + string(const string &source); + ~string(); +}; + +typedef vector lstring; + +} //namespace nall + +size_t count(nall::lstring&); +int find(nall::lstring &str, const char *key); +size_t strlcpy(nall::string &dest, const char *src, size_t length); +size_t strlcat(nall::string &dest, const char *src, size_t length); +void strcpy(nall::string &dest, const char *src); +void strcat(nall::string &dest, const char *src); +nall::string substr(const char *src, size_t start = 0, size_t length = 0); +nall::string& strlower(nall::string &str); +nall::string& strupper(nall::string &str); +nall::string& strtr(nall::string &dest, const char *before, const char *after); +nall::string strhex(uintmax_t value); +nall::string strdec(intmax_t value); +nall::string strbin(uintmax_t value); +nall::string strdouble(double value); +bool fread(nall::string &str, const char *filename); +nall::string& replace (nall::string &str, const char *key, const char *token); +nall::string& qreplace(nall::string &str, const char *key, const char *token); +void split (nall::lstring &dest, const char *key, const char *src, size_t limit = 0); +void qsplit(nall::lstring &dest, const char *key, const char *src, size_t limit = 0); +nall::string& ltrim(nall::string &str, const char *key = " "); +nall::string& rtrim(nall::string &str, const char *key = " "); +nall::string& trim (nall::string &str, const char *key = " "); +nall::string& ltrim_once(nall::string &str, const char *key = " "); +nall::string& rtrim_once(nall::string &str, const char *key = " "); +nall::string& trim_once (nall::string &str, const char *key = " "); + +#endif //ifndef NALL_STRING_HPP diff --git a/src/lib/nall/string/class.cpp b/src/lib/nall/string/class.cpp new file mode 100644 index 00000000..000d8fc2 --- /dev/null +++ b/src/lib/nall/string/class.cpp @@ -0,0 +1,223 @@ +#ifndef NALL_STRING_CLASS_CPP +#define NALL_STRING_CLASS_CPP + +size_t count(nall::lstring &str) { + return str.size(); +} + +int find(nall::lstring &str, const char *key) { + for(size_t i = 0; i < count(str); i++) { + if(str[i] == key) return i; + } + return -1; +} + +namespace nall { + +void string::reserve(size_t size_) { + if(size_ > size) { + size = size_; + data = (char*)realloc(data, size + 1); + data[size] = 0; + } +} + +//implicit-conversion, read-only +string::operator int() const { + return strdec(data); +} + +//implicit-conversion, read-only +string::operator const char*() const { + return data; +} + +//explicit-coversion, read-write +char* string::operator()() { + return data; +} + +//index, read-write +char& string::operator[](int index) { + reserve(index); + return data[index]; +} + +string& string::operator=(int num) { + operator=(strdec(num)); + return *this; +} + +string& string::operator=(double num) { + operator=(strdouble(num)); + return *this; +} + +string& string::operator=(const char *str) { + strcpy(*this, str); + return *this; +} + +string& string::operator=(const string &str) { + strcpy(*this, str); + return *this; +} + +string& string::operator<<(int num) { +string temp(num); + strcat(*this, temp); + return *this; +} + +string& string::operator<<(const char *str) { + strcat(*this, str); + return *this; +} + +string& string::operator<<(const string &str) { + strcat(*this, str); + return *this; +} + +bool string::operator==(const char *str) const { return strcmp(data, str) == 0; } +bool string::operator!=(const char *str) const { return strcmp(data, str) != 0; } +bool string::operator< (const char *str) const { return strcmp(data, str) < 0; } +bool string::operator<=(const char *str) const { return strcmp(data, str) <= 0; } +bool string::operator> (const char *str) const { return strcmp(data, str) > 0; } +bool string::operator>=(const char *str) const { return strcmp(data, str) >= 0; } + +string::string() { + size = 64; + data = (char*)malloc(size + 1); + *data = 0; +} + +string::string(int source) { + size = 64; + data = (char*)malloc(size + 1); + *data = 0; + operator=(strdec(source)); +} + +string::string(double source) { + size = 64; + data = (char*)malloc(size + 1); + *data = 0; + operator=(strdouble(source)); +} + +string::string(const char *source) { + size = strlen(source); + data = (char*)malloc(size + 1); + strcpy(data, source); +} + +string::string(const string &source) { + size = strlen(source); + data = (char*)malloc(size + 1); + strcpy(data, source); +} + +string::~string() { + if(data) free(data); +} + +} //namespace nall + +void strcpy(nall::string &dest, const char *src) { + int srclen = strlen(src); + dest.reserve(srclen); + strcpy(dest(), src); +} + +void strcat(nall::string &dest, const char *src) { + int srclen = strlen(src); + int destlen = strlen(dest); + dest.reserve(srclen + destlen); + strcat(dest(), src); +} + +size_t strlcpy(nall::string &dest, const char *src, size_t length) { + dest.reserve(length); + return strlcpy(dest(), src, length); +} + +size_t strlcat(nall::string &dest, const char *src, size_t length) { + dest.reserve(length); + return strlcat(dest(), src, length); +} + +nall::string substr(const char *src, size_t start, size_t length) { +nall::string dest; + if(length == 0) { //copy entire string + strcpy(dest, src + start); + } else { //copy partial string + strlcpy(dest, src + start, length + 1); + } + return dest; +} + +/* very simplistic wrappers to return nall::string& instead of char* type */ + +nall::string& strlower(nall::string &str) { strlower(str()); return str; } +nall::string& strupper(nall::string &str) { strupper(str()); return str; } +nall::string& strtr(nall::string &dest, const char *before, const char *after) { strtr(dest(), before, after); return dest; } +nall::string& ltrim(nall::string &str, const char *key) { ltrim(str(), key); return str; } +nall::string& rtrim(nall::string &str, const char *key) { rtrim(str(), key); return str; } +nall::string& trim (nall::string &str, const char *key) { trim (str(), key); return str; } +nall::string& ltrim_once(nall::string &str, const char *key) { ltrim_once(str(), key); return str; } +nall::string& rtrim_once(nall::string &str, const char *key) { rtrim_once(str(), key); return str; } +nall::string& trim_once (nall::string &str, const char *key) { trim_once (str(), key); return str; } + +/* arithmetic <> string */ + +nall::string strhex(uintmax_t value) { +nall::string temp; + temp.reserve(strhex(0, value)); + strhex(temp(), value); + return temp; +} + +nall::string strdec(intmax_t value) { +nall::string temp; + temp.reserve(strdec(0, value)); + strdec(temp(), value); + return temp; +} + +nall::string strbin(uintmax_t value) { +nall::string temp; + temp.reserve(strbin(0, value)); + strbin(temp(), value); + return temp; +} + +nall::string strdouble(double value) { +nall::string temp; + temp.reserve(strdouble(0, value)); + strdouble(temp(), value); + return temp; +} + +/* ... */ + +bool fread(nall::string &str, const char *filename) { + strcpy(str, ""); + +FILE *fp = fopen(filename, "rb"); + if(!fp)return false; + + fseek(fp, 0, SEEK_END); +size_t size = ftell(fp); + rewind(fp); +char *fdata = (char*)malloc(size + 1); + fread(fdata, 1, size, fp); + fclose(fp); + fdata[size] = 0; + strcpy(str, fdata); + free(fdata); + + return true; +} + +#endif //ifndef NALL_STRING_CLASS_CPP diff --git a/src/lib/nall/string/compare.cpp b/src/lib/nall/string/compare.cpp new file mode 100644 index 00000000..f7155a3d --- /dev/null +++ b/src/lib/nall/string/compare.cpp @@ -0,0 +1,100 @@ +#ifndef NALL_STRING_COMPARE_CPP +#define NALL_STRING_COMPARE_CPP + +char chrlower(char c) { + return (c >= 'A' && c <= 'Z') ? c + ('a' - 'A') : c; +} + +char chrupper(char c) { + return (c >= 'a' && c <= 'z') ? c - ('a' - 'A') : c; +} + +int stricmp(const char *dest, const char *src) { + while(*dest) { + if(chrlower(*dest) != chrlower(*src)) break; + dest++; + src++; + } + + return (int)chrlower(*dest) - (int)chrlower(*src); +} + +int strpos(const char *str, const char *key) { + int ssl = strlen(str), ksl = strlen(key); + + if(ksl > ssl) return -1; + for(int i = 0; i <= ssl - ksl; i++) { + if(!memcmp(str + i, key, ksl)) { + return i; + } + } + return -1; +} + +int qstrpos(const char *str, const char *key) { + int ssl = strlen(str), ksl = strlen(key); + + if(ksl > ssl) return -1; + for(int i = 0; i <= ssl - ksl;) { + uint8_t x = str[i]; + if(x == '\"' || x == '\'') { + uint8_t z = i++; + while(str[i] != x && i < ssl) i++; + if(i >= ssl) i = z; + } + if(!memcmp(str + i, key, ksl)) { + return i; + } else { + i++; + } + } + return -1; +} + +bool strbegin(const char *str, const char *key) { + int i, ssl = strlen(str), ksl = strlen(key); + + if(ksl > ssl) return false; + return (!memcmp(str, key, ksl)); +} + +bool stribegin(const char *str, const char *key) { + int ssl = strlen(str), ksl = strlen(key); + + if(ksl > ssl) return false; + for(int i = 0; i < ksl; i++) { + if(str[i] >= 'A' && str[i] <= 'Z') { + if(str[i] != key[i] && str[i]+0x20 != key[i])return false; + } else if(str[i] >= 'a' && str[i] <= 'z') { + if(str[i] != key[i] && str[i]-0x20 != key[i])return false; + } else { + if(str[i] != key[i])return false; + } + } + return true; +} + +bool strend(const char *str, const char *key) { + int ssl = strlen(str), ksl = strlen(key); + + if(ksl > ssl) return false; + return (!memcmp(str + ssl - ksl, key, ksl)); +} + +bool striend(const char *str, const char *key) { + int ssl = strlen(str), ksl = strlen(key); + + if(ksl > ssl) return false; + for(int i = ssl - ksl, z = 0; i < ssl; i++, z++) { + if(str[i] >= 'A' && str[i] <= 'Z') { + if(str[i] != key[z] && str[i]+0x20 != key[z])return false; + } else if(str[i] >= 'a' && str[i] <= 'z') { + if(str[i] != key[z] && str[i]-0x20 != key[z])return false; + } else { + if(str[i] != key[z])return false; + } + } + return true; +} + +#endif //ifndef NALL_STRING_COMPARE_CPP diff --git a/src/lib/nall/string/convert.cpp b/src/lib/nall/string/convert.cpp new file mode 100644 index 00000000..94a1e175 --- /dev/null +++ b/src/lib/nall/string/convert.cpp @@ -0,0 +1,293 @@ +#ifndef NALL_STRING_CONVERT_CPP +#define NALL_STRING_CONVERT_CPP + +#include +#include +#include + +char* strlower(char *str) { + if(!str) return 0; + int i = 0; + while(str[i]) { + str[i] = chrlower(str[i]); + i++; + } + return str; +} + +char* strupper(char *str) { + if(!str) return 0; + int i = 0; + while(str[i]) { + str[i] = chrupper(str[i]); + i++; + } + return str; +} + +char* strtr(char *dest, const char *before, const char *after) { + if(!dest || !before || !after) return dest; + int sl = strlen(dest), bsl = strlen(before), asl = strlen(after); + + if(bsl != asl || bsl == 0) return dest; //patterns must be the same length for 1:1 replace + for(unsigned i = 0; i < sl; i++) { + for(unsigned l = 0; l < bsl; l++) { + if(dest[i] == before[l]) { + dest[i] = after[l]; + break; + } + } + } + + return dest; +} + +//note: ISO C++ only guarantees that 0-9 is contigious, +//it does not guarantee that either A-F or a-f are also contigious +//however, A-F and a-f are contigious on virtually every platform in existence +//the optimizations and simplifications made possible by this are therefore unignorable +//however, just to be safe, this is tested at compile-time with the below assertion ... +//if false, a compiler error will be thrown + +static nall::static_assert< + ('A' == 'B' - 1) && ('B' == 'C' - 1) && ('C' == 'D' - 1) && ('D' == 'E' - 1) && ('E' == 'F' - 1) && + ('a' == 'b' - 1) && ('b' == 'c' - 1) && ('c' == 'd' - 1) && ('d' == 'e' - 1) && ('e' == 'f' - 1) +> hex_contigious_assertion_; + +uintmax_t strhex(const char *str) { + if(!str) return 0; + uintmax_t result = 0; + + //skip hex identifiers 0x and $, if present + if(*str == '0' && (*(str + 1) == 'X' || *(str + 1) == 'x')) str += 2; + else if(*str == '$') str++; + + while(*str) { + uint8_t x = *str++; + if(x >= '0' && x <= '9') x -= '0'; + else if(x >= 'A' && x <= 'F') x -= 'A' - 10; + else if(x >= 'a' && x <= 'f') x -= 'a' - 10; + else break; //stop at first invalid character + result = result * 16 + x; + } + + return result; +} + +intmax_t strdec(const char *str) { + if(!str) return 0; + intmax_t result = 0; + bool negate = false; + + //check for negation + if(*str == '-') { + negate = true; + str++; + } + + while(*str) { + uint8_t x = *str++; + if(x >= '0' && x <= '9') x -= '0'; + else break; //stop at first invalid character + result = result * 10 + x; + } + + return !negate ? result : -result; +} + +uintmax_t strbin(const char *str) { + if(!str) return 0; + uintmax_t result = 0; + + //skip bin identifiers 0b and %, if present + if(*str == '0' && (*(str + 1) == 'B' || *(str + 1) == 'b')) str += 2; + else if(*str == '%') str++; + + while(*str) { + uint8_t x = *str++; + if(x == '0' || x == '1') x -= '0'; + else break; //stop at first invalid character + result = result * 2 + x; + } + + return result; +} + +double strdouble(const char *str) { + if(!str) return 0.0; + bool negate = false; + + //check for negation + if(*str == '-') { + negate = true; + str++; + } + + intmax_t result_integral = 0; + while(*str) { + uint8_t x = *str++; + if(x >= '0' && x <= '9') x -= '0'; + else if(x == '.') break; //break loop and read fractional part + else return (double)result_integral; //invalid value, assume no fractional part + result_integral = result_integral * 10 + x; + } + + intmax_t result_fractional = 0; + while(*str) { + uint8_t x = *str++; + if(x >= '0' && x <= '9') x -= '0'; + else break; //stop at first invalid character + result_fractional = result_fractional * 10 + x; + } + + //calculate fractional portion + double result = (double)result_fractional; + while((uintmax_t)result > 0) result /= 10.0; + result += (double)result_integral; + + return !negate ? result : -result; +} + +size_t strhex(char *str, uintmax_t value, size_t length /* = 0 */) { + if(!length) length -= 1U; //"infinite" length + size_t initial_length = length; + + //count number of digits in value + int digits_integral = 1; + uintmax_t digits_integral_ = value; + while(digits_integral_ /= 16) digits_integral++; + + int digits = digits_integral; + if(!str) return digits + 1; //only computing required length? + + length = nall::min(digits, length - 1); + str += length; //seek to end of target string + *str = 0; //set null terminator + + while(length--) { + uint8_t x = value % 16; + value /= 16; + *--str = x < 10 ? (x + '0') : (x + 'a' - 10); //iterate backwards to write string + } + + return nall::min(initial_length, digits + 1); +} + +size_t strdec(char *str, intmax_t value_, size_t length /* = 0 */) { + if(!length) length = -1U; //"infinite" length + size_t initial_length = length; + + bool negate = value_ < 0; + uintmax_t value = value_ >= 0 ? value_ : -value_; + + //count number of digits in value + int digits_integral = 1; + uintmax_t digits_integral_ = value; + while(digits_integral_ /= 10) digits_integral++; + + int digits = (negate ? 1 : 0) + digits_integral; + if(!str) return digits + 1; //only computing required length? + + length = nall::min(digits, length - 1); + str += length; //seek to end of target string + *str = 0; //set null terminator + while(length && digits_integral--) { + uint8_t x = '0' + (value % 10); + value /= 10; + *--str = x; //iterate backwards to write string + length--; + } + + if(length && negate) { + *--str = '-'; + } + + return nall::min(initial_length, digits + 1); +} + +size_t strbin(char *str, uintmax_t value, size_t length /* = 0 */) { + if(!length) length = -1U; //"infinite" length + size_t initial_length = length; + + //count number of digits in value + int digits_integral = 1; + uintmax_t digits_integral_ = value; + while(digits_integral_ /= 2) digits_integral++; + + int digits = digits_integral; + if(!str) return digits + 1; //only computing required length? + + length = nall::min(digits, length - 1); + str += length; //seek to end of target string + *str = 0; //set null terminator + + while(length--) { + uint8_t x = '0' + (value % 2); + value /= 2; + *--str = x; //iterate backwards to write string + } + + return nall::min(initial_length, digits + 1); +} + +size_t strdouble(char *str, double value, size_t length /* = 0 */) { + if(!length) length = -1U; //"infinite" length + size_t initial_length = length; + + double fractional, integral; + fractional = modf(value, &integral); + uintmax_t value_integral = (uintmax_t)integral; + uintmax_t value_fractional = 0; + + //convert fractional portion to integral number (eg 0.275 -> 275) + //six nibbles of precision, one nibble for rounding + for(int i = 0; i < 7; i++) { + fractional *= 10.0; + value_fractional = value_fractional * 10 + ((uintmax_t)fractional % 10); + } + + //use seventh nibble to round fraction + value_fractional = (uintmax_t)((double)value_fractional / 10.0 + 0.5); + + //cull fractional zero nibbles (eg 275000 -> 275) + while(value_fractional && !(value_fractional % 10)) value_fractional /= 10; + + //count number of digits in integral value + int digits_integral = 1; + uintmax_t digits_integral_ = value_integral; + while(digits_integral_ /= 10) digits_integral++; + + //count number of digits in fractional value + int digits_fractional = 1; + uintmax_t digits_fractional_ = value_fractional; + while(digits_fractional_ /= 10) digits_fractional++; + + int digits = digits_integral + 1 + digits_fractional; //integral '.' fractional + if(!str) return digits + 1; //only computing required length? + + length = nall::min(digits, length - 1); + str += length; //seek to end of target string + *str = 0; //set null terminator + + while(length && digits_fractional--) { + uint8_t x = '0' + (value_fractional % 10); + value_fractional /= 10; + *--str = x; //iterate backwards to write string + length--; + } + + if(length) { + *--str = '.'; + length--; + } + + while(length-- && digits_integral--) { + uint8_t x = '0' + (value_integral % 10); + value_integral /= 10; + *--str = x; //interate backwards to write string + } + + return nall::min(initial_length, digits + 1); +} + +#endif //ifndef NALL_STRING_CONVERT_CPP diff --git a/src/lib/nall/string/match.cpp b/src/lib/nall/string/match.cpp new file mode 100644 index 00000000..43df1e36 --- /dev/null +++ b/src/lib/nall/string/match.cpp @@ -0,0 +1,72 @@ +#ifndef NALL_MATCH_CPP +#define NALL_MATCH_CPP + +bool match(const char *p, const char *s) { + const char *p_ = 0, *s_ = 0; + + for(;;) { + if(!*s) { + while(*p == '*') p++; + return !*p; + } + + //wildcard match + if(*p == '*') { + p_ = p++, s_ = s; + continue; + } + + //any match + if(*p == '?') { + p++, s++; + continue; + } + + //ranged match + if(*p == '{') { + #define pattern(name_, rule_) \ + if(strbegin(p, name_)) { \ + if(rule_) { \ + p += sizeof(name_) - 1, s++; \ + continue; \ + } \ + goto failure; \ + } + + pattern("{alpha}", (*s >= 'A' && *s <= 'Z') || (*s >= 'a' && *s <= 'z')) + pattern("{alphanumeric}", (*s >= 'A' && *s <= 'Z') || (*s >= 'a' && *s <= 'z') || (*s >= '0' && *s <= '9')) + pattern("{binary}", (*s == '0' || *s == '1')) + pattern("{hex}", (*s >= '0' && *s <= '9') || (*s >= 'A' && *s <= 'F') || (*s >= 'a' && *s <= 'f')) + pattern("{lowercase}", (*s >= 'a' && *s <= 'z')) + pattern("{numeric}", (*s >= '0' && *s <= '9')) + pattern("{uppercase}", (*s >= 'A' && *s <= 'Z')) + pattern("{whitespace}", (*s == ' ' || *s == '\t')) + + #undef pattern + goto failure; + } + + //reserved character match + if(*p == '\\') { + p++; + //fallthrough + } + + //literal match + if(*p == *s) { + p++, *s++; + continue; + } + + //attempt wildcard rematch + failure: + if(p_) { + p = p_, s = s_ + 1; + continue; + } + + return false; + } +} + +#endif //ifndef NALL_MATCH_CPP diff --git a/src/lib/nall/string/math.cpp b/src/lib/nall/string/math.cpp new file mode 100644 index 00000000..7a7249db --- /dev/null +++ b/src/lib/nall/string/math.cpp @@ -0,0 +1,150 @@ +#ifndef NALL_MATH_CPP +#define NALL_MATH_CPP + +static int eval_integer(const char *&s) { + if(!*s) throw "nall::bad_eval_integer"; + int value = 0, x = *s, y = *(s + 1); + + //hexadecimal + if(x == '0' && (y == 'X' || y == 'x')) { + s += 2; + for(;;) { + if(*s >= '0' && *s <= '9') { value = value * 16 + (*s++ - '0'); continue; } + if(*s >= 'A' && *s <= 'F') { value = value * 16 + (*s++ - 'A' + 10); continue; } + if(*s >= 'a' && *s <= 'f') { value = value * 16 + (*s++ - 'a' + 10); continue; } + return value; + } + } + + //binary + if(x == '0' && (y == 'B' || y == 'b')) { + s += 2; + for(;;) { + if(*s == '0' || *s == '1') { value = value * 2 + (*s++ - '0'); continue; } + return value; + } + } + + //octal (or decimal '0') + if(x == '0') { + s += 1; + for(;;) { + if(*s >= '0' && *s <= '7') { value = value * 8 + (*s++ - '0'); continue; } + return value; + } + } + + //decimal + if(x >= '0' && x <= '9') { + for(;;) { + if(*s >= '0' && *s <= '9') { value = value * 10 + (*s++ - '0'); continue; } + return value; + } + } + + throw "nall::bad_eval_integer"; +} + +static int eval(const char *&s, int depth = 0) { + if(!*s) throw "nall::bad_eval"; + while(*s == ' ' || *s == '\t') s++; //trim whitespace + int value = 0, x = *s, y = *(s + 1); + + if(*s == '(') { + value = eval(++s, 1); + if(*s++ != ')') throw "nall::bad_eval"; + } + + else if(x == '!') value = !eval(++s, 14); + else if(x == '~') value = ~eval(++s, 14); + else if(x == '+') value = +eval(++s, 14); + else if(x == '-') value = -eval(++s, 14); + + else if(x >= '0' && x <= '9') value = eval_integer(s); + + else throw "nall::bad_eval"; + + for(;;) { + while(*s == ' ' || *s == '\t') s++; //trim whitespace + if(!*s) break; + x = *s, y = *(s + 1); + + if(depth >= 13) break; + if(x == '*') { value *= eval(++s, 13); continue; } + if(x == '/') { value /= eval(++s, 13); continue; } + if(x == '%') { value %= eval(++s, 13); continue; } + + if(depth >= 12) break; + if(x == '+') { value += eval(++s, 12); continue; } + if(x == '-') { value -= eval(++s, 12); continue; } + + if(depth >= 11) break; + if(x == '<' && y == '<') { value <<= eval(++++s, 11); continue; } + if(x == '>' && y == '>') { value >>= eval(++++s, 11); continue; } + + if(depth >= 10) break; + if(x == '<' && y == '=') { value = value <= eval(++++s, 10); continue; } + if(x == '>' && y == '=') { value = value >= eval(++++s, 10); continue; } + if(x == '<') { value = value < eval(++s, 10); continue; } + if(x == '>') { value = value > eval(++s, 10); continue; } + + if(depth >= 9) break; + if(x == '=' && y == '=') { value = value == eval(++++s, 9); continue; } + if(x == '!' && y == '=') { value = value != eval(++++s, 9); continue; } + + if(depth >= 8) break; + if(x == '&' && y != '&') { value = value & eval(++s, 8); continue; } + + if(depth >= 7) break; + if(x == '^' && y != '^') { value = value ^ eval(++s, 7); continue; } + + if(depth >= 6) break; + if(x == '|' && y != '|') { value = value | eval(++s, 6); continue; } + + if(depth >= 5) break; + if(x == '&' && y == '&') { value = eval(++++s, 5) && value; continue; } + + if(depth >= 4) break; + if(x == '^' && y == '^') { value = (!eval(++++s, 4) != !value); continue; } + + if(depth >= 3) break; + if(x == '|' && y == '|') { value = eval(++++s, 3) || value; continue; } + + if(depth >= 2) break; + if(x == '?') { + int lhs = eval(++s, 2); + if(*s != ':') throw "nall::bad_eval"; + int rhs = eval(++s, 2); + value = value ? lhs : rhs; + continue; + } + + if(depth > 0 && x == ')') break; + + throw "nall::bad_eval"; + } + + return value; +} + +bool strint(const char *s, int &result) { + try { + result = eval_integer(s); + return true; + } catch(const char*) { + result = 0; + return false; + } +} + +bool strmath(const char *s, int &result) { + try { + result = eval(s); + return true; + } catch(const char*) { + result = 0; + return false; + } +} + +#endif //ifndef NALL_MATH_CPP diff --git a/src/lib/bstring/bstring.replace.cpp b/src/lib/nall/string/replace.cpp similarity index 77% rename from src/lib/bstring/bstring.replace.cpp rename to src/lib/nall/string/replace.cpp index 3c35c78c..f6f28a1a 100644 --- a/src/lib/bstring/bstring.replace.cpp +++ b/src/lib/nall/string/replace.cpp @@ -1,9 +1,11 @@ -#ifdef BSTRING_H +#ifndef NALL_STRING_REPLACE_CPP +#define NALL_STRING_REPLACE_CPP + +nall::string &replace(nall::string &str, const char *key, const char *token) { + int i, z, ksl = strlen(key), tsl = strlen(token), ssl = strlen(str); + unsigned int replace_count = 0, size = ssl; + char *data; -string &replace(string &str, const char *key, const char *token) { -int i, z, ksl = strlen(key), tsl = strlen(token), ssl = strlen(str); -uint replace_count = 0, size = ssl; -char *data; if(ksl > ssl)return str; if(tsl > ksl) { //the new string may be longer than the old string... for(i = 0; i <= ssl - ksl;) { //so let's find out how big of a string we'll need... @@ -31,11 +33,12 @@ char *data; return str; } -string &qreplace(string &str, const char *key, const char *token) { -int i, l, z, ksl = strlen(key), tsl = strlen(token), ssl = strlen(str); -uint replace_count = 0, size = ssl; -uint8 x; -char *data; +nall::string &qreplace(nall::string &str, const char *key, const char *token) { + int i, l, z, ksl = strlen(key), tsl = strlen(token), ssl = strlen(str); + unsigned int replace_count = 0, size = ssl; + uint8_t x; + char *data; + if(ksl > ssl)return str; if(tsl > ksl) { for(i = 0; i <= ssl - ksl;) { @@ -85,4 +88,4 @@ char *data; return str; } -#endif //ifdef BSTRING_H +#endif //ifndef NALL_STRING_REPLACE_CPP diff --git a/src/lib/nall/string/split.cpp b/src/lib/nall/string/split.cpp new file mode 100644 index 00000000..29dd246b --- /dev/null +++ b/src/lib/nall/string/split.cpp @@ -0,0 +1,52 @@ +#ifndef NALL_STRING_SPLIT_CPP +#define NALL_STRING_SPLIT_CPP + +void split(nall::lstring &dest, const char *key, const char *src, size_t limit) { + dest.reset(); + + int ssl = strlen(src), ksl = strlen(key); + int lp = 0, split_count = 0; + + for(int i = 0; i <= ssl - ksl;) { + if(!memcmp(src + i, key, ksl)) { + strlcpy(dest[split_count++], src + lp, i - lp + 1); + i += ksl; + lp = i; + if(!--limit) break; + } else i++; + } + + strcpy(dest[split_count++], src + lp); +} + +void qsplit(nall::lstring &dest, const char *key, const char *src, size_t limit) { + dest.reset(); + + int ssl = strlen(src), ksl = strlen(key); + int lp = 0, split_count = 0; + + for(int i = 0; i <= ssl - ksl;) { + uint8_t x = src[i]; + + if(x == '\"' || x == '\'') { + int z = i++; //skip opening quote + while(i < ssl && src[i] != x) i++; + if(i >= ssl) i = z; //failed match, rewind i + else { + i++; //skip closing quote + continue; //restart in case next char is also a quote + } + } + + if(!memcmp(src + i, key, ksl)) { + strlcpy(dest[split_count++], src + lp, i - lp + 1); + i += ksl; + lp = i; + if(!--limit) break; + } else i++; + } + + strcpy(dest[split_count++], src + lp); +} + +#endif //ifndef NALL_STRING_SPLIT_CPP diff --git a/src/lib/nall/string/strl.cpp b/src/lib/nall/string/strl.cpp new file mode 100644 index 00000000..d7efa354 --- /dev/null +++ b/src/lib/nall/string/strl.cpp @@ -0,0 +1,48 @@ +#ifndef NALL_STRING_STRL_CPP +#define NALL_STRING_STRL_CPP + +//strlcpy, strlcat based on OpenBSD implementation by Todd C. Miller + +//return = strlen(src) +size_t strlcpy(char *dest, const char *src, size_t length) { + char *d = dest; + const char *s = src; + size_t n = length; + + if(n) { + while(--n && (*d++ = *s++)); //copy as many bytes as possible, or until null terminator reached + } + + if(!n) { + if(length) *d = 0; + while(*s++); //traverse rest of s, so that s - src == strlen(src) + } + + return (s - src - 1); //return length of copied string, sans null terminator +} + +//return = strlen(src) + min(length, strlen(dest)) +size_t strlcat(char *dest, const char *src, size_t length) { + char *d = dest; + const char *s = src; + size_t n = length; + + while(n-- && *d) d++; //find end of dest + size_t dlength = d - dest; + n = length - dlength; //subtract length of dest from maximum string length + + if(!n) return dlength + strlen(s); + + while(*s) { + if(n != 1) { + *d++ = *s; + n--; + } + s++; + } + *d = 0; + + return dlength + (s - src); //return length of resulting string, sans null terminator +} + +#endif //ifndef NALL_STRING_STRL_CPP diff --git a/src/lib/nall/string/trim.cpp b/src/lib/nall/string/trim.cpp new file mode 100644 index 00000000..087f4743 --- /dev/null +++ b/src/lib/nall/string/trim.cpp @@ -0,0 +1,36 @@ +#ifndef NALL_STRING_TRIM_CPP +#define NALL_STRING_TRIM_CPP + +char* ltrim(char *str, const char *key) { + if(!key || !*key) return str; + while(strbegin(str, key)) strcpy(str, str + strlen(key)); + return str; +} + +char* rtrim(char *str, const char *key) { + if(!key || !*key) return str; + while(strend(str, key)) str[strlen(str) - strlen(key)] = 0; + return str; +} + +char* trim(char *str, const char *key) { + return ltrim(rtrim(str, key), key); +} + +char* ltrim_once(char *str, const char *key) { + if(!key || !*key) return str; + if(strbegin(str, key)) strcpy(str, str + strlen(key)); + return str; +} + +char* rtrim_once(char *str, const char *key) { + if(!key || !*key) return str; + if(strend(str, key)) str[strlen(str) - strlen(key)] = 0; + return str; +} + +char* trim_once(char *str, const char *key) { + return ltrim_once(rtrim_once(str, key), key); +} + +#endif //ifndef NALL_STRING_TRIM_CPP diff --git a/src/lib/nall/traits.hpp b/src/lib/nall/traits.hpp new file mode 100644 index 00000000..168e90d3 --- /dev/null +++ b/src/lib/nall/traits.hpp @@ -0,0 +1,90 @@ +#ifndef NALL_TRAITS_HPP +#define NALL_TRAITS_HPP + +namespace nall { + +/* is */ + +template struct is_integral { enum { value = false }; }; +template<> struct is_integral { enum { value = true }; }; +template<> struct is_integral { enum { value = true }; }; +template<> struct is_integral { enum { value = true }; }; +template<> struct is_integral { enum { value = true }; }; +template<> struct is_integral { enum { value = true }; }; +template<> struct is_integral { enum { value = true }; }; +template<> struct is_integral { enum { value = true }; }; +template<> struct is_integral { enum { value = true }; }; +template<> struct is_integral { enum { value = true }; }; +template<> struct is_integral { enum { value = true }; }; +template<> struct is_integral { enum { value = true }; }; +template<> struct is_integral { enum { value = true }; }; +template<> struct is_integral { enum { value = true }; }; + +template struct is_floating_point { enum { value = false }; }; +template<> struct is_floating_point { enum { value = true }; }; +template<> struct is_floating_point { enum { value = true }; }; +template<> struct is_floating_point { enum { value = true }; }; + +template struct is_void { enum { value = false }; }; +template<> struct is_void { enum { value = true }; }; + +template struct is_arithmetic { + enum { value = is_integral::value || is_floating_point::value }; +}; + +template struct is_fundamental { + enum { value = is_integral::value || is_floating_point::value || is_void::value }; +}; + +template struct is_compound { + enum { value = !is_fundamental::value }; +}; + +template struct is_array { enum { value = false }; }; +template struct is_array { enum { value = true }; }; +template struct is_array { enum { value = true }; }; + +template struct is_const { enum { value = false }; }; +template struct is_const { enum { value = true }; }; +template struct is_const { enum { value = true }; }; + +template struct is_pointer { enum { value = false }; }; +template struct is_pointer { enum { value = true }; }; + +template struct is_reference { enum { value = false }; }; +template struct is_reference { enum { value = true }; }; + +template struct is_same { enum { value = false }; }; +template struct is_same { enum { value = true }; }; + +/* add */ + +template struct add_const { typedef const T type; }; +template struct add_const { typedef const T type; }; +template struct add_const { typedef const T& type; }; + +template struct add_pointer { typedef T* type; }; +template struct add_pointer { typedef T** type; }; + +template struct add_reference { typedef T& type; }; +template struct add_reference { typedef T& type; }; + +/* remove */ + +template struct remove_const { typedef T type; }; +template struct remove_const { typedef T type; }; +template struct remove_const { typedef T type; }; + +template struct remove_extent { typedef T type; }; +template struct remove_extent { typedef T type; }; +template struct remove_extent { typedef T type; }; + +template struct remove_pointer { typedef T type; }; +template struct remove_pointer { typedef T type; }; + +template struct remove_reference { typedef T type; }; +template struct remove_reference { typedef T type; }; + +} //namespace nall + +#endif //ifndef NALL_TRAITS_HPP diff --git a/src/lib/nall/utility.hpp b/src/lib/nall/utility.hpp new file mode 100644 index 00000000..9a8caf40 --- /dev/null +++ b/src/lib/nall/utility.hpp @@ -0,0 +1,24 @@ +#ifndef NALL_UTILITY_HPP +#define NALL_UTILITY_HPP + +namespace nall { + +template +struct base_from_member { + T value; + base_from_member(T value_) : value(value_) {} +}; + +class noncopyable { +protected: + noncopyable() {} + ~noncopyable() {} + +private: + noncopyable(const noncopyable&); + const noncopyable& operator=(const noncopyable&); +}; + +} //namespace nall + +#endif //ifndef NALL_UTILITY_HPP diff --git a/src/lib/nall/varint.hpp b/src/lib/nall/varint.hpp new file mode 100644 index 00000000..d90db1e1 --- /dev/null +++ b/src/lib/nall/varint.hpp @@ -0,0 +1,103 @@ +#ifndef NALL_VARINT_HPP +#define NALL_VARINT_HPP + +#include +#include + +namespace nall { + +template class uint_t { +private: + enum { bytes = (bits + 7) >> 3 }; //minimum number of bytes needed to store value + typedef typename static_if< + sizeof(int) >= bytes, + unsigned int, + typename static_if< + sizeof(long) >= bytes, + unsigned long, + typename static_if< + sizeof(long long) >= bytes, + unsigned long long, + void + >::type + >::type + >::type T; + static_assert::value> uint_assert; + T data; + +public: + inline operator T() const { return data; } + inline T operator ++(int) { T r = data; data = uclip(data + 1); return r; } + inline T operator --(int) { T r = data; data = uclip(data - 1); return r; } + inline T& operator ++() { data = uclip(data + 1); return *this; } + inline T& operator --() { data = uclip(data - 1); return *this; } + inline T& operator =(const T i) { data = uclip(i); return *this; } + inline T& operator |=(const T i) { data = uclip(data | i); return *this; } + inline T& operator ^=(const T i) { data = uclip(data ^ i); return *this; } + inline T& operator &=(const T i) { data = uclip(data & i); return *this; } + inline T& operator<<=(const T i) { data = uclip(data << i); return *this; } + inline T& operator>>=(const T i) { data = uclip(data >> i); return *this; } + inline T& operator +=(const T i) { data = uclip(data + i); return *this; } + inline T& operator -=(const T i) { data = uclip(data - i); return *this; } + inline T& operator *=(const T i) { data = uclip(data * i); return *this; } + inline T& operator /=(const T i) { data = uclip(data / i); return *this; } + inline T& operator %=(const T i) { data = uclip(data % i); return *this; } + + inline uint_t() : data(0) {} + inline uint_t(const T i) : data(uclip(i)) {} +}; + +template class int_t { +private: + enum { bytes = (bits + 7) >> 3 }; //minimum number of bytes needed to store value + typedef typename static_if< + sizeof(int) >= bytes, + signed int, + typename static_if< + sizeof(long) >= bytes, + signed long, + typename static_if< + sizeof(long long) >= bytes, + signed long long, + void + >::type + >::type + >::type T; + static_assert::value> int_assert; + T data; + +public: + inline operator T() const { return data; } + inline T operator ++(int) { T r = data; data = sclip(data + 1); return r; } + inline T operator --(int) { T r = data; data = sclip(data - 1); return r; } + inline T& operator ++() { data = sclip(data + 1); return *this; } + inline T& operator --() { data = sclip(data - 1); return *this; } + inline T& operator =(const T i) { data = sclip(i); return *this; } + inline T& operator |=(const T i) { data = sclip(data | i); return *this; } + inline T& operator ^=(const T i) { data = sclip(data ^ i); return *this; } + inline T& operator &=(const T i) { data = sclip(data & i); return *this; } + inline T& operator<<=(const T i) { data = sclip(data << i); return *this; } + inline T& operator>>=(const T i) { data = sclip(data >> i); return *this; } + inline T& operator +=(const T i) { data = sclip(data + i); return *this; } + inline T& operator -=(const T i) { data = sclip(data - i); return *this; } + inline T& operator *=(const T i) { data = sclip(data * i); return *this; } + inline T& operator /=(const T i) { data = sclip(data / i); return *this; } + inline T& operator %=(const T i) { data = sclip(data % i); return *this; } + + inline int_t() : data(0) {} + inline int_t(const T i) : data(sclip(i)) {} +}; + +typedef int_t<24> int24_t; +typedef uint_t<24> uint24_t; +typedef int_t<48> int48_t; +typedef uint_t<48> uint48_t; + +} //namespace nall + +using nall::int24_t; +using nall::uint24_t; +using nall::int48_t; +using nall::uint48_t; + +#endif //ifndef NALL_VARINT_HPP diff --git a/src/lib/bvector.h b/src/lib/nall/vector.hpp similarity index 79% rename from src/lib/bvector.h rename to src/lib/nall/vector.hpp index c4a67ba2..dd408a4a 100644 --- a/src/lib/bvector.h +++ b/src/lib/nall/vector.hpp @@ -1,7 +1,9 @@ -/* - bvector : version 0.05 ~byuu (2006-12-16) - license: public domain -*/ +#ifndef NALL_VECTOR_HPP +#define NALL_VECTOR_HPP + +#include + +namespace nall { /***** * Dynamic vector allocation template class library @@ -65,20 +67,17 @@ * and speed is less critical. *****/ -#ifndef BVECTOR_H -#define BVECTOR_H - template class linear_vector { protected: -T *pool; -uint poolsize, objectsize; + T *pool; + unsigned poolsize, objectsize; public: - uint size() { return objectsize; } - uint capacity() { return poolsize; } + unsigned size() const { return objectsize; } + unsigned capacity() const { return poolsize; } void reset() { - for(uint i = 0; i < objectsize; i++) { pool[i].~T(); } + for(unsigned i = 0; i < objectsize; i++) { pool[i].~T(); } if(pool) { free(pool); @@ -89,11 +88,11 @@ public: objectsize = 0; } - void reserve(uint size) { + void reserve(unsigned size) { if(size == poolsize)return; if(size < poolsize) { - for(uint i = size; i < objectsize; i++) { pool[i].~T(); } + for(unsigned i = size; i < objectsize; i++) { pool[i].~T(); } objectsize = size; } @@ -106,9 +105,9 @@ public: if(size > poolsize)reserve(size); if(size < objectsize) { - for(uint i = size; i < objectsize; i++) { pool[i].~T(); } + for(unsigned i = size; i < objectsize; i++) { pool[i].~T(); } } else { - for(uint i = objectsize; i < size; i++) { new(pool + i) T; } + for(unsigned i = objectsize; i < size; i++) { new(pool + i) T; } } objectsize = size; @@ -137,15 +136,15 @@ public: template class ptr_vector { protected: -T **pool; -uint poolsize, objectsize; + T **pool; + unsigned poolsize, objectsize; public: - uint size() { return objectsize; } - uint capacity() { return poolsize; } + unsigned size() const { return objectsize; } + unsigned capacity() const { return poolsize; } void reset() { - for(uint i = 0; i < objectsize; i++) { if(pool[i])delete pool[i]; } + for(unsigned i = 0; i < objectsize; i++) { if(pool[i])delete pool[i]; } if(pool) { free(pool); @@ -156,11 +155,11 @@ public: objectsize = 0; } - void reserve(uint size) { + void reserve(unsigned size) { if(size == poolsize)return; if(size < poolsize) { - for(uint i = size; i < objectsize; i++) { if(pool[i])delete pool[i]; } + for(unsigned i = size; i < objectsize; i++) { if(pool[i])delete pool[i]; } objectsize = size; } @@ -176,7 +175,7 @@ public: if(size > poolsize)reserve(size); if(size < objectsize) { - for(uint i = size; i < objectsize; i++) { if(pool[i])delete pool[i]; } + for(unsigned i = size; i < objectsize; i++) { if(pool[i])delete pool[i]; } } objectsize = size; @@ -203,6 +202,10 @@ public: if(!pool[index])pool[index] = new T; return *pool[index]; } -}; +}; + +template class vector : public linear_vector {}; + +} //namespace nall -#endif //ifndef BVECTOR_H +#endif //ifndef NALL_VECTOR_HPP diff --git a/src/ui/vai/audio.h b/src/lib/ruby/audio.h similarity index 57% rename from src/ui/vai/audio.h rename to src/lib/ruby/audio.h index 8d42a948..ae536c95 100644 --- a/src/ui/vai/audio.h +++ b/src/lib/ruby/audio.h @@ -1,8 +1,3 @@ -#ifndef AUDIO_H -#define AUDIO_H - -#include "../../lib/bbase.h" - class Audio { public: enum Setting { @@ -15,13 +10,11 @@ public: virtual uintptr_t get(Setting) { return false; } virtual bool set(Setting, uintptr_t) { return false; } - virtual void sample(uint16 left, uint16 right) {} - virtual void clear_audio() {} - virtual void init() {} + virtual void sample(uint16_t left, uint16_t right) {} + virtual void clear() {} + virtual bool init() { return true; } virtual void term() {} Audio() {} virtual ~Audio() {} }; - -#endif //ifndef AUDIO_H diff --git a/src/ui/vai/audio/audio.ao.cpp b/src/lib/ruby/audio/ao.cpp similarity index 77% rename from src/ui/vai/audio/audio.ao.cpp rename to src/lib/ruby/audio/ao.cpp index caca1c22..9c47dc5e 100644 --- a/src/ui/vai/audio/audio.ao.cpp +++ b/src/lib/ruby/audio/ao.cpp @@ -1,46 +1,51 @@ -#include "audio.ao.h" - -#include +#include + +#include + +namespace ruby { + +#include "ao.h" class pAudioAO { public: AudioAO &self; + int driver_id; ao_sample_format driver_format; - ao_device *audio_device; - - struct { - uint frequency; - } settings; - - bool cap(Audio::Setting setting) { - if(setting == Audio::Frequency) return true; - return false; + ao_device *audio_device; + + struct { + unsigned frequency; + } settings; + + bool cap(Audio::Setting setting) { + if(setting == Audio::Frequency) return true; + return false; + } + + uintptr_t get(Audio::Setting setting) { + if(setting == Audio::Frequency) return settings.frequency; + return false; } - - uintptr_t get(Audio::Setting setting) { - if(setting == Audio::Frequency) return settings.frequency; - return false; - } - - bool set(Audio::Setting setting, uintptr_t param) { + + bool set(Audio::Setting setting, uintptr_t param) { if(setting == Audio::Frequency) { settings.frequency = param; if(audio_device) { term(); init(); } - return true; - } - return false; - } + return true; + } + return false; + } - void sample(uint16 l_sample, uint16 r_sample) { - uint32 samp = (l_sample << 0) + (r_sample << 16); + void sample(uint16_t l_sample, uint16_t r_sample) { + uint32_t samp = (l_sample << 0) + (r_sample << 16); ao_play(audio_device, (char*)&samp, 4); //This may need to be byte swapped for Big Endian } - void init() { + bool init() { driver_id = ao_default_driver_id(); //ao_driver_id((const char*)driver) if(driver_id < 0) driver_id = ao_default_driver_id(); //fallback on default if driver doesn't exist driver_format.bits = 16; @@ -49,11 +54,10 @@ public: driver_format.byte_format = AO_FMT_LITTLE; audio_device = ao_open_live(driver_id, &driver_format, 0); - if(audio_device) { - ao_info *di = ao_driver_info(driver_id); - } else { - printf("libao: failed to open audio device.\n"); - } + if(!audio_device) return false; + + ao_info *di = ao_driver_info(driver_id); + return true; } void term() { @@ -64,9 +68,10 @@ public: } pAudioAO(AudioAO &self_) : self(self_) { - settings.frequency = 22050; audio_device = 0; - ao_initialize(); + ao_initialize(); + + settings.frequency = 22050; } ~pAudioAO() { @@ -74,12 +79,14 @@ public: //ao_shutdown(); //FIXME: this is causing a segfault for some reason when called ... } }; - -bool AudioAO::cap(Setting setting) { return p.cap(setting); } -uintptr_t AudioAO::get(Setting setting) { return p.get(setting); } + +bool AudioAO::cap(Setting setting) { return p.cap(setting); } +uintptr_t AudioAO::get(Setting setting) { return p.get(setting); } bool AudioAO::set(Setting setting, uintptr_t param) { return p.set(setting, param); } -void AudioAO::sample(uint16 l_sample, uint16 r_sample) { p.sample(l_sample, r_sample); } -void AudioAO::init() { p.init(); } +void AudioAO::sample(uint16_t l_sample, uint16_t r_sample) { p.sample(l_sample, r_sample); } +bool AudioAO::init() { return p.init(); } void AudioAO::term() { p.term(); } AudioAO::AudioAO() : p(*new pAudioAO(*this)) {} AudioAO::~AudioAO() { delete &p; } + +} //namespace ruby diff --git a/src/ui/vai/audio/audio.ao.h b/src/lib/ruby/audio/ao.h similarity index 54% rename from src/ui/vai/audio/audio.ao.h rename to src/lib/ruby/audio/ao.h index 2037ea4f..c343e419 100644 --- a/src/ui/vai/audio/audio.ao.h +++ b/src/lib/ruby/audio/ao.h @@ -1,25 +1,23 @@ -#ifndef AUDIO_AO_H -#define AUDIO_AO_H - -#include "../audio.h" - -class pAudioAO; - -class AudioAO : public Audio { -public: - bool cap(Setting); - uintptr_t get(Setting); - bool set(Setting, uintptr_t); - - void sample(uint16 left, uint16 right); - void init(); - void term(); - - AudioAO(); - ~AudioAO(); - -private: - pAudioAO &p; -}; - -#endif //ifndef AUDIO_AO_H +/* + audio.ao (2007-12-26) + author: Nach +*/ + +class pAudioAO; + +class AudioAO : public Audio { +public: + bool cap(Setting); + uintptr_t get(Setting); + bool set(Setting, uintptr_t); + + void sample(uint16_t left, uint16_t right); + bool init(); + void term(); + + AudioAO(); + ~AudioAO(); + +private: + pAudioAO &p; +}; diff --git a/src/ui/vai/audio/audio.directsound.cpp b/src/lib/ruby/audio/directsound.cpp similarity index 79% rename from src/ui/vai/audio/audio.directsound.cpp rename to src/lib/ruby/audio/directsound.cpp index a27eed9b..c5f080ec 100644 --- a/src/ui/vai/audio/audio.directsound.cpp +++ b/src/lib/ruby/audio/directsound.cpp @@ -1,28 +1,31 @@ -#include "audio.directsound.h" - -#define WIN32_LEAN_AND_MEAN #include #include +#include + +namespace ruby { + +#include "directsound.h" + class pAudioDS { public: AudioDS &self; + LPDIRECTSOUND ds; LPDIRECTSOUNDBUFFER dsb_p, dsb_b; DSBUFFERDESC dsbd; WAVEFORMATEX wfx; struct { - uint32 *buffer; - uint buffer_pos, ring_pos; - uint buffer_size, ring_size; + uint32_t *buffer; + unsigned buffer_pos, ring_pos; + unsigned buffer_size, ring_size; } data; struct { HWND handle; bool synchronize; - uint frequency; - uint latency; + unsigned frequency; } settings; bool cap(Audio::Setting setting) { @@ -50,16 +53,15 @@ public: } if(setting == Audio::Frequency) { settings.frequency = param; - settings.latency = param / 40; - if(ds) init(); //reinitialize only if previously initialized + if(ds) init(); return true; } return false; } - void sample(uint16 l_sample, uint16 r_sample) { + void sample(uint16_t l_sample, uint16_t r_sample) { data.buffer[data.buffer_pos++] = (l_sample << 0) + (r_sample << 16); - if(data.buffer_pos < settings.latency) return; + if(data.buffer_pos < settings.frequency / 40) return; DWORD ring_pos, pos, size; for(;;) { @@ -80,7 +82,7 @@ public: data.buffer_pos = 0; } - void clear_audio() { + void clear() { data.buffer_pos = 0; data.ring_pos = 0; if(data.buffer) memset(data.buffer, 0, data.buffer_size); @@ -98,17 +100,17 @@ public: dsb_b->Play(0, 0, DSBPLAY_LOOPING); } - void init() { - clear_audio(); + bool init() { + clear(); term(); - data.ring_size = settings.latency * sizeof(uint32); + data.ring_size = settings.frequency / 40 * sizeof(uint32_t); data.buffer_size = data.ring_size * 16; - data.buffer = (uint32*)malloc(data.buffer_size); + data.buffer = (uint32_t*)malloc(data.buffer_size); data.buffer_pos = 0; DirectSoundCreate(0, &ds, 0); - ds->SetCooperativeLevel(settings.handle, DSSCL_PRIORITY); + ds->SetCooperativeLevel((HWND)settings.handle, DSSCL_PRIORITY); memset(&dsbd, 0, sizeof(dsbd)); dsbd.dwSize = sizeof(dsbd); @@ -137,11 +139,15 @@ public: dsb_b->SetFrequency(settings.frequency); dsb_b->SetCurrentPosition(0); - clear_audio(); + clear(); + return true; } void term() { - safe_free(data.buffer); + if(data.buffer) { + free(data.buffer); + data.buffer = 0; + } if(dsb_b) { dsb_b->Stop(); dsb_b->Release(); dsb_b = 0; } if(dsb_p) { dsb_p->Stop(); dsb_p->Release(); dsb_p = 0; } @@ -162,16 +168,17 @@ public: settings.handle = GetDesktopWindow(); settings.synchronize = false; settings.frequency = 22050; - settings.latency = settings.frequency / 40; } }; bool AudioDS::cap(Setting setting) { return p.cap(setting); } uintptr_t AudioDS::get(Setting setting) { return p.get(setting); } bool AudioDS::set(Setting setting, uintptr_t param) { return p.set(setting, param); } -void AudioDS::sample(uint16 l_sample, uint16 r_sample) { p.sample(l_sample, r_sample); } -void AudioDS::clear_audio() { p.clear_audio(); } -void AudioDS::init() { p.init(); } +void AudioDS::sample(uint16_t l_sample, uint16_t r_sample) { p.sample(l_sample, r_sample); } +void AudioDS::clear() { p.clear(); } +bool AudioDS::init() { return p.init(); } void AudioDS::term() { p.term(); } AudioDS::AudioDS() : p(*new pAudioDS(*this)) {} AudioDS::~AudioDS() { delete &p; } + +} //namespace ruby diff --git a/src/lib/ruby/audio/directsound.h b/src/lib/ruby/audio/directsound.h new file mode 100644 index 00000000..9fe0a188 --- /dev/null +++ b/src/lib/ruby/audio/directsound.h @@ -0,0 +1,24 @@ +/* + audio.directsound (2007-12-26) + author: byuu +*/ + +class pAudioDS; + +class AudioDS : public Audio { +public: + bool cap(Setting); + uintptr_t get(Setting); + bool set(Setting, uintptr_t); + + void sample(uint16_t left, uint16_t right); + void clear(); + bool init(); + void term(); + + AudioDS(); + ~AudioDS(); + +private: + pAudioDS &p; +}; diff --git a/src/lib/ruby/audio/openal.cpp b/src/lib/ruby/audio/openal.cpp new file mode 100644 index 00000000..4aad7c42 --- /dev/null +++ b/src/lib/ruby/audio/openal.cpp @@ -0,0 +1,194 @@ +#include +#include + +#include + +namespace ruby { + +#include "openal.h" + +class pAudioOpenAL { +public: + AudioOpenAL &self; + + struct { + ALCdevice *handle; + ALCcontext *context; + ALuint source; + ALenum format; + unsigned latency; + unsigned queue_length; + } device; + + struct { + uint32_t *data; + unsigned length; + unsigned size; + } buffer; + + struct { + bool synchronize; + unsigned frequency; + } settings; + + bool cap(Audio::Setting setting) { + if(setting == Audio::Synchronize) return true; + if(setting == Audio::Frequency) return true; + return false; + } + + uintptr_t get(Audio::Setting setting) { + if(setting == Audio::Synchronize) return settings.synchronize; + if(setting == Audio::Frequency) return settings.frequency; + return false; + } + + bool set(Audio::Setting setting, uintptr_t param) { + if(setting == Audio::Synchronize) { + settings.synchronize = param; + return true; + } + if(setting == Audio::Frequency) { + settings.frequency = param; + return true; + } + return false; + } + + void sample(uint16_t sl, uint16_t sr) { + buffer.data[buffer.length++] = sl + (sr << 16); + if(buffer.length < buffer.size) return; + + ALuint albuffer = 0; + int processed = 0; + for(;;) { + alGetSourcei(device.source, AL_BUFFERS_PROCESSED, &processed); + while(processed--) { + alSourceUnqueueBuffers(device.source, 1, &albuffer); + alDeleteBuffers(1, &albuffer); + device.queue_length--; + } + //wait for buffer playback to catch up to sample generation if not synchronizing + if(settings.synchronize == false || device.queue_length < 3) break; + } + + if(device.queue_length < 3) { + alGenBuffers(1, &albuffer); + alBufferData(albuffer, device.format, buffer.data, buffer.size * 4, settings.frequency); + alSourceQueueBuffers(device.source, 1, &albuffer); + device.queue_length++; + } + + ALint playing; + alGetSourcei(device.source, AL_SOURCE_STATE, &playing); + if(playing != AL_PLAYING) alSourcePlay(device.source); + buffer.length = 0; + } + + bool init() { + buffer.data = new uint32_t[buffer.size]; + device.queue_length = 0; + + bool success = false; + if(device.handle = alcOpenDevice(NULL)) { + if(device.context = alcCreateContext(device.handle, NULL)) { + alcMakeContextCurrent(device.context); + alGenSources(1, &device.source); + + //disable unused 3D features + alSourcef (device.source, AL_PITCH, 1.0); + alSourcef (device.source, AL_GAIN, 1.0); + alSource3f(device.source, AL_POSITION, 0.0, 0.0, 0.0); + alSource3f(device.source, AL_VELOCITY, 0.0, 0.0, 0.0); + alSource3f(device.source, AL_DIRECTION, 0.0, 0.0, 0.0); + alSourcef (device.source, AL_ROLLOFF_FACTOR, 0.0); + alSourcei (device.source, AL_SOURCE_RELATIVE, AL_TRUE); + + alListener3f(AL_POSITION, 0.0, 0.0, 0.0); + alListener3f(AL_VELOCITY, 0.0, 0.0, 0.0); + ALfloat listener_orientation[] = { 0.0, 0.0, -1.0, 0.0, 1.0, 0.0 }; + alListenerfv(AL_ORIENTATION, listener_orientation); + + success = true; + } + } + + if(success == false) { + term(); + return false; + } + + return true; + } + + void term() { + if(alIsSource(device.source) == AL_TRUE) { + int playing = 0; + alGetSourcei(device.source, AL_SOURCE_STATE, &playing); + if(playing == AL_PLAYING) { + alSourceStop(device.source); + int queued = 0; + alGetSourcei(device.source, AL_BUFFERS_QUEUED, &queued); + while(queued--) { + ALuint albuffer = 0; + alSourceUnqueueBuffers(device.source, 1, &albuffer); + alDeleteBuffers(1, &albuffer); + device.queue_length--; + } + } + + alDeleteSources(1, &device.source); + device.source = 0; + } + + if(device.context) { + alcMakeContextCurrent(NULL); + alcDestroyContext(device.context); + device.context = 0; + } + + if(device.handle) { + alcCloseDevice(device.handle); + device.handle = 0; + } + + if(buffer.data) { + delete[] buffer.data; + buffer.data = 0; + } + } + + pAudioOpenAL(AudioOpenAL &self_) : self(self_) { + device.source = 0; + device.handle = 0; + device.context = 0; + device.format = AL_FORMAT_STEREO16; + device.latency = 40; + device.queue_length = 0; + + buffer.data = 0; + buffer.length = 0; + buffer.size = device.latency * 32; + + settings.synchronize = true; + settings.frequency = 22050; + + alutInit(0, NULL); + } + + ~pAudioOpenAL() { + term(); + alutExit(); + } +}; + +bool AudioOpenAL::cap(Setting setting) { return p.cap(setting); } +uintptr_t AudioOpenAL::get(Setting setting) { return p.get(setting); } +bool AudioOpenAL::set(Setting setting, uintptr_t param) { return p.set(setting, param); } +void AudioOpenAL::sample(uint16_t sl, uint16_t sr) { p.sample(sl, sr); } +bool AudioOpenAL::init() { return p.init(); } +void AudioOpenAL::term() { p.term(); } +AudioOpenAL::AudioOpenAL() : p(*new pAudioOpenAL(*this)) {} +AudioOpenAL::~AudioOpenAL() { delete &p; } + +} //namespace ruby diff --git a/src/lib/ruby/audio/openal.h b/src/lib/ruby/audio/openal.h new file mode 100644 index 00000000..cb8e65bf --- /dev/null +++ b/src/lib/ruby/audio/openal.h @@ -0,0 +1,24 @@ +/* + audio.openal (2007-12-26) + author: Nach + contributors: byuu, wertigon, _willow_ +*/ + +class pAudioOpenAL; + +class AudioOpenAL : public Audio { +public: + bool cap(Setting); + uintptr_t get(Setting); + bool set(Setting, uintptr_t); + + void sample(uint16_t sl, uint16_t sr); + bool init(); + void term(); + + AudioOpenAL(); + ~AudioOpenAL(); + +private: + pAudioOpenAL &p; +}; diff --git a/src/lib/ruby/audio/oss.cpp b/src/lib/ruby/audio/oss.cpp new file mode 100644 index 00000000..91a41cbe --- /dev/null +++ b/src/lib/ruby/audio/oss.cpp @@ -0,0 +1,118 @@ +#include +#include +#include +#include + +//OSS4 soundcard.h includes below SNDCTL defines, but OSS3 does not +//However, OSS4 soundcard.h does not reside in +//Therefore, attempt to manually define SNDCTL values if using OSS3 header +//Note that if the defines below fail to work on any specific platform, one can point soundcard.h +//above to the correct location for OSS4 (usually /usr/lib/oss/include/sys/soundcard.h) +//Failing that, one can disable OSS4 ioctl calls inside init() and remove the below defines + +#ifndef SNDCTL_DSP_COOKEDMODE + #define SNDCTL_DSP_COOKEDMODE _IOW('P', 30, int) +#endif + +#ifndef SNDCTL_DSP_POLICY + #define SNDCTL_DSP_POLICY _IOW('P', 45, int) +#endif + +#include + +namespace ruby { + +#include "oss.h" + +class pAudioOSS { +public: + AudioOSS &self; + + struct { + int fd; + int format; + int channels; + const char *name; + } device; + + struct { + unsigned frequency; + } settings; + + bool cap(Audio::Setting setting) { + if(setting == Audio::Frequency) return true; + return false; + } + + uintptr_t get(Audio::Setting setting) { + if(setting == Audio::Frequency) return settings.frequency; + return false; + } + + bool set(Audio::Setting setting, uintptr_t param) { + if(setting == Audio::Frequency) { + settings.frequency = param; + if(device.fd > 0) { + term(); + init(); + } + return true; + } + return false; + } + + void sample(uint16_t sl, uint16_t sr) { + uint32_t sample = sl + (sr << 16); + write(device.fd, &sample, 4); + } + + bool init() { + device.fd = open(device.name, O_WRONLY, O_NONBLOCK); + if(device.fd < 0) return false; + + #if 1 //SOUND_VERSION >= 0x040000 + //attempt to enable OSS4-specific features regardless of version + //OSS3 ioctl calls will silently fail, but sound will still work + int cooked = 1, policy = 4; //policy should be 0 - 10, lower = less latency, more CPU usage + ioctl(device.fd, SNDCTL_DSP_COOKEDMODE, &cooked); + ioctl(device.fd, SNDCTL_DSP_POLICY, &policy); + #endif + int freq = settings.frequency; + ioctl(device.fd, SNDCTL_DSP_CHANNELS, &device.channels); + ioctl(device.fd, SNDCTL_DSP_SETFMT, &device.format); + ioctl(device.fd, SNDCTL_DSP_SPEED, &freq); + + return true; + } + + void term() { + if(device.fd > 0) { + close(device.fd); + device.fd = -1; + } + } + + pAudioOSS(AudioOSS &self_) : self(self_) { + device.fd = -1; + device.format = AFMT_S16_LE; + device.channels = 2; + device.name = "/dev/dsp"; + + settings.frequency = 22050; + } + + ~pAudioOSS() { + term(); + } +}; + +bool AudioOSS::cap(Setting setting) { return p.cap(setting); } +uintptr_t AudioOSS::get(Setting setting) { return p.get(setting); } +bool AudioOSS::set(Setting setting, uintptr_t param) { return p.set(setting, param); } +void AudioOSS::sample(uint16_t sl, uint16_t sr) { p.sample(sl, sr); } +bool AudioOSS::init() { return p.init(); } +void AudioOSS::term() { p.term(); } +AudioOSS::AudioOSS() : p(*new pAudioOSS(*this)) {} +AudioOSS::~AudioOSS() { delete &p; } + +} //namespace ruby diff --git a/src/lib/ruby/audio/oss.h b/src/lib/ruby/audio/oss.h new file mode 100644 index 00000000..1d2777e8 --- /dev/null +++ b/src/lib/ruby/audio/oss.h @@ -0,0 +1,23 @@ +/* + audio.oss (2007-12-26) + author: Nach +*/ + +class pAudioOSS; + +class AudioOSS : public Audio { +public: + bool cap(Setting); + uintptr_t get(Setting); + bool set(Setting, uintptr_t); + + void sample(uint16_t sl, uint16_t sr); + bool init(); + void term(); + + AudioOSS(); + ~AudioOSS(); + +private: + pAudioOSS &p; +}; diff --git a/src/lib/ruby/input.h b/src/lib/ruby/input.h new file mode 100644 index 00000000..b712cc6b --- /dev/null +++ b/src/lib/ruby/input.h @@ -0,0 +1,21 @@ +class Input { +public: + enum Setting { + Handle, + }; + + virtual bool cap(Setting) { return false; } + virtual uintptr_t get(Setting) { return false; } + virtual bool set(Setting, uintptr_t) { return false; } + + virtual bool key_down(uint16_t key) { return false; } + virtual bool key_up (uint16_t key) { return !key_down(key); } + + virtual void clear() {} + virtual void poll() {} + virtual bool init() { return true; } + virtual void term() {} + + Input() {} + virtual ~Input() {} +}; diff --git a/src/lib/ruby/input/directinput.cpp b/src/lib/ruby/input/directinput.cpp new file mode 100644 index 00000000..285f4e57 --- /dev/null +++ b/src/lib/ruby/input/directinput.cpp @@ -0,0 +1,321 @@ +#include +#define WIN32_LEAN_AND_MEAN +#include + +#define DIRECTINPUT_VERSION 0x0800 +#define DIRECTINPUT_JOYMAX 16 +#include + +#include + +namespace ruby { + +#include "directinput.h" + +BOOL CALLBACK DI_EnumJoypadsCallback(const DIDEVICEINSTANCE*, void*); + +using namespace nall; + +class pInputDI { +public: + InputDI &self; + uint8_t keystate[256 + DIRECTINPUT_JOYMAX * 256]; + LPDIRECTINPUT8 di; + LPDIRECTINPUTDEVICE8 di_key, di_joy[DIRECTINPUT_JOYMAX]; + unsigned di_joy_count; + + struct { + HWND handle; + } settings; + + bool cap(Input::Setting setting) { + if(setting == Input::Handle) return true; + return false; + } + + uintptr_t get(Input::Setting setting) { + if(setting == Input::Handle) return (uintptr_t)settings.handle; + return false; + } + + bool set(Input::Setting setting, uintptr_t param) { + if(setting == Input::Handle) { + settings.handle = (HWND)param; + return true; + } + return false; + } + + void clear() { + memset(keystate, 0, sizeof keystate); + } + + void poll() { + clear(); + + DIJOYSTATE2 js; + if(di_key) { + if(FAILED(di_key->GetDeviceState(256, keystate))) { + di_key->Acquire(); + if(FAILED(di_key->GetDeviceState(256, keystate))) { + memset(keystate, 0, 256); + } + } + } + + for(int i = 0; i < di_joy_count; i++) { + if(!di_joy[i]) continue; + + memset(js.rgbButtons, 0, 128); + + if(FAILED(di_joy[i]->Poll())) { + di_joy[i]->Acquire(); + if(FAILED(di_joy[i]->Poll())) { + continue; + } + } + di_joy[i]->GetDeviceState(sizeof(DIJOYSTATE2), &js); + + uint16_t index = 256 + (i << 8); //joypad index + memcpy(keystate + index, js.rgbButtons, 128); + + //map d-pad axes + int resistance = 75; //config::input.axis_resistance; + resistance = max(1, min(99, resistance)); + resistance = int32_t(double(resistance) * 32768.0 / 100.0); + int resistance_lo = 0x7fff - resistance; + int resistance_hi = 0x8000 + resistance; + keystate[index + 0x80] = (js.lY <= resistance_lo) ? 0x80 : 0x00; + keystate[index + 0x81] = (js.lY >= resistance_hi) ? 0x80 : 0x00; + keystate[index + 0x82] = (js.lX <= resistance_lo) ? 0x80 : 0x00; + keystate[index + 0x83] = (js.lX >= resistance_hi) ? 0x80 : 0x00; + + //map analog POV hat (directional pad) as well + unsigned pov = js.rgdwPOV[0]; + keystate[index + 0x80] |= (pov == 0 || pov == 31500 || pov == 4500) ? 0x80 : 0x00; + keystate[index + 0x81] |= (pov == 18000 || pov == 13500 || pov == 22500) ? 0x80 : 0x00; + keystate[index + 0x82] |= (pov == 27000 || pov == 22500 || pov == 31500) ? 0x80 : 0x00; + keystate[index + 0x83] |= (pov == 9000 || pov == 4500 || pov == 13500) ? 0x80 : 0x00; + } + } + + bool enum_joypads(const DIDEVICEINSTANCE *instance) { + if(FAILED(di->CreateDevice(instance->guidInstance, &di_joy[di_joy_count], 0))) { + return DIENUM_CONTINUE; //continue and try next joypad + } + + di_joy[di_joy_count]->SetDataFormat(&c_dfDIJoystick2); + di_joy[di_joy_count]->SetCooperativeLevel(settings.handle, DISCL_NONEXCLUSIVE | DISCL_BACKGROUND); + + if(++di_joy_count >= DIRECTINPUT_JOYMAX) return DIENUM_STOP; + return DIENUM_CONTINUE; + } + + bool init() { + di_key = 0; + for(int i = 0; i < DIRECTINPUT_JOYMAX; i++) di_joy[i] = 0; + di = 0; + di_joy_count = 0; + + DirectInput8Create(GetModuleHandle(0), DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&di, 0); + di->CreateDevice(GUID_SysKeyboard, &di_key, 0); + + di_key->SetDataFormat(&c_dfDIKeyboard); + di_key->SetCooperativeLevel(settings.handle, DISCL_NONEXCLUSIVE | DISCL_BACKGROUND); + di_key->Acquire(); + + di->EnumDevices(DI8DEVCLASS_GAMECTRL, DI_EnumJoypadsCallback, (void*)this, DIEDFL_ATTACHEDONLY); + + return true; + } + + void term() { + if(di_key) { + di_key->Unacquire(); + di_key->Release(); + di_key = 0; + } + + for(int i = 0; i < DIRECTINPUT_JOYMAX; i++) { + if(di_joy[i]) { + di_joy[i]->Unacquire(); + di_joy[i]->Release(); + di_joy[i] = 0; + } + } + + if(di) { + di->Release(); + di = 0; + } + + di_joy_count = 0; + } + + bool key_down(uint16_t key) { + assert(key < sizeof keystate); + return key ? keystate[translate(key)] & 0x80 : false; + } + + //translate keymap code to DirectInput code, to lookup key status in DI status table + uint16_t translate(uint16_t key) { + switch(key) { + case keyboard::escape: return 0x01; + + case keyboard::f1: return 0x3b; + case keyboard::f2: return 0x3c; + case keyboard::f3: return 0x3d; + case keyboard::f4: return 0x3e; + case keyboard::f5: return 0x3f; + case keyboard::f6: return 0x40; + case keyboard::f7: return 0x41; + case keyboard::f8: return 0x42; + case keyboard::f9: return 0x43; + case keyboard::f10: return 0x44; + case keyboard::f11: return 0x57; + case keyboard::f12: return 0x58; + + case keyboard::print_screen: return 0xb7; + case keyboard::scroll_lock: return 0x46; + case keyboard::pause: return 0xc5; + + case keyboard::tilde: return 0x29; + + case keyboard::num_1: return 0x02; + case keyboard::num_2: return 0x03; + case keyboard::num_3: return 0x04; + case keyboard::num_4: return 0x05; + case keyboard::num_5: return 0x06; + case keyboard::num_6: return 0x07; + case keyboard::num_7: return 0x08; + case keyboard::num_8: return 0x09; + case keyboard::num_9: return 0x0a; + case keyboard::num_0: return 0x0b; + + case keyboard::dash: return 0x0c; + case keyboard::equal: return 0x0d; + case keyboard::backspace: return 0x0e; + + case keyboard::insert: return 0xd2; + case keyboard::delete_: return 0xd3; + case keyboard::home: return 0xc7; + case keyboard::end: return 0xcf; + case keyboard::page_up: return 0xc9; + case keyboard::page_down: return 0xd1; + + case keyboard::a: return 0x1e; + case keyboard::b: return 0x30; + case keyboard::c: return 0x2e; + case keyboard::d: return 0x20; + case keyboard::e: return 0x12; + case keyboard::f: return 0x21; + case keyboard::g: return 0x22; + case keyboard::h: return 0x23; + case keyboard::i: return 0x17; + case keyboard::j: return 0x24; + case keyboard::k: return 0x25; + case keyboard::l: return 0x26; + case keyboard::m: return 0x32; + case keyboard::n: return 0x31; + case keyboard::o: return 0x18; + case keyboard::p: return 0x19; + case keyboard::q: return 0x10; + case keyboard::r: return 0x13; + case keyboard::s: return 0x1f; + case keyboard::t: return 0x14; + case keyboard::u: return 0x16; + case keyboard::v: return 0x2f; + case keyboard::w: return 0x11; + case keyboard::x: return 0x2d; + case keyboard::y: return 0x15; + case keyboard::z: return 0x2c; + + case keyboard::lbracket: return 0x1a; + case keyboard::rbracket: return 0x1b; + case keyboard::backslash: return 0x2b; + case keyboard::semicolon: return 0x27; + case keyboard::apostrophe: return 0x28; + case keyboard::comma: return 0x33; + case keyboard::period: return 0x34; + case keyboard::slash: return 0x35; + + case keyboard::pad_1: return 0x4f; + case keyboard::pad_2: return 0x50; + case keyboard::pad_3: return 0x51; + case keyboard::pad_4: return 0x4b; + case keyboard::pad_5: return 0x4c; + case keyboard::pad_6: return 0x4d; + case keyboard::pad_7: return 0x47; + case keyboard::pad_8: return 0x48; + case keyboard::pad_9: return 0x49; + case keyboard::pad_0: return 0x52; + case keyboard::point: return 0x53; + + case keyboard::add: return 0x4e; + case keyboard::subtract: return 0x4a; + case keyboard::multiply: return 0x37; + case keyboard::divide: return 0xb5; + case keyboard::enter: return 0x9c; + + case keyboard::num_lock : return 0x45; + case keyboard::caps_lock: return 0x3a; + + case keyboard::up: return 0xc8; + case keyboard::down: return 0xd0; + case keyboard::left: return 0xcb; + case keyboard::right: return 0xcd; + + case keyboard::tab: return 0x0f; + case keyboard::return_: return 0x1c; + case keyboard::spacebar: return 0x39; + + case keyboard::lctrl : return 0x1d; + case keyboard::rctrl : return 0x9d; + case keyboard::lalt : return 0x38; + case keyboard::ralt : return 0xb8; + case keyboard::lshift: return 0x2a; + case keyboard::rshift: return 0x36; + case keyboard::lsuper: return 0xdb; + case keyboard::rsuper: return 0xdc; + case keyboard::menu: return 0xdd; + } + + for(uint16_t j = 0; j < 16; j++) { + uint16_t index = 256 + (j << 8); + if(key == joypad<>::index(j, joypad<>::up)) return index + 0x80; + if(key == joypad<>::index(j, joypad<>::down)) return index + 0x81; + if(key == joypad<>::index(j, joypad<>::left)) return index + 0x82; + if(key == joypad<>::index(j, joypad<>::right)) return index + 0x83; + for(uint16_t b = 0; b < 16; b++) { + if(key == joypad<>::index(j, joypad<>::button_00 + b)) return index + b; + } + } + + return 0x00; + } + + pInputDI(InputDI &self_) : self(self_) { + di = 0; + di_key = 0; + for(int i = 0; i < DIRECTINPUT_JOYMAX; i++) di_joy[i] = 0; + } + + ~pInputDI() { term(); } +}; + +BOOL CALLBACK DI_EnumJoypadsCallback(const DIDEVICEINSTANCE *instance, void *p) { + return ((pInputDI*)p)->enum_joypads(instance); +} + +bool InputDI::cap(Setting setting) { return p.cap(setting); } +uintptr_t InputDI::get(Setting setting) { return p.get(setting); } +bool InputDI::set(Setting setting, uintptr_t param) { return p.set(setting, param); } +bool InputDI::key_down(uint16_t key) { return p.key_down(key); } +void InputDI::clear() { p.clear(); } +void InputDI::poll() { p.poll(); } +bool InputDI::init() { return p.init(); } +void InputDI::term() { p.term(); } +InputDI::InputDI() : p(*new pInputDI(*this)) {} +InputDI::~InputDI() { delete &p; } + +} //namespace ruby diff --git a/src/ui/vai/input/input.directinput.h b/src/lib/ruby/input/directinput.h similarity index 51% rename from src/ui/vai/input/input.directinput.h rename to src/lib/ruby/input/directinput.h index e7efd819..f568fa43 100644 --- a/src/ui/vai/input/input.directinput.h +++ b/src/lib/ruby/input/directinput.h @@ -1,8 +1,3 @@ -#ifndef INPUT_DIRECTINPUT_H -#define INPUT_DIRECTINPUT_H - -#include "../input.h" - class pInputDI; class InputDI : public Input { @@ -11,11 +6,11 @@ public: uintptr_t get(Setting); bool set(Setting, uintptr_t); - bool key_down(uint16 key); + bool key_down(uint16_t key); - void clear_input(); + void clear(); void poll(); - void init(); + bool init(); void term(); InputDI(); @@ -24,5 +19,3 @@ public: private: pInputDI &p; }; - -#endif //ifndef INPUT_DIRECTINPUT_H diff --git a/src/lib/ruby/input/sdl.cpp b/src/lib/ruby/input/sdl.cpp new file mode 100644 index 00000000..de22c515 --- /dev/null +++ b/src/lib/ruby/input/sdl.cpp @@ -0,0 +1,286 @@ +/***** + * SDL input driver + * + * Design notes: + * SDL contains the ability to poll both the keyboard and joypads, + * however it cannot capture keyboard input from windows that it + * did not create. Joypad input is captured globally, regardless + * of what created the active window. + * Letting SDL create the window to capture keyboard input is not + * practical. Users of an input library should ideally be able to + * create a window however they like -- with GTK+, Qt, etc. + * Therefore, this driver basically uses SDL for joypad support + * only, and uses the native platform's keyboard input handling + * routines. Clearly, this is not as portable, but there is little + * choice in the matter. + * In the worst case scenario, an unsupported platform, this + * driver will still work, but will not support keyboard input. + *****/ + +#include + +#if !defined(_WIN32) +#include +#include +#include +#include +#include +#include +#include +#include +#endif + +#include + +namespace ruby { + +#include "sdl.h" +using namespace nall; + +class pInputSDL { +public: + InputSDL &self; + SDL_Joystick *joy[16]; + SDL_Event event; + enum { + joy_button_00, joy_button_01, joy_button_02, joy_button_03, + joy_button_04, joy_button_05, joy_button_06, joy_button_07, + joy_button_08, joy_button_09, joy_button_10, joy_button_11, + joy_button_12, joy_button_13, joy_button_14, joy_button_15, + joy_up, joy_down, joy_left, joy_right, + joy_limit, + }; + bool joystate[16][joy_limit]; + + #if !defined(_WIN32) + char keystate[32]; + Display *display; + #endif + + bool key_down(uint16_t key) { + #if !defined(_WIN32) + #define map(i) (keystate[i >> 3] & (1 << (i & 7))) + + switch(key) { + case keyboard::escape: return map(0x09); + + case keyboard::f1: return map(0x43); + case keyboard::f2: return map(0x44); + case keyboard::f3: return map(0x45); + case keyboard::f4: return map(0x46); + case keyboard::f5: return map(0x47); + case keyboard::f6: return map(0x48); + case keyboard::f7: return map(0x49); + case keyboard::f8: return map(0x4a); + case keyboard::f9: return map(0x4b); + case keyboard::f10: return map(0x4c); + case keyboard::f11: return map(0x5f); + case keyboard::f12: return map(0x60); + + case keyboard::print_screen: return map(0x6f); + case keyboard::scroll_lock: return map(0x4e); + case keyboard::pause: return map(0x6e); + + case keyboard::tilde: return map(0x31); + + case keyboard::num_1: return map(0x0a); + case keyboard::num_2: return map(0x0b); + case keyboard::num_3: return map(0x0c); + case keyboard::num_4: return map(0x0d); + case keyboard::num_5: return map(0x0e); + case keyboard::num_6: return map(0x0f); + case keyboard::num_7: return map(0x10); + case keyboard::num_8: return map(0x11); + case keyboard::num_9: return map(0x12); + case keyboard::num_0: return map(0x13); + + case keyboard::dash: return map(0x14); + case keyboard::equal: return map(0x15); + case keyboard::backspace: return map(0x16); + + case keyboard::insert: return map(0x6a); + case keyboard::delete_: return map(0x6b); + case keyboard::home: return map(0x61); + case keyboard::end: return map(0x67); + case keyboard::page_up: return map(0x63); + case keyboard::page_down: return map(0x69); + + case keyboard::a: return map(0x26); + case keyboard::b: return map(0x38); + case keyboard::c: return map(0x36); + case keyboard::d: return map(0x28); + case keyboard::e: return map(0x1a); + case keyboard::f: return map(0x29); + case keyboard::g: return map(0x2a); + case keyboard::h: return map(0x2b); + case keyboard::i: return map(0x1f); + case keyboard::j: return map(0x2c); + case keyboard::k: return map(0x2d); + case keyboard::l: return map(0x2e); + case keyboard::m: return map(0x3a); + case keyboard::n: return map(0x39); + case keyboard::o: return map(0x20); + case keyboard::p: return map(0x21); + case keyboard::q: return map(0x18); + case keyboard::r: return map(0x1b); + case keyboard::s: return map(0x27); + case keyboard::t: return map(0x1c); + case keyboard::u: return map(0x1e); + case keyboard::v: return map(0x37); + case keyboard::w: return map(0x19); + case keyboard::x: return map(0x35); + case keyboard::y: return map(0x1d); + case keyboard::z: return map(0x34); + + case keyboard::lbracket: return map(0x22); + case keyboard::rbracket: return map(0x23); + case keyboard::backslash: return map(0x33); + case keyboard::semicolon: return map(0x2f); + case keyboard::apostrophe: return map(0x30); + case keyboard::comma: return map(0x3b); + case keyboard::period: return map(0x3c); + case keyboard::slash: return map(0x3d); + + case keyboard::pad_1: return map(0x57); + case keyboard::pad_2: return map(0x58); + case keyboard::pad_3: return map(0x59); + case keyboard::pad_4: return map(0x53); + case keyboard::pad_5: return map(0x54); + case keyboard::pad_6: return map(0x55); + case keyboard::pad_7: return map(0x4f); + case keyboard::pad_8: return map(0x50); + case keyboard::pad_9: return map(0x51); + + case keyboard::add: return map(0x56); + case keyboard::subtract: return map(0x52); + case keyboard::multiply: return map(0x3f); + case keyboard::divide: return map(0x70); + case keyboard::enter: return map(0x6c); + + case keyboard::num_lock: return map(0x4d); + case keyboard::caps_lock: return map(0x42); + + case keyboard::up: return map(0x62); + case keyboard::down: return map(0x68); + case keyboard::left: return map(0x64); + case keyboard::right: return map(0x66); + + case keyboard::tab: return map(0x17); + case keyboard::return_: return map(0x24); + case keyboard::spacebar: return map(0x41); + + case keyboard::lctrl: return map(0x25); + case keyboard::rctrl: return map(0x6d); + case keyboard::lalt: return map(0x40); + case keyboard::ralt: return map(0x71); + case keyboard::lshift: return map(0x32); + case keyboard::rshift: return map(0x3e); + case keyboard::lsuper: return map(0x73); + case keyboard::rsuper: return map(0x74); + case keyboard::menu: return map(0x75); + } + + #undef map + #endif + + for(int i = 0; i < 16; i++) { + if(key == joypad<>::index(i, joypad<>::up)) return joystate[i][joy_up]; + if(key == joypad<>::index(i, joypad<>::down)) return joystate[i][joy_down]; + if(key == joypad<>::index(i, joypad<>::left)) return joystate[i][joy_left]; + if(key == joypad<>::index(i, joypad<>::right)) return joystate[i][joy_right]; + for(int b = 0; b < 16; b++) { + if(key == joypad<>::index(i, joypad<>::button_00 + b)) return joystate[i][joy_button_00 + b]; + } + } + + return false; + } + + void clear() { + #if !defined(_WIN32) + memset(keystate, 0, sizeof keystate); + #endif + + for(int i = 0; i < 16; i++) { + for(int b = 0; b < joy_limit; b++) { + joystate[i][b] = false; + } + } + } + + void poll() { + SDL_JoystickUpdate(); + + #if !defined(_WIN32) + XQueryKeymap(display, keystate); + #endif + + for(int i = 0; i < 16; i++) { + if(!joy[i]) continue; + + joystate[i][joy_up] = false; + joystate[i][joy_down] = false; + joystate[i][joy_left] = false; + joystate[i][joy_right] = false; + + //only poll X,Y axes for D-pad, left analog and right analog. + //note 1: right analog is swapped on some controllers, this cannot be helped. + //note 2: some controllers report more axes than physically exist. + //these tend to return fixed values (eg 32767), which makes state changes + //impossible to detect. hence why polling *all* axes is unsafe. + int axes = SDL_JoystickNumAxes(joy[i]); + for(int a = 0; a < min(axes, 6); a++) { + int value = SDL_JoystickGetAxis(joy[i], a); + if((a & 1) == 0) { //X axis + joystate[i][joy_left] |= value < -16384; + joystate[i][joy_right] |= value > +16384; + } else { //Y axis + joystate[i][joy_up] |= value < -16384; + joystate[i][joy_down] |= value > +16384; + } + } + + for(int b = 0; b < 16; b++) { + joystate[i][b] = SDL_JoystickGetButton(joy[i], b); + } + } + } + + bool init() { + SDL_InitSubSystem(SDL_INIT_JOYSTICK); + SDL_JoystickEventState(SDL_IGNORE); + + for(int i = 0; i < SDL_NumJoysticks(); i++) { + joy[i] = SDL_JoystickOpen(i); + } + + #if !defined(_WIN32) + display = XOpenDisplay(0); + #endif + + return true; + } + + void term() { + for(int i = 0; i < 16; i++) { + if(joy[i]) SDL_JoystickClose(joy[i]); + } + SDL_QuitSubSystem(SDL_INIT_JOYSTICK); + } + + pInputSDL(InputSDL &self_) : self(self_) { + for(int i = 0; i < 16; i++) joy[i] = 0; + clear(); + } +}; + + +bool InputSDL::key_down(uint16_t key) { return p.key_down(key); } +void InputSDL::clear() { p.clear(); } +void InputSDL::poll() { p.poll(); } +bool InputSDL::init() { return p.init(); } +void InputSDL::term() { p.term(); } +InputSDL::InputSDL() : p(*new pInputSDL(*this)) {} +InputSDL::~InputSDL() { delete &p; } + +} //namespace ruby diff --git a/src/lib/ruby/input/sdl.h b/src/lib/ruby/input/sdl.h new file mode 100644 index 00000000..7a35ec3e --- /dev/null +++ b/src/lib/ruby/input/sdl.h @@ -0,0 +1,17 @@ +class pInputSDL; + +class InputSDL : public Input { +public: + bool key_down(uint16_t key); + + void clear(); + void poll(); + bool init(); + void term(); + + InputSDL(); + ~InputSDL(); + +private: + pInputSDL &p; +}; diff --git a/src/lib/ruby/input/x.cpp b/src/lib/ruby/input/x.cpp new file mode 100644 index 00000000..e45f15ee --- /dev/null +++ b/src/lib/ruby/input/x.cpp @@ -0,0 +1,175 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace ruby { + +#include "x.h" + +class pInputX { +public: + InputX &self; + Display *display; + char keymap[32]; + + bool key_down(uint16_t key) { + using namespace nall; + #define map(i) (keymap[i >> 3] & (1 << (i & 7))) + switch(key) { + case keyboard::escape: return map(0x09); + + case keyboard::f1: return map(0x43); + case keyboard::f2: return map(0x44); + case keyboard::f3: return map(0x45); + case keyboard::f4: return map(0x46); + case keyboard::f5: return map(0x47); + case keyboard::f6: return map(0x48); + case keyboard::f7: return map(0x49); + case keyboard::f8: return map(0x4a); + case keyboard::f9: return map(0x4b); + case keyboard::f10: return map(0x4c); + case keyboard::f11: return map(0x5f); + case keyboard::f12: return map(0x60); + + case keyboard::print_screen: return map(0x6f); + case keyboard::scroll_lock: return map(0x4e); + case keyboard::pause: return map(0x6e); + + case keyboard::tilde: return map(0x31); + + case keyboard::num_1: return map(0x0a); + case keyboard::num_2: return map(0x0b); + case keyboard::num_3: return map(0x0c); + case keyboard::num_4: return map(0x0d); + case keyboard::num_5: return map(0x0e); + case keyboard::num_6: return map(0x0f); + case keyboard::num_7: return map(0x10); + case keyboard::num_8: return map(0x11); + case keyboard::num_9: return map(0x12); + case keyboard::num_0: return map(0x13); + + case keyboard::dash: return map(0x14); + case keyboard::equal: return map(0x15); + case keyboard::backspace: return map(0x16); + + case keyboard::insert: return map(0x6a); + case keyboard::delete_: return map(0x6b); + case keyboard::home: return map(0x61); + case keyboard::end: return map(0x67); + case keyboard::page_up: return map(0x63); + case keyboard::page_down: return map(0x69); + + case keyboard::a: return map(0x26); + case keyboard::b: return map(0x38); + case keyboard::c: return map(0x36); + case keyboard::d: return map(0x28); + case keyboard::e: return map(0x1a); + case keyboard::f: return map(0x29); + case keyboard::g: return map(0x2a); + case keyboard::h: return map(0x2b); + case keyboard::i: return map(0x1f); + case keyboard::j: return map(0x2c); + case keyboard::k: return map(0x2d); + case keyboard::l: return map(0x2e); + case keyboard::m: return map(0x3a); + case keyboard::n: return map(0x39); + case keyboard::o: return map(0x20); + case keyboard::p: return map(0x21); + case keyboard::q: return map(0x18); + case keyboard::r: return map(0x1b); + case keyboard::s: return map(0x27); + case keyboard::t: return map(0x1c); + case keyboard::u: return map(0x1e); + case keyboard::v: return map(0x37); + case keyboard::w: return map(0x19); + case keyboard::x: return map(0x35); + case keyboard::y: return map(0x1d); + case keyboard::z: return map(0x34); + + case keyboard::lbracket: return map(0x22); + case keyboard::rbracket: return map(0x23); + case keyboard::backslash: return map(0x33); + case keyboard::semicolon: return map(0x2f); + case keyboard::apostrophe: return map(0x30); + case keyboard::comma: return map(0x3b); + case keyboard::period: return map(0x3c); + case keyboard::slash: return map(0x3d); + + case keyboard::pad_1: return map(0x57); + case keyboard::pad_2: return map(0x58); + case keyboard::pad_3: return map(0x59); + case keyboard::pad_4: return map(0x53); + case keyboard::pad_5: return map(0x54); + case keyboard::pad_6: return map(0x55); + case keyboard::pad_7: return map(0x4f); + case keyboard::pad_8: return map(0x50); + case keyboard::pad_9: return map(0x51); + + case keyboard::add: return map(0x56); + case keyboard::subtract: return map(0x52); + case keyboard::multiply: return map(0x3f); + case keyboard::divide: return map(0x70); + case keyboard::enter: return map(0x6c); + + case keyboard::num_lock: return map(0x4d); + case keyboard::caps_lock: return map(0x42); + + case keyboard::up: return map(0x62); + case keyboard::down: return map(0x68); + case keyboard::left: return map(0x64); + case keyboard::right: return map(0x66); + + case keyboard::tab: return map(0x17); + case keyboard::return_: return map(0x24); + case keyboard::spacebar: return map(0x41); + + case keyboard::lctrl: return map(0x25); + case keyboard::rctrl: return map(0x6d); + case keyboard::lalt: return map(0x40); + case keyboard::ralt: return map(0x71); + case keyboard::lshift: return map(0x32); + case keyboard::rshift: return map(0x3e); + case keyboard::lsuper: return map(0x73); + case keyboard::rsuper: return map(0x74); + case keyboard::menu: return map(0x75); + } + + #undef map + return false; + } + + void clear() { + memset(keymap, 0, sizeof keymap); + } + + void poll() { + XQueryKeymap(display, keymap); + } + + bool init() { + display = XOpenDisplay(0); + return true; + } + + void term() { + } + + pInputX(InputX &self_) : self(self_) {} +}; + +bool InputX::key_down(uint16_t key) { return p.key_down(key); } +void InputX::clear() { p.clear(); } +void InputX::poll() { p.poll(); } +bool InputX::init() { return p.init(); } +void InputX::term() { p.term(); } +InputX::InputX() : p(*new pInputX(*this)) {} +InputX::~InputX() { delete &p; } + +} //namespace ruby diff --git a/src/lib/ruby/input/x.h b/src/lib/ruby/input/x.h new file mode 100644 index 00000000..b05e6080 --- /dev/null +++ b/src/lib/ruby/input/x.h @@ -0,0 +1,17 @@ +class pInputX; + +class InputX : public Input { +public: + bool key_down(uint16_t key); + + void clear(); + void poll(); + bool init(); + void term(); + + InputX(); + ~InputX(); + +private: + pInputX &p; +}; diff --git a/src/lib/ruby/ruby.cpp b/src/lib/ruby/ruby.cpp new file mode 100644 index 00000000..ac0366e6 --- /dev/null +++ b/src/lib/ruby/ruby.cpp @@ -0,0 +1,195 @@ +#include + +namespace ruby { + +#include + +VideoInterface video; +AudioInterface audio; +InputInterface input; + +/* VideoInterface */ + +void VideoInterface::driver(const char *driver) { + if(p) term(); + + if(!strcmp(driver, "none")) p = new Video(); + + #ifdef VIDEO_DIRECT3D + else if(!strcmp(driver, "direct3d")) p = new VideoD3D(); + #endif + + #ifdef VIDEO_DIRECTDRAW + else if(!strcmp(driver, "directdraw")) p = new VideoDD(); + #endif + + #ifdef VIDEO_GDI + else if(!strcmp(driver, "gdi")) p = new VideoGDI(); + #endif + + #ifdef VIDEO_GLX + else if(!strcmp(driver, "opengl")) p = new VideoGLX(); + #endif + + #ifdef VIDEO_SDL + else if(!strcmp(driver, "sdl")) p = new VideoSDL(); + #endif + + #ifdef VIDEO_XV + else if(!strcmp(driver, "xv")) p = new VideoXv(); + #endif + + else //select the *safest* available driver, not the fastest + + #if defined(VIDEO_DIRECT3D) + p = new VideoD3D(); + #elif defined(VIDEO_DIRECTDRAW) + p = new VideoDD(); + #elif defined(VIDEO_GDI) + p = new VideoGDI(); + #elif defined(VIDEO_SDL) + p = new VideoSDL(); + #elif defined(VIDEO_XV) + p = new VideoXv(); + #elif defined(VIDEO_GLX) + p = new VideoGLX(); + #else + p = new Video(); + #endif +} + +bool VideoInterface::init() { + if(!p) driver(); + return p->init(); +} + +void VideoInterface::term() { + if(p) { + delete p; + p = 0; + } +} + +bool VideoInterface::cap(Video::Setting setting) { return p ? p->cap(setting) : false; } +uintptr_t VideoInterface::get(Video::Setting setting) { return p ? p->get(setting) : false; } +bool VideoInterface::set(Video::Setting setting, uintptr_t param) { return p ? p->set(setting, param) : false; } +bool VideoInterface::lock(uint16_t *&data, unsigned &pitch) { return p ? p->lock(data, pitch) : false; } +void VideoInterface::unlock() { if(p) p->unlock(); } +void VideoInterface::clear() { if(p) p->clear(); } +void VideoInterface::refresh(unsigned width, unsigned height) { if(p) p->refresh(width, height); } +VideoInterface::VideoInterface() : p(0) {} +VideoInterface::~VideoInterface() { term(); } + +/* AudioInterface */ + +void AudioInterface::driver(const char *driver) { + if(p) term(); + + if(!strcmp(driver, "none")) p = new Audio(); + + #ifdef AUDIO_AO + else if(!strcmp(driver, "ao")) p = new AudioAO(); + #endif + + #ifdef AUDIO_DIRECTSOUND + else if(!strcmp(driver, "directsound")) p = new AudioDS(); + #endif + + #ifdef AUDIO_OPENAL + else if(!strcmp(driver, "openal")) p = new AudioOpenAL(); + #endif + + #ifdef AUDIO_OSS + else if(!strcmp(driver, "oss")) p = new AudioOSS(); + #endif + + else //select the *safest* available driver, not the fastest + + #if defined(AUDIO_DIRECTSOUND) + p = new AudioDS(); + #elif defined(AUDIO_AO) + p = new AudioAO(); + #elif defined(AUDIO_OPENAL) + p = new AudioOpenAL(); + #elif defined(AUDIO_OSS) + p = new AudioOSS(); + #else + p = new Audio(); + #endif +} + +bool AudioInterface::init() { + if(!p) driver(); + return p->init(); +} + +void AudioInterface::term() { + if(p) { + delete p; + p = 0; + } +} + +bool AudioInterface::cap(Audio::Setting setting) { return p ? p->cap(setting) : false; } +uintptr_t AudioInterface::get(Audio::Setting setting) { return p ? p->get(setting) : false; } +bool AudioInterface::set(Audio::Setting setting, uintptr_t param) { return p ? p->set(setting, param) : false; } +void AudioInterface::sample(uint16_t left, uint16_t right) { if(p) p->sample(left, right); } +void AudioInterface::clear() { if(p) p->clear(); } +AudioInterface::AudioInterface() : p(0) {} +AudioInterface::~AudioInterface() { term(); } + +/* InputInterface */ + +void InputInterface::driver(const char *driver) { + if(p) term(); + + if(!strcmp(driver, "none")) p = new Input(); + + #ifdef INPUT_DIRECTINPUT + else if(!strcmp(driver, "directinput")) p = new InputDI(); + #endif + + #ifdef INPUT_SDL + else if(!strcmp(driver, "sdl")) p = new InputSDL(); + #endif + + #ifdef INPUT_X + else if(!strcmp(driver, "x")) p = new InputX(); + #endif + + else //select the *safest* available driver, not the fastest + + #if defined(INPUT_DIRECTINPUT) + p = new InputDI(); + #elif defined(INPUT_SDL) + p = new InputSDL(); + #elif defined(INPUT_X) + p = new InputX(); + #else + p = new Input(); + #endif +} + +bool InputInterface::init() { + if(!p) driver(); + return p->init(); +} + +void InputInterface::term() { + if(p) { + delete p; + p = 0; + } +} + +bool InputInterface::cap(Input::Setting setting) { return p ? p->cap(setting) : false; } +uintptr_t InputInterface::get(Input::Setting setting) { return p ? p->get(setting) : false; } +bool InputInterface::set(Input::Setting setting, uintptr_t param) { return p ? p->set(setting, param) : false; } +bool InputInterface::key_down(uint16_t key) { return p ? p->key_down(key) : false; } +bool InputInterface::key_up(uint16_t key) { return p ? p->key_up(key) : true; } +void InputInterface::clear() { if(p) p->clear(); } +void InputInterface::poll() { if(p) p->poll(); } +InputInterface::InputInterface() : p(0) {} +InputInterface::~InputInterface() { term(); } + +} //namespace ruby diff --git a/src/lib/ruby/ruby.h b/src/lib/ruby/ruby.h new file mode 100644 index 00000000..ff401fcb --- /dev/null +++ b/src/lib/ruby/ruby.h @@ -0,0 +1,88 @@ +/* + ruby + version: 0.01 (2008-02-03) + license: public domain +*/ + +#ifndef RUBY_H +#define RUBY_H + +#include +#include +#include +#include +using nall::min; +using nall::max; +using nall::zeromemory; + +namespace ruby { + +#include +#include +#include + +class VideoInterface { +public: + void driver(const char *driver = ""); + bool init(); + void term(); + + bool cap(Video::Setting setting); + uintptr_t get(Video::Setting setting); + bool set(Video::Setting setting, uintptr_t param); + bool lock(uint16_t *&data, unsigned &pitch); + void unlock(); + void clear(); + void refresh(unsigned width, unsigned height); + VideoInterface(); + ~VideoInterface(); + +private: + Video *p; +}; + +class AudioInterface { +public: + void driver(const char *driver = ""); + bool init(); + void term(); + + bool cap(Audio::Setting setting); + uintptr_t get(Audio::Setting setting); + bool set(Audio::Setting setting, uintptr_t param); + void sample(uint16_t left, uint16_t right); + void clear(); + AudioInterface(); + ~AudioInterface(); + +private: + Audio *p; +}; + +class InputInterface { +public: + void driver(const char *driver = ""); + bool init(); + void term(); + + bool cap(Input::Setting setting); + uintptr_t get(Input::Setting setting); + bool set(Input::Setting setting, uintptr_t param); + bool key_down(uint16_t key); + bool key_up(uint16_t key); + void clear(); + void poll(); + InputInterface(); + ~InputInterface(); + +private: + Input *p; +}; + +extern VideoInterface video; +extern AudioInterface audio; +extern InputInterface input; + +} //namespace ruby + +#endif //ifndef RUBY_H diff --git a/src/lib/ruby/ruby.impl.h b/src/lib/ruby/ruby.impl.h new file mode 100644 index 00000000..e5370168 --- /dev/null +++ b/src/lib/ruby/ruby.impl.h @@ -0,0 +1,57 @@ +/* Video */ + +#ifdef VIDEO_DIRECT3D + #include +#endif + +#ifdef VIDEO_DIRECTDRAW + #include +#endif + +#ifdef VIDEO_GDI + #include +#endif + +#ifdef VIDEO_GLX + #include +#endif + +#ifdef VIDEO_SDL + #include +#endif + +#ifdef VIDEO_XV + #include +#endif + +/* Audio */ + +#ifdef AUDIO_AO + #include +#endif + +#ifdef AUDIO_DIRECTSOUND + #include +#endif + +#ifdef AUDIO_OPENAL + #include +#endif + +#ifdef AUDIO_OSS + #include +#endif + +/* Input */ + +#ifdef INPUT_DIRECTINPUT + #include +#endif + +#ifdef INPUT_SDL + #include +#endif + +#ifdef INPUT_X + #include +#endif diff --git a/src/ui/vai/video.h b/src/lib/ruby/video.h similarity index 56% rename from src/ui/vai/video.h rename to src/lib/ruby/video.h index d01fa216..091e3e20 100644 --- a/src/ui/vai/video.h +++ b/src/lib/ruby/video.h @@ -1,8 +1,3 @@ -#ifndef VIDEO_H -#define VIDEO_H - -#include "../../lib/bbase.h" - class Video { public: enum Setting { @@ -20,16 +15,14 @@ public: virtual uintptr_t get(Setting) { return false; } virtual bool set(Setting, uintptr_t) { return false; } - virtual bool lock(uint16 *&data, uint &pitch) { return false; } + virtual bool lock(uint16_t *&data, unsigned &pitch) { return false; } virtual void unlock() {} - virtual void clear_video() {} - virtual void refresh(uint width, uint height) {} - virtual void init() {} + virtual void clear() {} + virtual void refresh(unsigned width, unsigned height) {} + virtual bool init() { return true; } virtual void term() {} Video() {} virtual ~Video() {} }; - -#endif //ifndef VIDEO_H diff --git a/src/ui/vai/video/video.direct3d.cpp b/src/lib/ruby/video/direct3d.cpp similarity index 72% rename from src/ui/vai/video/video.direct3d.cpp rename to src/lib/ruby/video/direct3d.cpp index 951bcb8f..a0656ecc 100644 --- a/src/ui/vai/video/video.direct3d.cpp +++ b/src/lib/ruby/video/direct3d.cpp @@ -1,11 +1,15 @@ -#include "video.direct3d.h" - #define WIN32_LEAN_AND_MEAN #include #include #define D3DVERTEX (D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1) +#include + +namespace ruby { + +#include "direct3d.h" + class pVideoD3D { public: VideoD3D &self; @@ -22,28 +26,27 @@ public: LPDIRECT3DSURFACE9 surface; struct d3dvertex { - float x, y, z, rhw; //screen coords - uint32 color; //diffuse color - float u, v; //texture coords + float x, y, z, rhw; //screen coords + uint32_t color; //diffuse color + float u, v; //texture coords }; struct { - uint32 t_usage, v_usage; - uint32 t_pool, v_pool; - uint32 lock; - uint32 filter; + uint32_t t_usage, v_usage; + uint32_t t_pool, v_pool; + uint32_t lock; + uint32_t filter; } flags; struct { bool dynamic; //device supports dynamic textures - bool addresswrap; //device supports texture address (u,v) wrapping bool stretchrect; //device supports StretchRect } caps; struct { HWND handle; bool synchronize; - uint filter; + unsigned filter; } settings; bool cap(Video::Setting setting) { @@ -77,15 +80,137 @@ public: return false; } - bool update_video_mode() { - HRESULT hr; + void update_filter() { + if(!device) return; + + switch(settings.filter) { default: + case Video::FilterPoint: flags.filter = D3DTEXF_POINT; break; + case Video::FilterLinear: flags.filter = D3DTEXF_LINEAR; break; + } + + device->SetSamplerState(0, D3DSAMP_MINFILTER, flags.filter); + device->SetSamplerState(0, D3DSAMP_MAGFILTER, flags.filter); + } + + /* Vertex format: + + 0----------1 + | /| + | / | + | / | + | / | + | / | + 2----------3 + + (x,y) screen coords, in pixels (-0.5 for texel / pixel correction) + (u,v) texture coords, betweeen 0.0 (top, left) to 1.0 (bottom, right) + */ + void set_vertex( + uint32_t px, uint32_t py, uint32_t pw, uint32_t ph, + uint32_t tw, uint32_t th, + uint32_t x, uint32_t y, uint32_t w, uint32_t h + ){ + d3dvertex vertex[4]; + vertex[0].x = vertex[2].x = (double)(x ) - 0.5; + vertex[1].x = vertex[3].x = (double)(x + w) - 0.5; + vertex[0].y = vertex[1].y = (double)(y ) - 0.5; + vertex[2].y = vertex[3].y = (double)(y + h) - 0.5; + + //Z-buffer and RHW are unused for 2D blit, set to normal values + vertex[0].z = vertex[1].z = vertex[2].z = vertex[3].z = 0.0; + vertex[0].rhw = vertex[1].rhw = vertex[2].rhw = vertex[3].rhw = 1.0; + + double rw = (double)w / (double)pw * (double)tw; + double rh = (double)h / (double)ph * (double)th; + vertex[0].u = vertex[2].u = (double)(px ) / rw; + vertex[1].u = vertex[3].u = (double)(px + w) / rw; + vertex[0].v = vertex[1].v = (double)(py ) / rh; + vertex[2].v = vertex[3].v = (double)(py + h) / rh; + + vertex_buffer->Lock(0, sizeof(d3dvertex) * 4, (void**)&vertex_ptr, 0); + memcpy(vertex_ptr, vertex, sizeof(d3dvertex) * 4); + vertex_buffer->Unlock(); + + device->SetStreamSource(0, vertex_buffer, 0, sizeof(d3dvertex)); + } + + void clear() { + if(!device) return; + if(caps.stretchrect == false && !texture) return; + + if(caps.stretchrect == false) { + texture->GetLevelDesc(0, &d3dsd); + texture->GetSurfaceLevel(0, &surface); + } + + if(surface) { + device->ColorFill(surface, 0, D3DCOLOR_XRGB(0x00, 0x00, 0x00)); + if(caps.stretchrect == false) { + surface->Release(); + } + } + + //clear primary display and all backbuffers + for(int i = 0; i < 3; i++) { + device->Clear(0, 0, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0x00, 0x00, 0x00), 1.0f, 0); + device->Present(0, 0, 0, 0); + } + } + + bool lock(uint16_t *&data, unsigned &pitch) { + if(caps.stretchrect == false) { + texture->GetLevelDesc(0, &d3dsd); + texture->GetSurfaceLevel(0, &surface); + } + surface->LockRect(&d3dlr, 0, flags.lock); + pitch = d3dlr.Pitch; + return data = (uint16_t*)d3dlr.pBits; + } + + void unlock() { + surface->UnlockRect(); + if(caps.stretchrect == false)surface->Release(); + } + + void refresh(unsigned r_width, unsigned r_height) { + if(!device) return; + + device->BeginScene(); + + if(caps.stretchrect == true) { + RECT rs; + SetRect(&rs, 0, 0, r_width, r_height); + LPDIRECT3DSURFACE9 temp; + device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &temp); + device->StretchRect(surface, &rs, temp, 0, static_cast(flags.filter)); + temp->Release(); + } else { + RECT rd; + GetClientRect(settings.handle, &rd); + set_vertex(0, 0, r_width, r_height, 1024, 1024, 0, 0, rd.right, rd.bottom); + device->SetTexture(0, texture); + device->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2); + } + + device->EndScene(); + + if(settings.synchronize) { + D3DRASTER_STATUS status; + for(;;) { + device->GetRasterStatus(0, &status); + if(bool(status.InVBlank) == true) break; + //Sleep(1); + } + } + + device->Present(0, 0, 0, 0); + } + + bool init() { term(); lpd3d = Direct3DCreate9(D3D_SDK_VERSION); - if(!lpd3d) { - printf("VideoD3D: failed to create Direct3D9 interface"); - return false; - } + if(!lpd3d) return false; memset(&presentation, 0, sizeof(presentation)); presentation.Flags = D3DPRESENTFLAG_VIDEO; @@ -104,20 +229,14 @@ public: if(lpd3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, settings.handle, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &presentation, &device) != D3D_OK) { - printf("VideoD3D: failed to create Direct3D9 device"); return false; } //detect device capabilities device->GetDeviceCaps(&d3dcaps); - if(d3dcaps.MaxTextureWidth < 1024 || d3dcaps.MaxTextureWidth < 1024) { - printf("VideoD3D: renderer requires that the video card supports textures up to 1024x1024.\n" - "However, this display adapter only supports %dx%d-sized textures.\n" - "", d3dcaps.MaxTextureWidth, d3dcaps.MaxTextureHeight); - return false; - } + if(d3dcaps.MaxTextureWidth < 1024 || d3dcaps.MaxTextureWidth < 1024) return false; + caps.dynamic = bool(d3dcaps.Caps2 & D3DCAPS2_DYNAMICTEXTURES); - caps.addresswrap = bool(d3dcaps.TextureAddressCaps & D3DPTADDRESSCAPS_WRAP); caps.stretchrect = (d3dcaps.DevCaps2 & D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES) && (d3dcaps.StretchRectFilterCaps & D3DPTFILTERCAPS_MINFPOINT) && (d3dcaps.StretchRectFilterCaps & D3DPTFILTERCAPS_MAGFPOINT) && @@ -148,11 +267,6 @@ public: device->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); device->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); - if(caps.addresswrap == true) { - device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP); - device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP); - } - device->SetRenderState(D3DRS_LIGHTING, false); device->SetRenderState(D3DRS_ZENABLE, false); device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); @@ -164,8 +278,6 @@ public: device->SetVertexShader(NULL); device->SetFVF(D3DVERTEX); - update_filter(); - if(caps.stretchrect == true) { device->CreateOffscreenPlainSurface(1024, 1024, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &surface, NULL); @@ -177,153 +289,17 @@ public: device->CreateVertexBuffer(sizeof(d3dvertex) * 4, flags.v_usage, D3DVERTEX, static_cast(flags.v_pool), &vertex_buffer, NULL); - clear_video(); + update_filter(); + clear(); return true; } - void update_filter() { - if(!device) return; - - switch(settings.filter) { default: - case Video::FilterPoint: flags.filter = D3DTEXF_POINT; break; - case Video::FilterLinear: flags.filter = D3DTEXF_LINEAR; break; - } - - device->SetSamplerState(0, D3DSAMP_MINFILTER, flags.filter); - device->SetSamplerState(0, D3DSAMP_MAGFILTER, flags.filter); - } - - /* Vertex format: - - 0----------1 - | /| - | / | - | / | - | / | - | / | - 2----------3 - - (x,y) screen coords, in pixels (-0.5 for texel / pixel correction) - (u,v) texture coords, betweeen 0.0 (top, left) to 1.0 (bottom, right) - */ - void set_vertex(uint32 px, uint32 py, uint32 pw, uint32 ph, - uint32 tw, uint32 th, uint32 x, uint32 y, uint32 w, uint32 h) { - d3dvertex vertex[4]; - vertex[0].x = vertex[2].x = (float)(x ) - 0.5; - vertex[1].x = vertex[3].x = (float)(x + w) - 0.5; - vertex[0].y = vertex[1].y = (float)(y ) - 0.5; - vertex[2].y = vertex[3].y = (float)(y + h) - 0.5; - - //unused - vertex[0].z = vertex[1].z = 1.0; - vertex[2].z = vertex[3].z = 1.0; - vertex[0].rhw = vertex[1].rhw = 1.0; - vertex[2].rhw = vertex[3].rhw = 1.0; - - //setup a gradient fade for when pause is enabled - vertex[0].color = 0x80000000; - vertex[1].color = 0xa8000000; - vertex[2].color = 0xa8000000; - vertex[3].color = 0xd0000000; - - float rw = (float)w / (float)pw * (float)tw; - float rh = (float)h / (float)ph * (float)th; - vertex[0].u = vertex[2].u = (float)(px ) / rw; - vertex[1].u = vertex[3].u = (float)(px + w) / rw; - vertex[0].v = vertex[1].v = (float)(py ) / rh; - vertex[2].v = vertex[3].v = (float)(py + h) / rh; - - vertex_buffer->Lock(0, sizeof(d3dvertex) * 4, (void**)&vertex_ptr, 0); - memcpy(vertex_ptr, vertex, sizeof(d3dvertex) * 4); - vertex_buffer->Unlock(); - - device->SetStreamSource(0, vertex_buffer, 0, sizeof(d3dvertex)); - } - - void clear_video() { - if(!device) return; - if(caps.stretchrect == false && !texture) return; - - if(caps.stretchrect == false) { - texture->GetLevelDesc(0, &d3dsd); - texture->GetSurfaceLevel(0, &surface); - } - - if(surface) { - device->ColorFill(surface, 0, D3DCOLOR_XRGB(0x00, 0x00, 0x00)); - if(caps.stretchrect == false) { - surface->Release(); - } - } - - //clear primary display and all backbuffers - for(int i = 0; i < 3; i++) { - device->Clear(0, 0, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0x00, 0x00, 0x00), 1.0f, 0); - device->Present(0, 0, 0, 0); - } - } - - bool lock(uint16 *&data, uint &pitch) { - if(caps.stretchrect == false) { - texture->GetLevelDesc(0, &d3dsd); - texture->GetSurfaceLevel(0, &surface); - } - surface->LockRect(&d3dlr, 0, flags.lock); - pitch = d3dlr.Pitch; - data = (uint16*)d3dlr.pBits; - return data; - } - - void unlock() { - surface->UnlockRect(); - if(caps.stretchrect == false)surface->Release(); - } - - void refresh(uint r_width, uint r_height) { - if(!device) return; - - device->BeginScene(); - - if(caps.stretchrect == true) { - RECT rs; - SetRect(&rs, 0, 0, r_width, r_height); - LPDIRECT3DSURFACE9 temp; - device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &temp); - device->StretchRect(surface, &rs, temp, 0, static_cast(flags.filter)); - temp->Release(); - } else { - RECT rd; - GetClientRect(settings.handle, &rd); - set_vertex(0, 0, r_width, r_height, 1024, 1024, 0, 0, rd.right, rd.bottom); - device->SetTexture(0, texture); - device->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2); - } - - device->EndScene(); - - if(settings.synchronize) { - D3DRASTER_STATUS status; - for(;;) { - device->GetRasterStatus(0, &status); - if(bool(status.InVBlank) == true) break; - //Sleep(1); - } - } - - device->Present(0, 0, 0, 0); - } - - void init() { - term(); - update_video_mode(); - } - void term() { - safe_release(vertex_buffer); - safe_release(surface); - safe_release(texture); - safe_release(device); - safe_release(lpd3d); + if(vertex_buffer) { vertex_buffer->Release(); vertex_buffer = 0; } + if(surface) { surface->Release(); surface = 0; } + if(texture) { texture->Release(); texture = 0; } + if(device) { device->Release(); device = 0; } + if(lpd3d) { lpd3d->Release(); lpd3d = 0; } } pVideoD3D(VideoD3D &self_) : self(self_) { @@ -342,11 +318,15 @@ public: bool VideoD3D::cap(Setting setting) { return p.cap(setting); } uintptr_t VideoD3D::get(Setting setting) { return p.get(setting); } bool VideoD3D::set(Setting setting, uintptr_t param) { return p.set(setting, param); } -bool VideoD3D::lock(uint16 *&data, uint &pitch) { return p.lock(data, pitch); } +bool VideoD3D::lock(uint16_t *&data, unsigned &pitch) { return p.lock(data, pitch); } void VideoD3D::unlock() { p.unlock(); } -void VideoD3D::clear_video() { p.clear_video(); } -void VideoD3D::refresh(uint width, uint height) { p.refresh(width, height); } -void VideoD3D::init() { p.init(); } +void VideoD3D::clear() { p.clear(); } +void VideoD3D::refresh(unsigned width, unsigned height) { p.refresh(width, height); } +bool VideoD3D::init() { return p.init(); } void VideoD3D::term() { p.term(); } VideoD3D::VideoD3D() : p(*new pVideoD3D(*this)) {} VideoD3D::~VideoD3D() { delete &p; } + +} //namespace ruby + +#undef D3DVERTEX diff --git a/src/lib/ruby/video/direct3d.h b/src/lib/ruby/video/direct3d.h new file mode 100644 index 00000000..17c2d66a --- /dev/null +++ b/src/lib/ruby/video/direct3d.h @@ -0,0 +1,22 @@ +class pVideoD3D; + +class VideoD3D : public Video { +public: + bool cap(Setting); + uintptr_t get(Setting); + bool set(Setting, uintptr_t); + + bool lock(uint16_t *&data, unsigned &pitch); + void unlock(); + + void clear(); + void refresh(unsigned width, unsigned height); + bool init(); + void term(); + + VideoD3D(); + ~VideoD3D(); + +private: + pVideoD3D &p; +}; diff --git a/src/ui/vai/video/video.directdraw.cpp b/src/lib/ruby/video/directdraw.cpp similarity index 80% rename from src/ui/vai/video/video.directdraw.cpp rename to src/lib/ruby/video/directdraw.cpp index c26a1bed..4d021d1e 100644 --- a/src/ui/vai/video/video.directdraw.cpp +++ b/src/lib/ruby/video/directdraw.cpp @@ -1,9 +1,13 @@ -#include "video.directdraw.h" - #define WIN32_LEAN_AND_MEAN #include #include +#include + +namespace ruby { + +#include "directdraw.h" + class pVideoDD { public: VideoDD &self; @@ -44,7 +48,7 @@ public: return false; } - void clear_video() { + void clear() { DDBLTFX fx; fx.dwSize = sizeof(DDBLTFX); fx.dwFillColor = 0x00000000; @@ -52,18 +56,17 @@ public: raster->Blt(0, 0, 0, DDBLT_WAIT | DDBLT_COLORFILL, &fx); } - bool lock(uint16 *&data, uint &pitch) { + bool lock(uint16_t *&data, unsigned &pitch) { if(raster->Lock(0, &ddsd, DDLOCK_WAIT, 0) != DD_OK) return false; pitch = ddsd.lPitch; - data = (uint16*)ddsd.lpSurface; - return data; + return data = (uint16_t*)ddsd.lpSurface; } void unlock() { raster->Unlock(0); } - void refresh(uint r_width, uint r_height) { + void refresh(unsigned r_width, unsigned r_height) { if(settings.synchronize) { for(;;) { BOOL in_vblank; @@ -88,12 +91,12 @@ public: } } - void init() { + bool init() { term(); DirectDrawCreate(0, &lpdd, 0); lpdd->QueryInterface(IID_IDirectDraw7, (void**)&lpdd7); - safe_release(lpdd); + if(lpdd) { lpdd->Release(); lpdd = 0; } lpdd7->SetCooperativeLevel(settings.handle, DDSCL_NORMAL); @@ -109,7 +112,8 @@ public: screen->SetClipper(clipper); create_raster(); - clear_video(); + clear(); + return true; } void create_raster() { @@ -146,11 +150,11 @@ public: } void term() { - safe_release(clipper); - safe_release(raster); - safe_release(screen); - safe_release(lpdd7); - safe_release(lpdd); + if(clipper) { clipper->Release(); clipper = 0; } + if(raster) { raster->Release(); raster = 0; } + if(screen) { screen->Release(); screen = 0; } + if(lpdd7) { lpdd7->Release(); lpdd7 = 0; } + if(lpdd) { lpdd->Release(); lpdd = 0; } } pVideoDD(VideoDD &self_) : self(self_) { @@ -167,11 +171,13 @@ public: bool VideoDD::cap(Setting setting) { return p.cap(setting); } uintptr_t VideoDD::get(Setting setting) { return p.get(setting); } bool VideoDD::set(Setting setting, uintptr_t param) { return p.set(setting, param); } -bool VideoDD::lock(uint16 *&data, uint &pitch) { return p.lock(data, pitch); } +bool VideoDD::lock(uint16_t *&data, unsigned &pitch) { return p.lock(data, pitch); } void VideoDD::unlock() { p.unlock(); } -void VideoDD::clear_video() { p.clear_video(); } -void VideoDD::refresh(uint width, uint height) { p.refresh(width, height); } -void VideoDD::init() { p.init(); } +void VideoDD::clear() { p.clear(); } +void VideoDD::refresh(unsigned width, unsigned height) { p.refresh(width, height); } +bool VideoDD::init() { return p.init(); } void VideoDD::term() { p.term(); } VideoDD::VideoDD() : p(*new pVideoDD(*this)) {} VideoDD::~VideoDD() { delete &p; } + +} //namespace ruby diff --git a/src/lib/ruby/video/directdraw.h b/src/lib/ruby/video/directdraw.h new file mode 100644 index 00000000..f202121b --- /dev/null +++ b/src/lib/ruby/video/directdraw.h @@ -0,0 +1,22 @@ +class pVideoDD; + +class VideoDD : public Video { +public: + bool cap(Setting); + uintptr_t get(Setting); + bool set(Setting, uintptr_t); + + bool lock(uint16_t *&data, unsigned &pitch); + void unlock(); + + void clear(); + void refresh(unsigned width, unsigned height); + bool init(); + void term(); + + VideoDD(); + ~VideoDD(); + +private: + pVideoDD &p; +}; diff --git a/src/ui/vai/video/video.gdi.cpp b/src/lib/ruby/video/gdi.cpp similarity index 73% rename from src/ui/vai/video/video.gdi.cpp rename to src/lib/ruby/video/gdi.cpp index 0863d1b8..4c827a27 100644 --- a/src/ui/vai/video/video.gdi.cpp +++ b/src/lib/ruby/video/gdi.cpp @@ -1,13 +1,18 @@ -#include "video.gdi.h" - +#include #define WIN32_LEAN_AND_MEAN #include +#include + +namespace ruby { + +#include "gdi.h" + class pVideoGDI { public: VideoGDI &self; - uint16 *buffer; + uint16_t *buffer; HBITMAP bitmap; HDC bitmapdc; BITMAPINFO bmi; @@ -34,15 +39,14 @@ public: return false; } - bool lock(uint16 *&data, uint &pitch) { + bool lock(uint16_t *&data, unsigned &pitch) { pitch = 2048; - data = buffer; - return data; + return data = buffer; } void unlock() {} - void refresh(uint r_width, uint r_height) { + void refresh(unsigned r_width, unsigned r_height) { RECT rc; GetClientRect(settings.handle, &rc); @@ -52,8 +56,8 @@ public: ReleaseDC(settings.handle, hdc); } - void init() { - HDC hdc = GetDC(settings.handle); + bool init() { + HDC hdc = GetDC(settings.handle); bitmapdc = CreateCompatibleDC(hdc); assert(bitmapdc); bitmap = CreateCompatibleBitmap(hdc, 1024, 1024); @@ -68,7 +72,9 @@ public: bmi.bmiHeader.biPlanes = 1; bmi.bmiHeader.biBitCount = 16; //biBitCount of 15 is invalid, biBitCount of 16 is really RGB555 bmi.bmiHeader.biCompression = BI_RGB; - bmi.bmiHeader.biSizeImage = 1024 * 1024 * sizeof(uint16); + bmi.bmiHeader.biSizeImage = 1024 * 1024 * sizeof(uint16_t); + + return true; } void term() { @@ -77,7 +83,7 @@ public: } pVideoGDI(VideoGDI &self_) : self(self_) { - buffer = (uint16*)malloc(1024 * 1024 * sizeof(uint16)); + buffer = (uint16_t*)malloc(1024 * 1024 * sizeof(uint16_t)); settings.handle = 0; } @@ -89,10 +95,12 @@ public: bool VideoGDI::cap(Setting setting) { return p.cap(setting); } uintptr_t VideoGDI::get(Setting setting) { return p.get(setting); } bool VideoGDI::set(Setting setting, uintptr_t param) { return p.set(setting, param); } -bool VideoGDI::lock(uint16 *&data, uint &pitch) { return p.lock(data, pitch); } +bool VideoGDI::lock(uint16_t *&data, unsigned &pitch) { return p.lock(data, pitch); } void VideoGDI::unlock() { p.unlock(); } -void VideoGDI::refresh(uint width, uint height) { p.refresh(width, height); } -void VideoGDI::init() { p.init(); } +void VideoGDI::refresh(unsigned width, unsigned height) { p.refresh(width, height); } +bool VideoGDI::init() { return p.init(); } void VideoGDI::term() { p.term(); } VideoGDI::VideoGDI() : p(*new pVideoGDI(*this)) {} VideoGDI::~VideoGDI() { delete &p; } + +} //namespace ruby diff --git a/src/ui/vai/video/video.gdi.h b/src/lib/ruby/video/gdi.h similarity index 51% rename from src/ui/vai/video/video.gdi.h rename to src/lib/ruby/video/gdi.h index 4399c257..7a2c5735 100644 --- a/src/ui/vai/video/video.gdi.h +++ b/src/lib/ruby/video/gdi.h @@ -1,8 +1,3 @@ -#ifndef VIDEO_GDI_H -#define VIDEO_GDI_H - -#include "../video.h" - class pVideoGDI; class VideoGDI : public Video { @@ -11,11 +6,11 @@ public: uintptr_t get(Setting); bool set(Setting, uintptr_t); - bool lock(uint16 *&data, uint &pitch); + bool lock(uint16_t *&data, unsigned &pitch); void unlock(); - void refresh(uint width, uint height); - void init(); + void refresh(unsigned width, unsigned height); + bool init(); void term(); VideoGDI(); @@ -24,5 +19,3 @@ public: private: pVideoGDI &p; }; - -#endif //ifndef VIDEO_GDI_H diff --git a/src/lib/ruby/video/glx.cpp b/src/lib/ruby/video/glx.cpp new file mode 100644 index 00000000..c9c80514 --- /dev/null +++ b/src/lib/ruby/video/glx.cpp @@ -0,0 +1,241 @@ +#include +#include + +#include + +namespace ruby { + +#include "glx.h" + +class pVideoGLX { +public: + VideoGLX &self; + uint16_t *buffer; + + Display *display; + int screen; + XWindowAttributes attributes; + GLXFBConfig fbconfig, *fbconfiglist; + GLXContext glxcontext; + GLXWindow glxwindow; + GLuint gltexture; + + struct { + bool double_buffer; + unsigned buffer_size; + unsigned red_size; + unsigned green_size; + unsigned blue_size; + unsigned alpha_size; + } glx; + + struct { + Window handle; + unsigned filter; + } settings; + + bool cap(Video::Setting setting) { + if(setting == Video::Handle) return true; + if(setting == Video::Filter) return true; + return false; + } + + uintptr_t get(Video::Setting setting) { + if(setting == Video::Handle) return settings.handle; + if(setting == Video::Filter) return settings.filter; + return false; + } + + bool set(Video::Setting setting, uintptr_t param) { + if(setting == Video::Handle) { + settings.handle = param; + return true; + } + if(setting == Video::Filter) { + settings.filter = param; + return true; + } + return false; + } + + bool lock(uint16_t *&data, unsigned &pitch) { + pitch = 1024 * 2; + return data = buffer; + } + + void unlock() { + } + + void clear() { + memset(buffer, 0, 1024 * 1024 * sizeof(uint16_t)); + glClearColor(0.0, 0.0, 0.0, 1.0); + glClear(GL_COLOR_BUFFER_BIT); + glFlush(); + if(glx.double_buffer) glXSwapBuffers(display, glxwindow); + } + + void refresh(unsigned width_, unsigned height_) { + XGetWindowAttributes(display, settings.handle, &attributes); + + glClearColor(0.0, 0.0, 0.0, 1.0); + glClear(GL_COLOR_BUFFER_BIT); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, + settings.filter == Video::FilterPoint ? GL_NEAREST : GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, + settings.filter == Video::FilterPoint ? GL_NEAREST : GL_LINEAR); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0, attributes.width, 0, attributes.height, -1.0, 1.0); + glViewport(0, 0, attributes.width, attributes.height); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glPixelStorei(GL_UNPACK_ROW_LENGTH, 1024); //length of buffer in pixels + glTexSubImage2D(GL_TEXTURE_2D, + /* mip-map level = */ 0, /* x = */ 0, /* y = */ 0, + width_, height_, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, buffer); + + //OpenGL projection sets 0,0 as *bottom-left* of screen + //Therefore, below vertices flip image to support top-left source + //Texture range = x1:0.0, y1:0.0, x2:1.0, y2:1.0 + //Vertex range = x1:0, y1:0, x2:width, y2:height + double w = double(width_) / 1024.0; + double h = double(height_) / 1024.0; + int u = attributes.width; + int v = attributes.height; + glBegin(GL_TRIANGLE_STRIP); + glTexCoord2f(0, 0); glVertex3i(0, v, 0); + glTexCoord2f(w, 0); glVertex3i(u, v, 0); + glTexCoord2f(0, h); glVertex3i(0, 0, 0); + glTexCoord2f(w, h); glVertex3i(u, 0, 0); + glEnd(); + + glFlush(); + if(glx.double_buffer) glXSwapBuffers(display, glxwindow); + } + + bool init() { + buffer = new(zeromemory) uint16_t[1024 * 1024 * 4]; + + //GLX requires a compatible X11 visualid to render to. + //glXChooseFBConfig often chooses visualid that is not + //compatible with target X11 window's visualid. + //Therefore, iterate all available framebuffer configurations + //to locate matching visualid. + + display = XOpenDisplay(0); + screen = DefaultScreen(display); + XGetWindowAttributes(display, settings.handle, &attributes); + + int elements = 0; + fbconfig = 0; + fbconfiglist = glXGetFBConfigs(display, screen, &elements); + for(int i = 0; i < elements; i++) { + int visualid = 0; + glXGetFBConfigAttrib(display, fbconfiglist[i], GLX_VISUAL_ID, &visualid); + if(visualid == attributes.visual->visualid) { + fbconfig = fbconfiglist[i]; + break; + } + } + + if(!fbconfig) { + fprintf(stderr, "VideoGLX: failed to find compatible Visual ID\n"); + term(); + return false; + } + + glxcontext = glXCreateNewContext(display, fbconfig, GLX_RGBA_TYPE, 0, false); + if(!glxcontext) { + fprintf(stderr, "VideoGLX: failed to create context\n"); + term(); + return false; + } + + glxwindow = glXCreateWindow(display, fbconfig, settings.handle, 0); + if(!glxwindow) { + fprintf(stderr, "VideoGLX: failed to create window\n"); + term(); + return false; + } + + if(glXMakeContextCurrent(display, glxwindow, glxwindow, glxcontext) == false) { + fprintf(stderr, "VideoGLX: failed to set context\n"); + term(); + return false; + } + + //read attributes of frame buffer for later use + int value = 0; + glXGetFBConfigAttrib(display, fbconfig, GLX_DOUBLEBUFFER, &value); + glx.double_buffer = value; + glXGetFBConfigAttrib(display, fbconfig, GLX_BUFFER_SIZE, &value); + glx.buffer_size = value; + glXGetFBConfigAttrib(display, fbconfig, GLX_RED_SIZE, &value); + glx.red_size = value; + glXGetFBConfigAttrib(display, fbconfig, GLX_GREEN_SIZE, &value); + glx.green_size = value; + glXGetFBConfigAttrib(display, fbconfig, GLX_BLUE_SIZE, &value); + glx.blue_size = value; + glXGetFBConfigAttrib(display, fbconfig, GLX_ALPHA_SIZE, &value); + glx.alpha_size = value; + + //disable unused features, enable required features + glDisable(GL_BLEND); + glDisable(GL_DEPTH_TEST); + glDisable(GL_POLYGON_SMOOTH); + glEnable(GL_DITHER); + glEnable(GL_TEXTURE_2D); + + //create GL texture to copy buffer to + gltexture = 0; + glGenTextures(1, &gltexture); + glBindTexture(GL_TEXTURE_2D, gltexture); + glPixelStorei(GL_UNPACK_ROW_LENGTH, 1024); + glTexImage2D(GL_TEXTURE_2D, + /* mip-map level = */ 0, /* internal format = */ GL_RGB, + /* width = */ 1024, /* height = */ 1024, /* border = */ 0, + /* format = */ GL_RGB, GL_UNSIGNED_SHORT_5_6_5, buffer); + + return true; + } + + void term() { + if(gltexture) { + glDeleteTextures(1, &gltexture); + gltexture = 0; + } + + if(glxcontext) { + glXDestroyContext(display, glxcontext); + glxcontext = 0; + } + + delete[] buffer; + } + + pVideoGLX(VideoGLX &self_) : self(self_) { + settings.handle = 0; + glxcontext = 0; + glxwindow = 0; + gltexture = 0; + } +}; + +bool VideoGLX::cap(Setting setting) { return p.cap(setting); } +uintptr_t VideoGLX::get(Setting setting) { return p.get(setting); } +bool VideoGLX::set(Setting setting, uintptr_t param) { return p.set(setting, param); } +bool VideoGLX::lock(uint16_t *&data, unsigned &pitch) { return p.lock(data, pitch); } +void VideoGLX::unlock() { p.unlock(); } +void VideoGLX::clear() { p.clear(); } +void VideoGLX::refresh(unsigned width, unsigned height) { p.refresh(width, height); } +bool VideoGLX::init() { return p.init(); } +void VideoGLX::term() { p.term(); } +VideoGLX::VideoGLX() : p(*new pVideoGLX(*this)) {} +VideoGLX::~VideoGLX() { delete &p; } + +} //namespace ruby diff --git a/src/lib/ruby/video/glx.h b/src/lib/ruby/video/glx.h new file mode 100644 index 00000000..444f60e6 --- /dev/null +++ b/src/lib/ruby/video/glx.h @@ -0,0 +1,22 @@ +class pVideoGLX; + +class VideoGLX : public Video { +public: + bool cap(Setting); + uintptr_t get(Setting); + bool set(Setting, uintptr_t); + + bool lock(uint16_t *&data, unsigned &pitch); + void unlock(); + + void clear(); + void refresh(unsigned width, unsigned height); + bool init(); + void term(); + + VideoGLX(); + ~VideoGLX(); + +private: + pVideoGLX &p; +}; diff --git a/src/lib/ruby/video/sdl.cpp b/src/lib/ruby/video/sdl.cpp new file mode 100644 index 00000000..ab13c878 --- /dev/null +++ b/src/lib/ruby/video/sdl.cpp @@ -0,0 +1,113 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace ruby { + +#include "sdl.h" + +class pVideoSDL { +public: + VideoSDL &self; + Display *display; + SDL_Surface *screen, *buffer; + + struct { + uintptr_t handle; + } settings; + + bool cap(Video::Setting setting) { + if(setting == Video::Handle) return true; + return false; + } + + uintptr_t get(Video::Setting setting) { + if(setting == Video::Handle) return settings.handle; + return false; + } + + bool set(Video::Setting setting, uintptr_t param) { + if(setting == Video::Handle) { + settings.handle = param; + return true; + } + return false; + } + + bool lock(uint16_t *&data, unsigned &pitch) { + if(SDL_MUSTLOCK(buffer)) SDL_LockSurface(buffer); + pitch = buffer->pitch; + return data = (uint16_t*)buffer->pixels; + } + + void unlock() { + if(SDL_MUSTLOCK(buffer)) SDL_UnlockSurface(buffer); + } + + void clear() { + } + + void refresh(unsigned width, unsigned height) { + XWindowAttributes attributes; + XGetWindowAttributes(display, settings.handle, &attributes); + + SDL_Rect src, dest; + + src.x = 0; + src.y = 0; + src.w = width; + src.h = height; + + dest.x = 0; + dest.y = 0; + dest.w = attributes.width; + dest.h = attributes.height; + + SDL_SoftStretch(buffer, &src, screen, &dest); + SDL_UpdateRect(screen, dest.x, dest.y, dest.w, dest.h); + } + + bool init() { + display = XOpenDisplay(0); + char env[512]; + sprintf(env, "SDL_WINDOWID=%ld", settings.handle); + putenv(env); + SDL_InitSubSystem(SDL_INIT_VIDEO); + screen = SDL_SetVideoMode(2560, 1600, 16, SDL_HWSURFACE); + buffer = SDL_CreateRGBSurface(SDL_HWSURFACE, + 1024, 1024, + 16, 0xf800, 0x07e0, 0x001f, 0x0000 + ); + return true; + } + + void term() { + SDL_QuitSubSystem(SDL_INIT_VIDEO); + } + + pVideoSDL(VideoSDL &self_) : self(self_) { + settings.handle = 0; + } +}; + +bool VideoSDL::cap(Setting setting) { return p.cap(setting); } +uintptr_t VideoSDL::get(Setting setting) { return p.get(setting); } +bool VideoSDL::set(Setting setting, uintptr_t param) { return p.set(setting, param); } +bool VideoSDL::lock(uint16_t *&data, unsigned &pitch) { return p.lock(data, pitch); } +void VideoSDL::unlock() { p.unlock(); } +void VideoSDL::clear() { p.clear(); } +void VideoSDL::refresh(unsigned width, unsigned height) { p.refresh(width, height); } +bool VideoSDL::init() { return p.init(); } +void VideoSDL::term() { p.term(); } +VideoSDL::VideoSDL() : p(*new pVideoSDL(*this)) {} +VideoSDL::~VideoSDL() { delete &p; } + +} //namespace ruby diff --git a/src/lib/ruby/video/sdl.h b/src/lib/ruby/video/sdl.h new file mode 100644 index 00000000..d3fb9f43 --- /dev/null +++ b/src/lib/ruby/video/sdl.h @@ -0,0 +1,22 @@ +class pVideoSDL; + +class VideoSDL : public Video { +public: + bool cap(Setting); + uintptr_t get(Setting); + bool set(Setting, uintptr_t); + + bool lock(uint16_t *&data, unsigned &pitch); + void unlock(); + + void clear(); + void refresh(unsigned width, unsigned height); + bool init(); + void term(); + + VideoSDL(); + ~VideoSDL(); + +private: + pVideoSDL &p; +}; diff --git a/src/ui/vai/video/video.xv.cpp b/src/lib/ruby/video/xv.cpp similarity index 63% rename from src/ui/vai/video/video.xv.cpp rename to src/lib/ruby/video/xv.cpp index 24937908..79809717 100644 --- a/src/ui/vai/video/video.xv.cpp +++ b/src/lib/ruby/video/xv.cpp @@ -1,5 +1,3 @@ -#include "video.xv.h" - #include #include #include @@ -9,18 +7,24 @@ #include #include -extern "C" XvImage* XvShmCreateImage(Display*, XvPortID, int, char*, int, int, XShmSegmentInfo*); +extern "C" XvImage* XvShmCreateImage(Display*, XvPortID, int, char*, int, int, XShmSegmentInfo*); + +#include + +namespace ruby { + +#include "xv.h" class pVideoXv { public: VideoXv &self; - uint16 *buffer; + uint16_t *buffer; XvImage *xvimage; GC gc; Display *display; int screen, xv_port; XShmSegmentInfo shminfo; - uint8 *ytable, *utable, *vtable; + uint8_t *ytable, *utable, *vtable; struct { Window handle; @@ -44,38 +48,37 @@ public: return false; } - bool lock(uint16 *&data, uint &pitch) { + bool lock(uint16_t *&data, unsigned &pitch) { pitch = 1024 * 2; - data = buffer; - return data; + return data = buffer; } void unlock() { } - void clear_video() { - memset(buffer, 0, 1024 * 1024 * sizeof(uint16)); - //clear twice in case video is double buffered ... + void clear() { + memset(buffer, 0, 1024 * 1024 * sizeof(uint16_t)); + //clear twice in case video is double buffered ... refresh(1024, 1024); refresh(1024, 1024); } - void refresh(uint r_width, uint r_height) { + void refresh(unsigned r_width, unsigned r_height) { Window dw; int d0, d1; - uint d2, d3; - uint width, height; + unsigned d2, d3; + unsigned width, height; XGetGeometry(display, settings.handle, &dw, &d0, &d1, &width, &height, &d2, &d3); - uint16 *input = (uint16*)buffer; - uint16 *output = (uint16*)xvimage->data; + uint16_t *input = (uint16_t*)buffer; + uint16_t *output = (uint16_t*)xvimage->data; for(int y = 0; y < r_height; y++) { for(int x = 0; x < r_width >> 1; x++) { - uint16 p0 = *input++; - uint16 p1 = *input++; + uint16_t p0 = *input++; + uint16_t p1 = *input++; - uint8 u = (utable[p0] + utable[p1]) >> 1; - uint8 v = (vtable[p0] + vtable[p1]) >> 1; + uint8_t u = (utable[p0] + utable[p1]) >> 1; + uint8_t v = (vtable[p0] + vtable[p1]) >> 1; *output++ = (u << 8) | ytable[p0]; *output++ = (v << 8) | ytable[p1]; @@ -90,13 +93,13 @@ public: true); } - void init() { - buffer = (uint16*)malloc(1024 * 1024 * sizeof(uint16)); + bool init() { + buffer = (uint16_t*)malloc(1024 * 1024 * sizeof(uint16_t)); display = XOpenDisplay(0); screen = DefaultScreen(display); gc = XCreateGC(display, settings.handle, 0, 0); - XVisualInfo visual_info; + XVisualInfo visual_info; if(XMatchVisualInfo(display, screen, 24, TrueColor, &visual_info)) { } else if(XMatchVisualInfo(display, screen, 16, TrueColor, &visual_info)) { } else if(XMatchVisualInfo(display, screen, 15, TrueColor, &visual_info)) { @@ -105,40 +108,54 @@ public: } else if(XMatchVisualInfo(display, screen, 8, StaticGray, &visual_info)) { } else if(XMatchVisualInfo(display, screen, 1, StaticGray, &visual_info)) { } else { - printf("VideoXv: unable to find suitable video display.\n"); + fprintf(stderr, "VideoXv: unable to find suitable video display.\n"); + return false; } - if(!XShmQueryExtension(display)) printf("VideoXv: XShm extension not found.\n"); + if(!XShmQueryExtension(display)) { + fprintf(stderr, "VideoXv: XShm extension not found.\n"); + return false; + } xv_port = -1; - XvAdaptorInfo *adaptor_info; - uint adaptor_count; + XvAdaptorInfo *adaptor_info; + unsigned adaptor_count; XvQueryAdaptors(display, DefaultRootWindow(display), &adaptor_count, &adaptor_info); - for(uint i = 0; i < adaptor_count; i++) { - //find adaptor that supports both input (memory->drawable) and image (drawable->screen) masks + for(unsigned i = 0; i < adaptor_count; i++) { + //find adaptor that supports both input (memory->drawable) and image (drawable->screen) masks if(adaptor_info[i].type & XvInputMask && adaptor_info[i].type & XvImageMask) { xv_port = adaptor_info[i].base_id; break; } } XvFreeAdaptorInfo(adaptor_info); - if(xv_port == -1) printf("VideoXv: failed to find valid XvPort.\n"); + if(xv_port == -1) { + fprintf(stderr, "VideoXv: failed to find valid XvPort.\n"); + return false; + } - //set colorkey to auto paint, so that Xv video output is always visible - const Atom atom = XInternAtom(display, "XV_AUTOPAINT_COLORKEY", true); + //set colorkey to auto paint, so that Xv video output is always visible + const Atom atom = XInternAtom(display, "XV_AUTOPAINT_COLORKEY", true); if(atom != None) XvSetPortAttribute(display, xv_port, atom, 1); - //0x00000003 = 32-bit X8R8G8B8 [xRGB] (few drivers support this mode) - //0x32595559 = 16-bit Y8U8,Y8V8 [YUY2] (most drivers support this mode) + //0x00000003 = 32-bit X8R8G8B8 [xRGB] (few drivers support this mode) + //0x32595559 = 16-bit Y8U8,Y8V8 [YUY2] (most drivers support this mode) xvimage = XvShmCreateImage(display, xv_port, 0x32595559, 0, 1024, 1024, &shminfo); - if(!xvimage) printf("VideoXv: XShmCreateImage failed.\n"); + if(!xvimage) { + fprintf(stderr, "VideoXv: XShmCreateImage failed.\n"); + return false; + } shminfo.shmid = shmget(IPC_PRIVATE, xvimage->data_size, IPC_CREAT | 0777); shminfo.shmaddr = xvimage->data = (char*)shmat(shminfo.shmid, 0, 0); shminfo.readOnly = false; - if(!XShmAttach(display, &shminfo)) printf("VideoXv: XShmAttach failed.\n"); + if(!XShmAttach(display, &shminfo)) { + fprintf(stderr, "VideoXv: XShmAttach failed.\n"); + return false; + } init_yuv_tables(); - clear_video(); + clear(); + return true; } void term() { @@ -149,13 +166,13 @@ public: } void init_yuv_tables() { - ytable = (uint8*)malloc(65536); - utable = (uint8*)malloc(65536); - vtable = (uint8*)malloc(65536); + ytable = (uint8_t*)malloc(65536); + utable = (uint8_t*)malloc(65536); + vtable = (uint8_t*)malloc(65536); for(int i = 0; i < 65536; i++) { //extract RGB565 color data from i - uint8 r = (i >> 11) & 31, g = (i >> 5) & 63, b = (i) & 31; + uint8_t r = (i >> 11) & 31, g = (i >> 5) & 63, b = (i) & 31; r = (r << 3) | (r >> 2); //R5->R8 g = (g << 2) | (g >> 4); //G6->G8 b = (b << 3) | (b >> 2); //B5->B8 @@ -185,11 +202,13 @@ public: bool VideoXv::cap(Setting setting) { return p.cap(setting); } uintptr_t VideoXv::get(Setting setting) { return p.get(setting); } bool VideoXv::set(Setting setting, uintptr_t param) { return p.set(setting, param); } -bool VideoXv::lock(uint16 *&data, uint &pitch) { return p.lock(data, pitch); } +bool VideoXv::lock(uint16_t *&data, unsigned &pitch) { return p.lock(data, pitch); } void VideoXv::unlock() { p.unlock(); } -void VideoXv::clear_video() { p.clear_video(); } -void VideoXv::refresh(uint width, uint height) { p.refresh(width, height); } -void VideoXv::init() { p.init(); } +void VideoXv::clear() { p.clear(); } +void VideoXv::refresh(unsigned width, unsigned height) { p.refresh(width, height); } +bool VideoXv::init() { return p.init(); } void VideoXv::term() { p.term(); } VideoXv::VideoXv() : p(*new pVideoXv(*this)) {} VideoXv::~VideoXv() { delete &p; } + +} //namespace ruby diff --git a/src/lib/ruby/video/xv.h b/src/lib/ruby/video/xv.h new file mode 100644 index 00000000..f93b9728 --- /dev/null +++ b/src/lib/ruby/video/xv.h @@ -0,0 +1,22 @@ +class pVideoXv; + +class VideoXv : public Video { +public: + bool cap(Setting); + uintptr_t get(Setting); + bool set(Setting, uintptr_t); + + bool lock(uint16_t *&data, unsigned &pitch); + void unlock(); + + void clear(); + void refresh(unsigned width, unsigned height); + bool init(); + void term(); + + VideoXv(); + ~VideoXv(); + +private: + pVideoXv &p; +}; diff --git a/src/ppu/bppu/bppu_mmio.cpp b/src/ppu/bppu/bppu_mmio.cpp index 78c46ea8..17784636 100644 --- a/src/ppu/bppu/bppu_mmio.cpp +++ b/src/ppu/bppu/bppu_mmio.cpp @@ -5,13 +5,12 @@ void bPPU::latch_counters() { } uint16 bPPU::get_vram_address() { -uint16 addr; - addr = regs.vram_addr; + uint16 addr = regs.vram_addr; switch(regs.vram_mapping) { - case 0: break; //direct - case 1: addr = (addr & 0xff00) | ((addr & 0x001f) << 3) | ((addr >> 5) & 7); break; - case 2: addr = (addr & 0xfe00) | ((addr & 0x003f) << 3) | ((addr >> 6) & 7); break; - case 3: addr = (addr & 0xfc00) | ((addr & 0x007f) << 3) | ((addr >> 7) & 7); break; + case 0: break; //direct mapping + case 1: addr = (addr & 0xff00) | ((addr & 0x001f) << 3) | ((addr >> 5) & 7); break; + case 2: addr = (addr & 0xfe00) | ((addr & 0x003f) << 3) | ((addr >> 6) & 7); break; + case 3: addr = (addr & 0xfc00) | ((addr & 0x007f) << 3) | ((addr >> 7) & 7); break; } return (addr << 1); } @@ -695,7 +694,8 @@ uint8 bPPU::mmio_r213d() { uint8 bPPU::mmio_r213e() { uint8 r = 0x00; r |= (regs.time_over) ? 0x80 : 0x00; - r |= (regs.range_over) ? 0x40 : 0x00; + r |= (regs.range_over) ? 0x40 : 0x00; + r |= (regs.ppu1_mdr & 0x10); r |= (ppu1_version & 0x0f); regs.ppu1_mdr = r; return regs.ppu1_mdr; diff --git a/src/ppu/bppu/bppu_render_mode7.cpp b/src/ppu/bppu/bppu_render_mode7.cpp index 720087e7..9d16a8be 100644 --- a/src/ppu/bppu/bppu_render_mode7.cpp +++ b/src/ppu/bppu/bppu_render_mode7.cpp @@ -1,109 +1,106 @@ -/* - bsnes mode7 renderer - - base algorithm written by anomie - bsnes implementation written by byuu - - supports mode 7 + extbg + rotate + zoom + - direct color + scrolling + m7sel + windowing + mosaic - interlace and pseudo-hires support are automatic via main rendering routine -*/ +/***** + * bsnes mode7 renderer + * + * base algorithm written by anomie + * bsnes implementation written by byuu + * + * supports mode 7 + extbg + rotate + zoom + + * direct color + scrolling + m7sel + windowing + mosaic + * interlace and pseudo-hires support are automatic via main rendering routine + *****/ //13-bit sign extend //--s---vvvvvvvvvv -> ssssssvvvvvvvvvv #define CLIP(x) ( ((x) & 0x2000) ? ( (x) | ~0x03ff) : ((x) & 0x03ff) ) void bPPU::render_line_mode7(uint8 bg, uint8 pri0_pos, uint8 pri1_pos) { - if(regs.bg_enabled[bg] == false && regs.bgsub_enabled[bg] == false)return; + if(regs.bg_enabled[bg] == false && regs.bgsub_enabled[bg] == false) return; -//are layers disabled by user? - if(render_enabled(bg, 0) == false)pri0_pos = 0; - if(render_enabled(bg, 1) == false)pri1_pos = 0; -//nothing to render? - if(!pri0_pos && !pri1_pos)return; + //are layers disabled by user? + if(render_enabled(bg, 0) == false) pri0_pos = 0; + if(render_enabled(bg, 1) == false) pri1_pos = 0; -int32 px, py; -int32 tx, ty, tile, palette; + //nothing to render? + if(!pri0_pos && !pri1_pos) return; -int32 a = sclip<16>(regs.m7a); -int32 b = sclip<16>(regs.m7b); -int32 c = sclip<16>(regs.m7c); -int32 d = sclip<16>(regs.m7d); + int32 px, py; + int32 tx, ty, tile, palette; -int32 cx = sclip<13>(regs.m7x); -int32 cy = sclip<13>(regs.m7y); -int32 hofs = sclip<13>(regs.m7_hofs); -int32 vofs = sclip<13>(regs.m7_vofs); + int32 a = sclip<16>(regs.m7a); + int32 b = sclip<16>(regs.m7b); + int32 c = sclip<16>(regs.m7c); + int32 d = sclip<16>(regs.m7d); -int _pri, _x; -bool _bg_enabled = regs.bg_enabled[bg]; -bool _bgsub_enabled = regs.bgsub_enabled[bg]; + int32 cx = sclip<13>(regs.m7x); + int32 cy = sclip<13>(regs.m7y); + int32 hofs = sclip<13>(regs.m7_hofs); + int32 vofs = sclip<13>(regs.m7_vofs); + + int _pri, _x; + bool _bg_enabled = regs.bg_enabled[bg]; + bool _bgsub_enabled = regs.bgsub_enabled[bg]; build_window_tables(bg); -uint8 *wt_main = window[bg].main; -uint8 *wt_sub = window[bg].sub; + uint8 *wt_main = window[bg].main; + uint8 *wt_sub = window[bg].sub; -int32 y = (regs.mode7_vflip == false) ? (line.y) : (255 - line.y); + int32 y = (regs.mode7_vflip == false) ? (line.y) : (255 - line.y); -uint16 *mtable_x, *mtable_y; + uint16 *mtable_x, *mtable_y; if(bg == BG1) { mtable_x = (uint16*)mosaic_table[(regs.mosaic_enabled[BG1] == true) ? regs.mosaic_size : 0]; mtable_y = (uint16*)mosaic_table[(regs.mosaic_enabled[BG1] == true) ? regs.mosaic_size : 0]; } else { //bg == BG2 - //Mode7 EXTBG BG2 uses BG1 mosaic enable to control vertical mosaic, - //and BG2 mosaic enable to control horizontal mosaic... + //Mode7 EXTBG BG2 uses BG1 mosaic enable to control vertical mosaic, + //and BG2 mosaic enable to control horizontal mosaic... mtable_x = (uint16*)mosaic_table[(regs.mosaic_enabled[BG2] == true) ? regs.mosaic_size : 0]; mtable_y = (uint16*)mosaic_table[(regs.mosaic_enabled[BG1] == true) ? regs.mosaic_size : 0]; } -int32 psx = ((a * CLIP(hofs - cx)) & ~63) + ((b * CLIP(vofs - cy)) & ~63) + ((b * mtable_y[y]) & ~63) + (cx << 8); -int32 psy = ((c * CLIP(hofs - cx)) & ~63) + ((d * CLIP(vofs - cy)) & ~63) + ((d * mtable_y[y]) & ~63) + (cy << 8); -//suggestion by TRAC, difference can be no greater than 1 bit (due to rounding) from above, -//but verification would be good... -//int32 psx = ((a * CLIP(hofs - cx)) & ~63) + ((b * (CLIP(vofs - cy) + mtable_y[y])) & ~63) + (cx << 8); -//int32 psy = ((c * CLIP(hofs - cx)) & ~63) + ((d * (CLIP(vofs - cy) + mtable_y[y])) & ~63) + (cy << 8); + int32 psx = ((a * CLIP(hofs - cx)) & ~63) + ((b * CLIP(vofs - cy)) & ~63) + ((b * mtable_y[y]) & ~63) + (cx << 8); + int32 psy = ((c * CLIP(hofs - cx)) & ~63) + ((d * CLIP(vofs - cy)) & ~63) + ((d * mtable_y[y]) & ~63) + (cy << 8); for(int32 x = 0; x < 256; x++) { px = psx + (a * mtable_x[x]); py = psy + (c * mtable_x[x]); - //mask floating-point bits (low 8 bits) + //mask floating-point bits (low 8 bits) px >>= 8; py >>= 8; switch(regs.mode7_repeat) { - case 0: //screen repitition outside of screen area - case 1: //same as case 0 - px &= 1023; - py &= 1023; - tx = ((px >> 3) & 127); - ty = ((py >> 3) & 127); - tile = vram[(ty * 128 + tx) << 1]; - palette = vram[(((tile << 6) + ((py & 7) << 3) + (px & 7)) << 1) + 1]; - break; - case 2: //palette color 0 outside of screen area - if(px < 0 || px > 1023 || py < 0 || py > 1023) { - palette = 0; - } else { + case 0: //screen repitition outside of screen area + case 1: { //same as case 0 px &= 1023; py &= 1023; tx = ((px >> 3) & 127); ty = ((py >> 3) & 127); tile = vram[(ty * 128 + tx) << 1]; palette = vram[(((tile << 6) + ((py & 7) << 3) + (px & 7)) << 1) + 1]; - } - break; - case 3: //character 0 repetition outside of screen area - if(px < 0 || px > 1023 || py < 0 || py > 1023) { - tile = 0; - } else { - px &= 1023; - py &= 1023; - tx = ((px >> 3) & 127); - ty = ((py >> 3) & 127); - tile = vram[(ty * 128 + tx) << 1]; - } - palette = vram[(((tile << 6) + ((py & 7) << 3) + (px & 7)) << 1) + 1]; - break; + } break; + case 2: { //palette color 0 outside of screen area + if(px < 0 || px > 1023 || py < 0 || py > 1023) { + palette = 0; + } else { + px &= 1023; + py &= 1023; + tx = ((px >> 3) & 127); + ty = ((py >> 3) & 127); + tile = vram[(ty * 128 + tx) << 1]; + palette = vram[(((tile << 6) + ((py & 7) << 3) + (px & 7)) << 1) + 1]; + } + } break; + case 3: { //character 0 repetition outside of screen area + if(px < 0 || px > 1023 || py < 0 || py > 1023) { + tile = 0; + } else { + px &= 1023; + py &= 1023; + tx = ((px >> 3) & 127); + ty = ((py >> 3) & 127); + tile = vram[(ty * 128 + tx) << 1]; + } + palette = vram[(((tile << 6) + ((py & 7) << 3) + (px & 7)) << 1) + 1]; + } break; } if(bg == BG1) { @@ -113,13 +110,13 @@ int32 psy = ((c * CLIP(hofs - cx)) & ~63) + ((d * CLIP(vofs - cy)) & ~63) + ((d palette &= 0x7f; } - if(!palette)continue; + if(!palette) continue; _x = (regs.mode7_hflip == false) ? (x) : (255 - x); - uint32 col; + uint32 col; if(regs.direct_color == true && bg == BG1) { - //direct color mode does not apply to bg2, as it is only 128 colors... + //direct color mode does not apply to bg2, as it is only 128 colors... col = get_direct_color(0, palette); } else { col = get_palette(palette); diff --git a/src/smp/iplrom.h b/src/smp/iplrom.h index d78aa905..58bccbd9 100644 --- a/src/smp/iplrom.h +++ b/src/smp/iplrom.h @@ -37,5 +37,5 @@ const uint8 SMP::iplrom[64] = { /*fff8*/ 0x5d, //mov x,a /*fff9*/ 0xd0, 0xdb, //bne $ffd6 /*fffb*/ 0x1f, 0x00, 0x00, //jmp ($0000+x) -/*fffe*/ 0xc0, 0xff //---reset vector location ($ffc0) +/*fffe*/ 0xc0, 0xff //reset vector location ($ffc0) }; diff --git a/src/snes/audio/audio.cpp b/src/snes/audio/audio.cpp index 7bb08930..e6469b28 100644 --- a/src/snes/audio/audio.cpp +++ b/src/snes/audio/audio.cpp @@ -1,9 +1,10 @@ +//TODO: move audio logging code to SNESInterface class + void SNES::audio_update(uint16 l_sample, uint16 r_sample) { if(pcmfp) { fput(pcmfp, l_sample, 2); fput(pcmfp, r_sample, 2); } - if(config::snes.mute == true) { l_sample = r_sample = 0x0000; } snesinterface.audio_sample(l_sample, r_sample); } diff --git a/src/snes/scheduler/scheduler.cpp b/src/snes/scheduler/scheduler.cpp index d31d695b..6120a23f 100644 --- a/src/snes/scheduler/scheduler.cpp +++ b/src/snes/scheduler/scheduler.cpp @@ -11,14 +11,14 @@ void threadentry_dsp() { dsp.enter(); } void Scheduler::enter() { switch(clock.active) { - case THREAD_CPU: co_switch(thread_cpu); break; - case THREAD_SMP: co_switch(thread_smp); break; - case THREAD_PPU: co_switch(thread_ppu); break; - case THREAD_DSP: co_switch(thread_dsp); break; + case THREAD_CPU: co_switch(thread_cpu); break; + case THREAD_SMP: co_switch(thread_smp); break; + case THREAD_PPU: co_switch(thread_ppu); break; + case THREAD_DSP: co_switch(thread_dsp); break; } } -void Scheduler::exit() { +void Scheduler::exit() { co_switch(thread_snes); } @@ -28,17 +28,18 @@ void Scheduler::init() { config::cpu.pal_clock_rate; clock.smp_freq = snes.region() == SNES::NTSC ? config::smp.ntsc_clock_rate : - config::smp.pal_clock_rate; + config::smp.pal_clock_rate; + clock.smp_freq &= ~7; //smp_freq must be divisible by eight for dsp_freq clock.dsp_freq = clock.smp_freq >> 3; clock.active = THREAD_CPU; clock.cpusmp = 0; clock.smpdsp = 0; - if(thread_cpu)co_delete(thread_cpu); - if(thread_smp)co_delete(thread_smp); - if(thread_ppu)co_delete(thread_ppu); - if(thread_dsp)co_delete(thread_dsp); + if(thread_cpu) co_delete(thread_cpu); + if(thread_smp) co_delete(thread_smp); + if(thread_ppu) co_delete(thread_ppu); + if(thread_dsp) co_delete(thread_dsp); thread_snes = co_active(); thread_cpu = co_create(sizeof(void*) * 64 * 1024, threadentry_cpu); diff --git a/src/snes/snes.cpp b/src/snes/snes.cpp index 8e5f2281..de5a1357 100644 --- a/src/snes/snes.cpp +++ b/src/snes/snes.cpp @@ -1,10 +1,11 @@ -#include "../base.h" +#include "../base.h" + +cothread_t co_active_ = 0; SNES snes; BSXBase bsxbase; BSXCart bsxcart; BSXFlash bsxflash; -SuperFX superfx; SRTC srtc; SDD1 sdd1; Cx4 cx4; @@ -32,7 +33,6 @@ void SNES::init() { bsxbase.init(); bsxcart.init(); bsxflash.init(); - superfx.init(); srtc.init(); sdd1.init(); cx4.init(); @@ -66,7 +66,6 @@ void SNES::power() { if(cartridge.info.bsxbase) bsxbase.power(); if(cartridge.info.bsxcart) bsxcart.power(); if(cartridge.info.bsxflash) bsxflash.power(); - if(cartridge.info.superfx) superfx.power(); if(cartridge.info.srtc) srtc.power(); if(cartridge.info.sdd1) sdd1.power(); if(cartridge.info.cx4) cx4.power(); @@ -87,7 +86,6 @@ void SNES::power() { if(cartridge.info.bsxbase) bsxbase.enable(); if(cartridge.info.bsxcart) bsxcart.enable(); if(cartridge.info.bsxflash) bsxflash.enable(); - if(cartridge.info.superfx) superfx.enable(); if(cartridge.info.srtc) srtc.enable(); if(cartridge.info.sdd1) sdd1.enable(); if(cartridge.info.cx4) cx4.enable(); @@ -113,7 +111,6 @@ void SNES::reset() { if(cartridge.info.bsxbase) bsxbase.reset(); if(cartridge.info.bsxcart) bsxcart.reset(); if(cartridge.info.bsxflash) bsxflash.reset(); - if(cartridge.info.superfx) superfx.reset(); if(cartridge.info.srtc) srtc.reset(); if(cartridge.info.sdd1) sdd1.reset(); if(cartridge.info.cx4) cx4.reset(); diff --git a/src/ui/config.cpp b/src/ui/config.cpp index a670bf26..a82f40b9 100644 --- a/src/ui/config.cpp +++ b/src/ui/config.cpp @@ -3,96 +3,117 @@ namespace config { char filename[PATH_MAX + 16] = "bsnes.cfg"; struct System { - static StringSetting video, audio, input; - static IntegerSetting regulate_speed, speed; + static string_setting video, audio, input; + static integral_setting regulate_speed, speed; } system; -StringSetting System::video(&config(), "system.video", "Video hardware interface", ""); -StringSetting System::audio(&config(), "system.audio", "Audio hardware interface", ""); -StringSetting System::input(&config(), "system.input", "Input hardware interface", ""); +string_setting System::video(config(), "system.video", "Video hardware interface", ""); +string_setting System::audio(config(), "system.audio", "Audio hardware interface", ""); +string_setting System::input(config(), "system.input", "Input hardware interface", ""); -IntegerSetting System::regulate_speed(&config(), "system.regulate_speed", "Regulate speed to 60hz (NTSC) / 50hz (PAL)", IntegerSetting::Boolean, true); -IntegerSetting System::speed(0, "system.speed", "Current speed regulation setting (1-5)", IntegerSetting::Decimal, 3); +integral_setting System::regulate_speed(config(), "system.regulate_speed", "Regulate speed to 60hz (NTSC) / 50hz (PAL)", integral_setting::boolean, true); +integral_setting System::speed("system.speed", "Current speed regulation setting (1-5)", integral_setting::decimal, 3); struct Video { - static IntegerSetting mode; + static integral_setting mode; struct Windowed { - static IntegerSetting synchronize, aspect_correction; - static IntegerSetting region, multiplier, hardware_filter, software_filter; + static integral_setting synchronize, aspect_correction; + static integral_setting region, multiplier, hardware_filter, software_filter; } windowed; struct Fullscreen { - static IntegerSetting synchronize, aspect_correction; - static IntegerSetting region, multiplier, hardware_filter, software_filter; + static integral_setting synchronize, aspect_correction; + static integral_setting region, multiplier, hardware_filter, software_filter; } fullscreen; - static IntegerSetting aspect_ntsc_x, aspect_ntsc_y, aspect_pal_x, aspect_pal_y; - static IntegerSetting frameskip; - static IntegerSetting use_vram; + static integral_setting aspect_ntsc_x, aspect_ntsc_y, aspect_pal_x, aspect_pal_y; + static integral_setting frameskip; + static integral_setting use_vram; } video; //0 = windowed, 1 = fullscreen, 2 = exclusive -IntegerSetting Video::mode(0, "video.mode", "Active video mode", IntegerSetting::Decimal, 0); +integral_setting Video::mode("video.mode", "Active video mode", integral_setting::decimal, 0); -IntegerSetting Video::Windowed::synchronize(&config(), "video.windowed.synchronize", "Synchronize to video refresh rate", IntegerSetting::Boolean, false); -IntegerSetting Video::Windowed::aspect_correction(&config(), "video.windowed.aspect_correction", +integral_setting Video::Windowed::synchronize(config(), "video.windowed.synchronize", "Synchronize to video refresh rate", integral_setting::boolean, false); +integral_setting Video::Windowed::aspect_correction(config(), "video.windowed.aspect_correction", "Correct video aspect ratio\n" "Defaults assume display pixels are perfectly square\n" "Formula: width = width * video.aspect__x / video.aspect__y\n", - IntegerSetting::Boolean, true); -IntegerSetting Video::Windowed::region(&config(), "video.windowed.region", "Video output region\n" + integral_setting::boolean, true); +integral_setting Video::Windowed::region(config(), "video.windowed.region", "Video output region\n" "0 = NTSC, 1 = PAL", - IntegerSetting::Decimal, 0); -IntegerSetting Video::Windowed::multiplier(&config(), "video.windowed.multiplier", "Video output size multiplier (1-5x)\n" + integral_setting::decimal, 0); +integral_setting Video::Windowed::multiplier(config(), "video.windowed.multiplier", "Video output size multiplier (1-5x)\n" "1 = 1x (<= 320x240)\n" "2 = 2x (<= 640x480)\n" "etc.", - IntegerSetting::Decimal, 2); -IntegerSetting Video::Windowed::hardware_filter(&config(), "video.windowed.hardware_filter", "Video hardware filter\n" + integral_setting::decimal, 2); +integral_setting Video::Windowed::hardware_filter(config(), "video.windowed.hardware_filter", "Video hardware filter\n" "0 = Point\n" "1 = Linear\n", - IntegerSetting::Decimal, 1); -IntegerSetting Video::Windowed::software_filter(&config(), "video.windowed.software_filter", "Video software filter\n" + integral_setting::decimal, 1); +integral_setting Video::Windowed::software_filter(config(), "video.windowed.software_filter", "Video software filter\n" "0 = None\n" "1 = NTSC\n" "2 = HQ2x\n" "3 = Scale2x\n", - IntegerSetting::Decimal, 0); + integral_setting::decimal, 0); -IntegerSetting Video::Fullscreen::synchronize (&config(), "video.fullscreen.synchronize", "", IntegerSetting::Boolean, false); -IntegerSetting Video::Fullscreen::aspect_correction(&config(), "video.fullscreen.aspect_correction", "", IntegerSetting::Boolean, true); -IntegerSetting Video::Fullscreen::region (&config(), "video.fullscreen.region", "", IntegerSetting::Decimal, 0); -IntegerSetting Video::Fullscreen::multiplier (&config(), "video.fullscreen.multiplier", "", IntegerSetting::Decimal, 2); -IntegerSetting Video::Fullscreen::hardware_filter (&config(), "video.fullscreen.hardware_filter", "", IntegerSetting::Decimal, 1); -IntegerSetting Video::Fullscreen::software_filter (&config(), "video.fullscreen.software_filter", "", IntegerSetting::Decimal, 0); +integral_setting Video::Fullscreen::synchronize (config(), "video.fullscreen.synchronize", "", integral_setting::boolean, false); +integral_setting Video::Fullscreen::aspect_correction(config(), "video.fullscreen.aspect_correction", "", integral_setting::boolean, true); +integral_setting Video::Fullscreen::region (config(), "video.fullscreen.region", "", integral_setting::decimal, 0); +integral_setting Video::Fullscreen::multiplier (config(), "video.fullscreen.multiplier", "", integral_setting::decimal, 2); +integral_setting Video::Fullscreen::hardware_filter (config(), "video.fullscreen.hardware_filter", "", integral_setting::decimal, 1); +integral_setting Video::Fullscreen::software_filter (config(), "video.fullscreen.software_filter", "", integral_setting::decimal, 0); -IntegerSetting Video::aspect_ntsc_x(&config(), "video.aspect_ntsc_x", "", IntegerSetting::Decimal, 54); -IntegerSetting Video::aspect_ntsc_y(&config(), "video.aspect_ntsc_y", "", IntegerSetting::Decimal, 47); -IntegerSetting Video::aspect_pal_x (&config(), "video.aspect_pal_x", "", IntegerSetting::Decimal, 32); -IntegerSetting Video::aspect_pal_y (&config(), "video.aspect_pal_y", "", IntegerSetting::Decimal, 23); +integral_setting Video::aspect_ntsc_x(config(), "video.aspect_ntsc_x", "", integral_setting::decimal, 54); +integral_setting Video::aspect_ntsc_y(config(), "video.aspect_ntsc_y", "", integral_setting::decimal, 47); +integral_setting Video::aspect_pal_x (config(), "video.aspect_pal_x", "", integral_setting::decimal, 32); +integral_setting Video::aspect_pal_y (config(), "video.aspect_pal_y", "", integral_setting::decimal, 23); -IntegerSetting Video::frameskip(0, "video.frameskip", "Video frameskip", IntegerSetting::Decimal, 0); -IntegerSetting Video::use_vram(&config(), "video.use_vram", "Use Video RAM instead of System RAM when possible", IntegerSetting::Boolean, true); +integral_setting Video::frameskip("video.frameskip", "Video frameskip", integral_setting::decimal, 0); +integral_setting Video::use_vram(config(), "video.use_vram", "Use Video RAM instead of System RAM when possible", integral_setting::boolean, true); struct Audio { - static IntegerSetting synchronize; - static IntegerSetting frequency; + static integral_setting synchronize; + static integral_setting frequency; + static integral_setting mute; } audio; -IntegerSetting Audio::synchronize(&config(), "audio.synchronize", "Synchronize to audio sample rate.", IntegerSetting::Boolean, true); -IntegerSetting Audio::frequency(&config(), "audio.frequency", "Default audio playback frequency.", IntegerSetting::Decimal, 32000); +integral_setting Audio::synchronize(config(), "audio.synchronize", "Synchronize to audio sample rate", integral_setting::boolean, true); +integral_setting Audio::frequency(config(), "audio.frequency", "Default audio playback frequency", integral_setting::decimal, 32000); +integral_setting Audio::mute(config(), "audio.mute", "Mute audio playback", integral_setting::boolean, false); -struct Input { - static IntegerSetting axis_resistance; - static IntegerSetting allow_invalid_input; +struct Input { + static integral_setting capture_mode; + static integral_setting axis_resistance; + static integral_setting allow_invalid_input; struct Joypad1 { - static StringSetting up, down, left, right, a, b, x, y, l, r, select, start; + static string_setting up, down, left, right, a, b, x, y, l, r, select, start; } joypad1; struct Joypad2 { - static StringSetting up, down, left, right, a, b, x, y, l, r, select, start; - } joypad2; -} input; + static string_setting up, down, left, right, a, b, x, y, l, r, select, start; + } joypad2; + + struct GUI { + static string_setting load; + static string_setting pause; + static string_setting reset; + static string_setting power; + static string_setting toggle_fullscreen; + static string_setting toggle_menubar; + static string_setting toggle_statusbar; + } gui; +} input; + +integral_setting Input::capture_mode(config(), "input.capture_mode", + "Capture method for input to main emulation window\n" + "When emulation window does not have focus:\n" + "0 = Allow input\n" + "1 = Ignore input\n" + "2 = Pause emulator", + integral_setting::decimal, 2); -IntegerSetting Input::axis_resistance(&config(), "input.axis_resistance", +integral_setting Input::axis_resistance(config(), "input.axis_resistance", "Axis resistance for all analog joypads\n" "Affects responsiveness of analog stick movement by specifying what percentage\n" "in any given direction the axis must be pressed to trigger a button press.\n" @@ -102,42 +123,50 @@ IntegerSetting Input::axis_resistance(&config(), "input.axis_resistance", "up to 100 (axis must be pressed fully to given corner).\n" "Value affects all four directions of the axis equally.\n" "Note: Values below 10 or above 90 are not recommended and may not work at all.", - IntegerSetting::Decimal, 75); + integral_setting::decimal, 75); -IntegerSetting Input::allow_invalid_input(&config(), "input.allow_invalid_input", +integral_setting Input::allow_invalid_input(config(), "input.allow_invalid_input", "Allow up+down and left+right combinations (not recommended)", - IntegerSetting::Boolean, false); + integral_setting::boolean, false); -StringSetting Input::Joypad1::up (&config(), "input.joypad1.up", "", "up"); -StringSetting Input::Joypad1::down (&config(), "input.joypad1.down", "", "down"); -StringSetting Input::Joypad1::left (&config(), "input.joypad1.left", "", "left"); -StringSetting Input::Joypad1::right (&config(), "input.joypad1.right", "", "right"); -StringSetting Input::Joypad1::a (&config(), "input.joypad1.a", "", "x"); -StringSetting Input::Joypad1::b (&config(), "input.joypad1.b", "", "z"); -StringSetting Input::Joypad1::x (&config(), "input.joypad1.x", "", "s"); -StringSetting Input::Joypad1::y (&config(), "input.joypad1.y", "", "a"); -StringSetting Input::Joypad1::l (&config(), "input.joypad1.l", "", "d"); -StringSetting Input::Joypad1::r (&config(), "input.joypad1.r", "", "c"); -StringSetting Input::Joypad1::select(&config(), "input.joypad1.select", "", "rshift"); -StringSetting Input::Joypad1::start (&config(), "input.joypad1.start", "", "enter"); +string_setting Input::Joypad1::up (config(), "input.joypad1.up", "", "up"); +string_setting Input::Joypad1::down (config(), "input.joypad1.down", "", "down"); +string_setting Input::Joypad1::left (config(), "input.joypad1.left", "", "left"); +string_setting Input::Joypad1::right (config(), "input.joypad1.right", "", "right"); +string_setting Input::Joypad1::a (config(), "input.joypad1.a", "", "x"); +string_setting Input::Joypad1::b (config(), "input.joypad1.b", "", "z"); +string_setting Input::Joypad1::x (config(), "input.joypad1.x", "", "s"); +string_setting Input::Joypad1::y (config(), "input.joypad1.y", "", "a"); +string_setting Input::Joypad1::l (config(), "input.joypad1.l", "", "d"); +string_setting Input::Joypad1::r (config(), "input.joypad1.r", "", "c"); +string_setting Input::Joypad1::select(config(), "input.joypad1.select", "", "rshift"); +string_setting Input::Joypad1::start (config(), "input.joypad1.start", "", "return"); -StringSetting Input::Joypad2::up (&config(), "input.joypad2.up", "", "t"); -StringSetting Input::Joypad2::down (&config(), "input.joypad2.down", "", "g"); -StringSetting Input::Joypad2::left (&config(), "input.joypad2.left", "", "f"); -StringSetting Input::Joypad2::right (&config(), "input.joypad2.right", "", "h"); -StringSetting Input::Joypad2::a (&config(), "input.joypad2.a", "", "k"); -StringSetting Input::Joypad2::b (&config(), "input.joypad2.b", "", "j"); -StringSetting Input::Joypad2::x (&config(), "input.joypad2.x", "", "i"); -StringSetting Input::Joypad2::y (&config(), "input.joypad2.y", "", "u"); -StringSetting Input::Joypad2::l (&config(), "input.joypad2.l", "", "o"); -StringSetting Input::Joypad2::r (&config(), "input.joypad2.r", "", "l"); -StringSetting Input::Joypad2::select(&config(), "input.joypad2.select", "", "lbracket"); -StringSetting Input::Joypad2::start (&config(), "input.joypad2.start", "", "rbracket"); +string_setting Input::Joypad2::up (config(), "input.joypad2.up", "", "t"); +string_setting Input::Joypad2::down (config(), "input.joypad2.down", "", "g"); +string_setting Input::Joypad2::left (config(), "input.joypad2.left", "", "f"); +string_setting Input::Joypad2::right (config(), "input.joypad2.right", "", "h"); +string_setting Input::Joypad2::a (config(), "input.joypad2.a", "", "k"); +string_setting Input::Joypad2::b (config(), "input.joypad2.b", "", "j"); +string_setting Input::Joypad2::x (config(), "input.joypad2.x", "", "i"); +string_setting Input::Joypad2::y (config(), "input.joypad2.y", "", "u"); +string_setting Input::Joypad2::l (config(), "input.joypad2.l", "", "o"); +string_setting Input::Joypad2::r (config(), "input.joypad2.r", "", "l"); +string_setting Input::Joypad2::select(config(), "input.joypad2.select", "", "lbracket"); +string_setting Input::Joypad2::start (config(), "input.joypad2.start", "", "rbracket"); + +string_setting Input::GUI::load (config(), "input.gui.load", "", "none"); +string_setting Input::GUI::pause (config(), "input.gui.pause", "", "f12"); +string_setting Input::GUI::reset (config(), "input.gui.reset", "", "none"); +string_setting Input::GUI::power (config(), "input.gui.power", "", "none"); +string_setting Input::GUI::toggle_fullscreen(config(), "input.gui.toggle_fullscreen", "", "f11"); +string_setting Input::GUI::toggle_menubar (config(), "input.gui.toggle_menubar", "", "escape"); +string_setting Input::GUI::toggle_statusbar (config(), "input.gui.toggle_statusbar", "", "escape"); struct Misc { - static IntegerSetting show_frame_counter; + static integral_setting show_status; } misc; -IntegerSetting Misc::show_frame_counter(&config(), "misc.show_frame_counter", "Display frame counter", IntegerSetting::Boolean, true); +integral_setting Misc::show_status(config(), "misc.show_status", "Display information statusbar", integral_setting::boolean, true); }; diff --git a/src/ui/miu/event.cpp b/src/ui/event.cpp similarity index 59% rename from src/ui/miu/event.cpp rename to src/ui/event.cpp index 70a10036..d51e1490 100644 --- a/src/ui/miu/event.cpp +++ b/src/ui/event.cpp @@ -1,263 +1,327 @@ -namespace event { - -void load_video_settings() { - video_settings.mode = config::video.mode; - switch(video_settings.mode) { default: - case 0: //windowed - video_settings.aspect_correction = config::video.windowed.aspect_correction; - video_settings.synchronize = config::video.windowed.synchronize; - video_settings.region = config::video.windowed.region; - video_settings.multiplier = config::video.windowed.multiplier; - video_settings.hardware_filter = config::video.windowed.hardware_filter; - video_settings.software_filter = config::video.windowed.software_filter; - break; - case 1: //fullscreen - video_settings.aspect_correction = config::video.fullscreen.aspect_correction; - video_settings.synchronize = config::video.fullscreen.synchronize; - video_settings.region = config::video.fullscreen.region; - video_settings.multiplier = config::video.fullscreen.multiplier; - video_settings.hardware_filter = config::video.fullscreen.hardware_filter; - video_settings.software_filter = config::video.fullscreen.software_filter; - break; - } -} - -void update_aspect_correction(bool aspect_correction) { - switch(config::video.mode) { default: - case 0: config::video.windowed.aspect_correction = aspect_correction; break; - case 1: config::video.fullscreen.aspect_correction = aspect_correction; break; - } - update_video_settings(); -} - -void update_multiplier(uint multiplier) { - switch(config::video.mode) { default: - case 0: config::video.windowed.multiplier = multiplier; break; - case 1: config::video.fullscreen.multiplier = multiplier; break; - } - update_video_settings(); -} - -void update_region(uint region) { - switch(config::video.mode) { default: - case 0: config::video.windowed.region = region; break; - case 1: config::video.fullscreen.region = region; break; - } - update_video_settings(); -} - -void update_hardware_filter(uint hardware_filter) { - switch(config::video.mode) { default: - case 0: config::video.windowed.hardware_filter = hardware_filter; break; - case 1: config::video.fullscreen.hardware_filter = hardware_filter; break; - } - update_video_settings(); -} - -void update_software_filter(uint software_filter) { - switch(config::video.mode) { default: - case 0: config::video.windowed.software_filter = software_filter; break; - case 1: config::video.fullscreen.software_filter = software_filter; break; - } - update_video_settings(); -} - -void update_speed_regulation(uint speed) { - config::system.speed = max(1, min(speed, 5)); - if(uiAudio && uiAudio->cap(Audio::Frequency)) { - switch(config::system.speed) { - case 1: uiAudio->set(Audio::Frequency, 16000); break; - case 2: uiAudio->set(Audio::Frequency, 24000); break; - case 3: uiAudio->set(Audio::Frequency, 32000); break; - case 4: uiAudio->set(Audio::Frequency, 48000); break; - case 5: uiAudio->set(Audio::Frequency, 64000); break; - } - } -} - -void update_frame_counter() { - if(ppu.status.frames_updated) { - ppu.status.frames_updated = false; - if(config::misc.show_frame_counter == true) { - window_main.set_text(string() << BSNES_TITLE << " [" << ppu.status.frames_executed << "]"); - } - } -} - -void update_video_settings() { - load_video_settings(); - -uint width = 256; -uint height = video_settings.region == 0 ? 224 : 239; -uint multiplier = minmax<1, 5>(video_settings.multiplier); - width *= multiplier; - height *= multiplier; - if(video_settings.aspect_correction == true) { - if(video_settings.region == 0) { //NTSC - width = uint( double(width) * double(config::video.aspect_ntsc_x) / double(config::video.aspect_ntsc_y) ); - } else { //PAL - width = uint( double(width) * double(config::video.aspect_pal_x) / double(config::video.aspect_pal_y) ); - } - } - - switch(video_settings.mode) { default: - case 0: { //windowed - window_main.unfullscreen(); - window_main.resize(width, height); - window_main.move(window_main.view, 0, 0); - window_main.view.resize(width, height); - } break; - case 1: { //fullscreen - window_main.fullscreen(); - window_main.move(window_main.view, - (miu().screen_width() - width) / 2, - (miu().screen_height() - height) / 2); - window_main.view.resize(width, height); - } break; - } - -uint filter, standard; - switch(video_settings.software_filter) { default: - case 0: filter = VIDEOFILTER_DIRECT; break; - case 1: filter = VIDEOFILTER_NTSC; break; - case 2: filter = VIDEOFILTER_HQ2X; break; - case 3: filter = VIDEOFILTER_SCALE2X; break; - } - - switch(video_settings.region) { default: - case 0: standard = SNES::VIDEOSTANDARD_NTSC; break; - case 1: standard = SNES::VIDEOSTANDARD_PAL; break; - } - - snes.set_video_filter(filter); - snes.set_video_standard(standard); - - if(uiVideo) { - uiVideo->set(Video::Synchronize, video_settings.synchronize); - uiVideo->set(Video::Filter, video_settings.hardware_filter); - } - -//update main window video mode checkbox settings - window_main.update_menu_settings(); -} - -void toggle_menu() { - window_main.menu_show(!window_main.menu_visible()); - update_video_settings(); -} - -void toggle_fullscreen() { - if(config::video.mode != 1) { //switch to fullscreen mode if not already in it - config::video.mode = 1; - } else { //switch to windowed mode if already in fullscreen mode - config::video.mode = 0; - } - update_video_settings(); -} - -// - -bool load_rom(char *fn) { -lstring dir; - strcpy(fn, ""); - strcpy(dir[0], config::path.rom); - replace(dir[0], "\\", "/"); - if(strlen(dir[0]) && !strend(dir[0], "/")) strcat(dir[0], "/"); - -//append base path if rom path is relative - if(strbegin(dir[0], "./")) { - ltrim(dir[0], "./"); - strcpy(dir[1], dir[0]); - strcpy(dir[0], config::path.base); - strcat(dir[0], dir[1]); - } - - return miu().file_load(0, fn, - "SNES images;*.smc,*.sfc,*.swc,*.fig,*.bs,*.st" - #if defined(GZIP_SUPPORT) - ",*.gz,*.z,*.zip" - #endif - #if defined(JMA_SUPPORT) - ",*.jma" - #endif - "|All files;*.*", - dir[0]); -} - -void load_rom() { -char fn[PATH_MAX]; - if(load_rom(fn) == false) return; - load_cart_normal(fn); -} - -void load_cart_normal(const char *filename) { - if(!filename || !*filename) return; - - if(cartridge.loaded() == true) cartridge.unload(); - cartridge.load_cart_normal(filename); - -//warn if unsupported hardware detected - if(cartridge.info.superfx) alert("Warning: unsupported SuperFX chip detected."); - if(cartridge.info.sa1) alert("Warning: unsupported SA-1 chip detected."); - if(cartridge.info.st011) alert("Warning: unsupported ST011 chip detected."); - if(cartridge.info.st018) alert("Warning: unsupported ST018 chip detected."); - - snes.power(); - window_cheat_editor.refresh(); -} - -void load_cart_bsx(const char *base, const char *slot) { - if(!base || !*base) return; - - if(cartridge.loaded() == true) cartridge.unload(); - cartridge.load_cart_bsx(base, slot); - - snes.power(); - window_cheat_editor.refresh(); -} - -void load_cart_bsc(const char *base, const char *slot) { - if(!base || !*base) return; - - if(cartridge.loaded() == true) cartridge.unload(); - cartridge.load_cart_bsc(base, slot); - - snes.power(); - window_cheat_editor.refresh(); -} - -void load_cart_st(const char *base, const char *slotA, const char *slotB) { - if(!base || !*base) return; - - if(cartridge.loaded() == true) cartridge.unload(); - cartridge.load_cart_st(base, slotA, slotB); - - snes.power(); - window_cheat_editor.refresh(); -} - -void unload_rom() { - if(cartridge.loaded() == true) { - cartridge.unload(); - uiVideo->clear_video(); - uiAudio->clear_audio(); - } - window_main.set_text(BSNES_TITLE); - window_cheat_editor.refresh(); -} - -void reset() { - if(cartridge.loaded() == true) { - snes.reset(); - dprintf("* Reset"); - } -} - -void power() { - if(cartridge.loaded() == true) { - snes.power(); - dprintf("* Power"); - } -} - -}; +namespace event { + +void keydown(uint16_t key) { + if(window_main.focused()) { + if(key == input_manager.gui.load) load_rom(); + if(key == input_manager.gui.pause) { + _pause_ = !_pause_; //toggle pause state + if(_pause_) { + audio.clear(); + if(cartridge.loaded()) window_main.status.set_text("(Paused)"); + } + } + if(key == input_manager.gui.reset) reset(); + if(key == input_manager.gui.power) power(); + if(key == input_manager.gui.toggle_fullscreen) toggle_fullscreen(); + if(key == input_manager.gui.toggle_menubar) toggle_menubar(); + if(key == input_manager.gui.toggle_statusbar) toggle_statusbar(); + } + + if(window_input_capture.focused()) { + if(window_input_capture.waiting == true) { + if(window_input_capture.locked == false) { + window_input_capture.assign(key); + } + } + } +} + +void keyup(uint16_t key) { + if(window_input_capture.focused()) { + if(window_input_capture.waiting == true) { + if(window_input_capture.locked == true) { + window_input_capture.locked = input.key_down(keyboard::return_) || input.key_down(keyboard::spacebar); + } + } + } +} + +void load_video_settings() { + video_settings.mode = config::video.mode; + switch(video_settings.mode) { default: + case 0: { //windowed + video_settings.aspect_correction = config::video.windowed.aspect_correction; + video_settings.synchronize = config::video.windowed.synchronize; + video_settings.region = config::video.windowed.region; + video_settings.multiplier = config::video.windowed.multiplier; + video_settings.hardware_filter = config::video.windowed.hardware_filter; + video_settings.software_filter = config::video.windowed.software_filter; + } break; + + case 1: { //fullscreen + video_settings.aspect_correction = config::video.fullscreen.aspect_correction; + video_settings.synchronize = config::video.fullscreen.synchronize; + video_settings.region = config::video.fullscreen.region; + video_settings.multiplier = config::video.fullscreen.multiplier; + video_settings.hardware_filter = config::video.fullscreen.hardware_filter; + video_settings.software_filter = config::video.fullscreen.software_filter; + } break; + } +} + +void update_aspect_correction(bool aspect_correction) { + switch(config::video.mode) { default: + case 0: config::video.windowed.aspect_correction = aspect_correction; break; + case 1: config::video.fullscreen.aspect_correction = aspect_correction; break; + } + update_video_settings(); +} + +void update_multiplier(uint multiplier) { + switch(config::video.mode) { default: + case 0: config::video.windowed.multiplier = multiplier; break; + case 1: config::video.fullscreen.multiplier = multiplier; break; + } + update_video_settings(); +} + +void update_region(uint region) { + switch(config::video.mode) { default: + case 0: config::video.windowed.region = region; break; + case 1: config::video.fullscreen.region = region; break; + } + update_video_settings(); +} + +void update_hardware_filter(uint hardware_filter) { + switch(config::video.mode) { default: + case 0: config::video.windowed.hardware_filter = hardware_filter; break; + case 1: config::video.fullscreen.hardware_filter = hardware_filter; break; + } + update_video_settings(); +} + +void update_software_filter(uint software_filter) { + switch(config::video.mode) { default: + case 0: config::video.windowed.software_filter = software_filter; break; + case 1: config::video.fullscreen.software_filter = software_filter; break; + } + update_video_settings(); +} + +void update_speed_regulation(uint speed) { + config::system.speed = max(1U, min(speed, 5U)); + if(audio.cap(Audio::Frequency)) { + switch(config::system.speed) { + case 1: audio.set(Audio::Frequency, 16000); break; + case 2: audio.set(Audio::Frequency, 24000); break; + case 3: audio.set(Audio::Frequency, 32000); break; + case 4: audio.set(Audio::Frequency, 48000); break; + case 5: audio.set(Audio::Frequency, 64000); break; + } + } +} + +void update_frame_counter() { + if(!cartridge.loaded()) { + window_main.status.set_text(""); + return; + } + + if(_pause_ || _autopause_) return; + + if(ppu.status.frames_updated) { + ppu.status.frames_updated = false; + window_main.status.set_text(string() + << (int)ppu.status.frames_executed + << (snes.region() == SNES::NTSC ? " / 60 fps" : " / 50 fps") + ); + } +} + +void update_video_settings() { + load_video_settings(); + +uint width = 256; +uint height = video_settings.region == 0 ? 224 : 239; +uint multiplier = minmax<1, 5>(video_settings.multiplier); + width *= multiplier; + height *= multiplier; + if(video_settings.aspect_correction == true) { + if(video_settings.region == 0) { //NTSC + width = uint( double(width) * double(config::video.aspect_ntsc_x) / double(config::video.aspect_ntsc_y) ); + } else { //PAL + width = uint( double(width) * double(config::video.aspect_pal_x) / double(config::video.aspect_pal_y) ); + } + } + + switch(video_settings.mode) { default: + case 0: { //windowed + window_main.unfullscreen(); + //try and clamp windows larger than the screen to the screen size. + //note that since APIs such as X11 lack the ability to get the full window size + //(with border, etc), this can never be a perfect fit to the screen. + int w = min(width, hiro().screen_width()); + int h = min(height, hiro().screen_height()); + window_main.resize(w, h); + window_main.move(window_main.view, 0, 0); + window_main.view.resize(w, h); + } break; + + case 1: { //fullscreen + window_main.fullscreen(); + int view_width = window_main.get_width(); + int view_height = window_main.get_height(); + window_main.move(window_main.view, + //center view inside window, do not exceed window size + width < view_width ? (view_width - width) / 2 : 0, + height < view_height ? (view_height - height) / 2 : 0 + ); + window_main.view.resize(min(width, view_width), min(height, view_height)); + } break; + } + +uint filter, standard; + switch(video_settings.software_filter) { default: + case 0: filter = VIDEOFILTER_DIRECT; break; + case 1: filter = VIDEOFILTER_NTSC; break; + case 2: filter = VIDEOFILTER_HQ2X; break; + case 3: filter = VIDEOFILTER_SCALE2X; break; + } + + switch(video_settings.region) { default: + case 0: standard = SNES::VIDEOSTANDARD_NTSC; break; + case 1: standard = SNES::VIDEOSTANDARD_PAL; break; + } + + snes.set_video_filter(filter); + snes.set_video_standard(standard); + + video.set(Video::Synchronize, video_settings.synchronize); + video.set(Video::Filter, video_settings.hardware_filter); + +//update main window video mode checkbox settings + window_main.update_menu_settings(); +} + +void toggle_fullscreen() { + if(config::video.mode != 1) { //switch to fullscreen mode if not already in it + config::video.mode = 1; + } else { //switch to windowed mode if already in fullscreen mode + config::video.mode = 0; + } + update_video_settings(); +} + +void toggle_menubar() { + window_main.menu.show(!window_main.menu.visible()); + update_video_settings(); +} + +void toggle_statusbar() { + window_main.status.show(!window_main.status.visible()); + update_video_settings(); +} + +// + +bool load_rom(char *fn) { + audio.clear(); + + lstring dir; + strcpy(fn, ""); + strcpy(dir[0], config::path.rom); + replace(dir[0], "\\", "/"); + if(strlen(dir[0]) && !strend(dir[0], "/")) strcat(dir[0], "/"); + +//append base path if rom path is relative + if(strbegin(dir[0], "./")) { + ltrim(dir[0], "./"); + strcpy(dir[1], dir[0]); + strcpy(dir[0], config::path.base); + strcat(dir[0], dir[1]); + } + + return hiro().file_load(0, fn, + "SNES images;*.smc,*.sfc,*.swc,*.fig,*.bs,*.st" + #if defined(GZIP_SUPPORT) + ",*.gz,*.z,*.zip" + #endif + #if defined(JMA_SUPPORT) + ",*.jma" + #endif + "|All files;*.*", + dir[0]); +} + +void load_rom() { +char fn[PATH_MAX]; + if(load_rom(fn) == false) return; + load_cart_normal(fn); +} + +void load_cart_normal(const char *filename) { + if(!filename || !*filename) return; + + if(cartridge.loaded() == true) cartridge.unload(); + cartridge.load_cart_normal(filename); + +//warn if unsupported hardware detected + if(cartridge.info.superfx) alert("Warning: unsupported SuperFX chip detected."); + if(cartridge.info.sa1) alert("Warning: unsupported SA-1 chip detected."); + if(cartridge.info.st011) alert("Warning: unsupported ST011 chip detected."); + if(cartridge.info.st018) alert("Warning: unsupported ST018 chip detected."); + + _pause_ = false; + snes.power(); + window_cheat_editor.refresh(); +} + +void load_cart_bsx(const char *base, const char *slot) { + if(!base || !*base) return; + + if(cartridge.loaded() == true) cartridge.unload(); + cartridge.load_cart_bsx(base, slot); + + _pause_ = false; + snes.power(); + window_cheat_editor.refresh(); +} + +void load_cart_bsc(const char *base, const char *slot) { + if(!base || !*base) return; + + if(cartridge.loaded() == true) cartridge.unload(); + cartridge.load_cart_bsc(base, slot); + + _pause_ = false; + snes.power(); + window_cheat_editor.refresh(); +} + +void load_cart_st(const char *base, const char *slotA, const char *slotB) { + if(!base || !*base) return; + + if(cartridge.loaded() == true) cartridge.unload(); + cartridge.load_cart_st(base, slotA, slotB); + + _pause_ = false; + snes.power(); + window_cheat_editor.refresh(); +} + +void unload_rom() { + if(cartridge.loaded() == true) { + cartridge.unload(); + video.clear(); + audio.clear(); + } + window_main.status.set_text(""); + window_cheat_editor.refresh(); +} + +void reset() { + if(cartridge.loaded() == true) { + snes.reset(); + dprintf("* Reset"); + } +} + +void power() { + if(cartridge.loaded() == true) { + snes.power(); + dprintf("* Power"); + } +} + +}; diff --git a/src/ui/miu/event.h b/src/ui/event.h similarity index 84% rename from src/ui/miu/event.h rename to src/ui/event.h index 250f414f..2e4b6e27 100644 --- a/src/ui/miu/event.h +++ b/src/ui/event.h @@ -1,4 +1,7 @@ -namespace event { +namespace event { + +void keydown(uint16_t); +void keyup(uint16_t); struct VideoSettings { uint mode; @@ -20,9 +23,10 @@ void update_software_filter(uint); void update_speed_regulation(uint); void update_frame_counter(); -void update_video_settings(); -void toggle_menu(); +void update_video_settings(); void toggle_fullscreen(); +void toggle_menubar(); +void toggle_statusbar(); bool load_rom(char*); void load_rom(); @@ -34,4 +38,4 @@ void unload_rom(); void reset(); void power(); -}; +} //namespace event diff --git a/src/ui/inputmgr.cpp b/src/ui/inputmgr.cpp index 506c596b..038b8cd1 100644 --- a/src/ui/inputmgr.cpp +++ b/src/ui/inputmgr.cpp @@ -1,144 +1,170 @@ -class InputManager { public: - struct Joypad { - uint16 up, down, left, right, a, b, x, y, l, r, select, start; - } joypad1, joypad2; - struct Joystat { - bool up, down, left, right, a, b, x, y, l, r, select, start; - } joystat1, joystat2; +class InputManager { +public: + struct Joypad { + struct Button { + uint16_t value; + bool state; + } up, down, left, right, a, b, x, y, l, r, select, start; + } joypad1, joypad2; + + struct GUI { + uint16_t load; + uint16_t pause; + uint16_t reset; + uint16_t power; + uint16_t toggle_fullscreen; + uint16_t toggle_menubar; + uint16_t toggle_statusbar; + } gui; - uint16 scan(); void bind(); void poll(); - bool get_status(uint device, uint button); -} input_manager; - -//search all key bindings, return keymap::none if no keys are active -uint16 InputManager::scan() { - uiInput->poll(); - for(uint i = 0; i < keymap::limit; i++) { - if(uiInput->key_down(i)) { return i; } - } - for(uint j = 0; j < 16; j++) { - if(uiInput->key_down(keymap::joypad_flag | (j << 16) | keymap::joypad_up)) { - return (keymap::joypad_flag | (j << 16) | keymap::joypad_up); - } - if(uiInput->key_down(keymap::joypad_flag | (j << 16) | keymap::joypad_down)) { - return (keymap::joypad_flag | (j << 16) | keymap::joypad_down); - } - if(uiInput->key_down(keymap::joypad_flag | (j << 16) | keymap::joypad_left)) { - return (keymap::joypad_flag | (j << 16) | keymap::joypad_left); - } - if(uiInput->key_down(keymap::joypad_flag | (j << 16) | keymap::joypad_right)) { - return (keymap::joypad_flag | (j << 16) | keymap::joypad_right); - } - for(uint i = 0; i < 128; i++) { - if(uiInput->key_down(keymap::joypad_flag | (j << 16) | i)) { - return (keymap::joypad_flag | (j << 16) | i); - } - } - } - return keymap::none; + bool get_status(uint device, uint button); + + void refresh(); + function on_keydown; + function on_keyup; + + InputManager(); + ~InputManager(); + +private: + uint8_t *state; +} input_manager; + +//refresh input state for PC keyboard and joypads +//callbacks can be bound to on_keydown and on_keyup +//callbacks will be invoked whenever input status changes +//this should be called roughly every ~20-50ms +//however, this need not be called if no callbacks are attached +void InputManager::refresh() { + input.poll(); + for(uint i = 0; i < input_limit; i++) { + bool prev_state = state[i]; + state[i] = input.key_down(i); + if(!prev_state && state[i] && on_keydown) on_keydown(i); + if( prev_state && !state[i] && on_keyup ) on_keyup(i); + } } void InputManager::bind() { - joypad1.up = keymap::find(config::input.joypad1.up); - joypad1.down = keymap::find(config::input.joypad1.down); - joypad1.left = keymap::find(config::input.joypad1.left); - joypad1.right = keymap::find(config::input.joypad1.right); - joypad1.a = keymap::find(config::input.joypad1.a); - joypad1.b = keymap::find(config::input.joypad1.b); - joypad1.x = keymap::find(config::input.joypad1.x); - joypad1.y = keymap::find(config::input.joypad1.y); - joypad1.l = keymap::find(config::input.joypad1.l); - joypad1.r = keymap::find(config::input.joypad1.r); - joypad1.select = keymap::find(config::input.joypad1.select); - joypad1.start = keymap::find(config::input.joypad1.start); + joypad1.up.value = input_find(config::input.joypad1.up); + joypad1.down.value = input_find(config::input.joypad1.down); + joypad1.left.value = input_find(config::input.joypad1.left); + joypad1.right.value = input_find(config::input.joypad1.right); + joypad1.a.value = input_find(config::input.joypad1.a); + joypad1.b.value = input_find(config::input.joypad1.b); + joypad1.x.value = input_find(config::input.joypad1.x); + joypad1.y.value = input_find(config::input.joypad1.y); + joypad1.l.value = input_find(config::input.joypad1.l); + joypad1.r.value = input_find(config::input.joypad1.r); + joypad1.select.value = input_find(config::input.joypad1.select); + joypad1.start.value = input_find(config::input.joypad1.start); + + joypad1.up.state = joypad1.down.state = joypad1.left.state = joypad1.right.state = + joypad1.a.state = joypad1.b.state = joypad1.x.state = joypad1.y.state = + joypad1.l.state = joypad1.r.state = joypad1.select.state = joypad1.start.state = + false; - joystat1.up = joystat1.down = joystat1.left = joystat1.right = - joystat1.a = joystat1.b = joystat1.x = joystat1.y = - joystat1.l = joystat1.r = joystat1.select = joystat1.start = false; + joypad2.up.value = input_find(config::input.joypad2.up); + joypad2.down.value = input_find(config::input.joypad2.down); + joypad2.left.value = input_find(config::input.joypad2.left); + joypad2.right.value = input_find(config::input.joypad2.right); + joypad2.a.value = input_find(config::input.joypad2.a); + joypad2.b.value = input_find(config::input.joypad2.b); + joypad2.x.value = input_find(config::input.joypad2.x); + joypad2.y.value = input_find(config::input.joypad2.y); + joypad2.l.value = input_find(config::input.joypad2.l); + joypad2.r.value = input_find(config::input.joypad2.r); + joypad2.select.value = input_find(config::input.joypad2.select); + joypad2.start.value = input_find(config::input.joypad2.start); - joypad2.up = keymap::find(config::input.joypad2.up); - joypad2.down = keymap::find(config::input.joypad2.down); - joypad2.left = keymap::find(config::input.joypad2.left); - joypad2.right = keymap::find(config::input.joypad2.right); - joypad2.a = keymap::find(config::input.joypad2.a); - joypad2.b = keymap::find(config::input.joypad2.b); - joypad2.x = keymap::find(config::input.joypad2.x); - joypad2.y = keymap::find(config::input.joypad2.y); - joypad2.l = keymap::find(config::input.joypad2.l); - joypad2.r = keymap::find(config::input.joypad2.r); - joypad2.select = keymap::find(config::input.joypad2.select); - joypad2.start = keymap::find(config::input.joypad2.start); - - joystat2.up = joystat2.down = joystat2.left = joystat2.right = - joystat2.a = joystat2.b = joystat2.x = joystat2.y = - joystat2.l = joystat2.r = joystat2.select = joystat2.start = false; + joypad2.up.state = joypad2.down.state = joypad2.left.state = joypad2.right.state = + joypad2.a.state = joypad2.b.state = joypad2.x.state = joypad2.y.state = + joypad2.l.state = joypad2.r.state = joypad2.select.state = joypad2.start.state = + false; + + gui.load = input_find(config::input.gui.load); + gui.pause = input_find(config::input.gui.pause); + gui.reset = input_find(config::input.gui.reset); + gui.power = input_find(config::input.gui.power); + gui.toggle_fullscreen = input_find(config::input.gui.toggle_fullscreen); + gui.toggle_menubar = input_find(config::input.gui.toggle_menubar); + gui.toggle_statusbar = input_find(config::input.gui.toggle_statusbar); } void InputManager::poll() { - joystat1.up = uiInput->key_down(joypad1.up); - joystat1.down = uiInput->key_down(joypad1.down); - joystat1.left = uiInput->key_down(joypad1.left); - joystat1.right = uiInput->key_down(joypad1.right); - joystat1.a = uiInput->key_down(joypad1.a); - joystat1.b = uiInput->key_down(joypad1.b); - joystat1.x = uiInput->key_down(joypad1.x); - joystat1.y = uiInput->key_down(joypad1.y); - joystat1.l = uiInput->key_down(joypad1.l); - joystat1.r = uiInput->key_down(joypad1.r); - joystat1.select = uiInput->key_down(joypad1.select); - joystat1.start = uiInput->key_down(joypad1.start); + joypad1.up.state = input.key_down(joypad1.up.value); + joypad1.down.state = input.key_down(joypad1.down.value); + joypad1.left.state = input.key_down(joypad1.left.value); + joypad1.right.state = input.key_down(joypad1.right.value); + joypad1.a.state = input.key_down(joypad1.a.value); + joypad1.b.state = input.key_down(joypad1.b.value); + joypad1.x.state = input.key_down(joypad1.x.value); + joypad1.y.state = input.key_down(joypad1.y.value); + joypad1.l.state = input.key_down(joypad1.l.value); + joypad1.r.state = input.key_down(joypad1.r.value); + joypad1.select.state = input.key_down(joypad1.select.value); + joypad1.start.state = input.key_down(joypad1.start.value); - joystat2.up = uiInput->key_down(joypad2.up); - joystat2.down = uiInput->key_down(joypad2.down); - joystat2.left = uiInput->key_down(joypad2.left); - joystat2.right = uiInput->key_down(joypad2.right); - joystat2.a = uiInput->key_down(joypad2.a); - joystat2.b = uiInput->key_down(joypad2.b); - joystat2.x = uiInput->key_down(joypad2.x); - joystat2.y = uiInput->key_down(joypad2.y); - joystat2.l = uiInput->key_down(joypad2.l); - joystat2.r = uiInput->key_down(joypad2.r); - joystat2.select = uiInput->key_down(joypad2.select); - joystat2.start = uiInput->key_down(joypad2.start); + joypad2.up.state = input.key_down(joypad2.up.value); + joypad2.down.state = input.key_down(joypad2.down.value); + joypad2.left.state = input.key_down(joypad2.left.value); + joypad2.right.state = input.key_down(joypad2.right.value); + joypad2.a.state = input.key_down(joypad2.a.value); + joypad2.b.state = input.key_down(joypad2.b.value); + joypad2.x.state = input.key_down(joypad2.x.value); + joypad2.y.state = input.key_down(joypad2.y.value); + joypad2.l.state = input.key_down(joypad2.l.value); + joypad2.r.state = input.key_down(joypad2.r.value); + joypad2.select.state = input.key_down(joypad2.select.value); + joypad2.start.state = input.key_down(joypad2.start.value); } bool InputManager::get_status(uint device, uint button) { switch(device) { - case SNES::DEVICEID_JOYPAD1: - switch(button) { - case SNES::JOYPAD_UP: return joystat1.up; - case SNES::JOYPAD_DOWN: return joystat1.down; - case SNES::JOYPAD_LEFT: return joystat1.left; - case SNES::JOYPAD_RIGHT: return joystat1.right; - case SNES::JOYPAD_A: return joystat1.a; - case SNES::JOYPAD_B: return joystat1.b; - case SNES::JOYPAD_X: return joystat1.x; - case SNES::JOYPAD_Y: return joystat1.y; - case SNES::JOYPAD_L: return joystat1.l; - case SNES::JOYPAD_R: return joystat1.r; - case SNES::JOYPAD_SELECT: return joystat1.select; - case SNES::JOYPAD_START: return joystat1.start; - } - break; - case SNES::DEVICEID_JOYPAD2: - switch(button) { - case SNES::JOYPAD_UP: return joystat2.up; - case SNES::JOYPAD_DOWN: return joystat2.down; - case SNES::JOYPAD_LEFT: return joystat2.left; - case SNES::JOYPAD_RIGHT: return joystat2.right; - case SNES::JOYPAD_A: return joystat2.a; - case SNES::JOYPAD_B: return joystat2.b; - case SNES::JOYPAD_X: return joystat2.x; - case SNES::JOYPAD_Y: return joystat2.y; - case SNES::JOYPAD_L: return joystat2.l; - case SNES::JOYPAD_R: return joystat2.r; - case SNES::JOYPAD_SELECT: return joystat2.select; - case SNES::JOYPAD_START: return joystat2.start; - } - break; + case SNES::DEVICEID_JOYPAD1: { + switch(button) { + case SNES::JOYPAD_UP: return joypad1.up.state; + case SNES::JOYPAD_DOWN: return joypad1.down.state; + case SNES::JOYPAD_LEFT: return joypad1.left.state; + case SNES::JOYPAD_RIGHT: return joypad1.right.state; + case SNES::JOYPAD_A: return joypad1.a.state; + case SNES::JOYPAD_B: return joypad1.b.state; + case SNES::JOYPAD_X: return joypad1.x.state; + case SNES::JOYPAD_Y: return joypad1.y.state; + case SNES::JOYPAD_L: return joypad1.l.state; + case SNES::JOYPAD_R: return joypad1.r.state; + case SNES::JOYPAD_SELECT: return joypad1.select.state; + case SNES::JOYPAD_START: return joypad1.start.state; + } + } break; + + case SNES::DEVICEID_JOYPAD2: { + switch(button) { + case SNES::JOYPAD_UP: return joypad2.up.state; + case SNES::JOYPAD_DOWN: return joypad2.down.state; + case SNES::JOYPAD_LEFT: return joypad2.left.state; + case SNES::JOYPAD_RIGHT: return joypad2.right.state; + case SNES::JOYPAD_A: return joypad2.a.state; + case SNES::JOYPAD_B: return joypad2.b.state; + case SNES::JOYPAD_X: return joypad2.x.state; + case SNES::JOYPAD_Y: return joypad2.y.state; + case SNES::JOYPAD_L: return joypad2.l.state; + case SNES::JOYPAD_R: return joypad2.r.state; + case SNES::JOYPAD_SELECT: return joypad2.select.state; + case SNES::JOYPAD_START: return joypad2.start.state; + } + } break; } return false; } + +InputManager::InputManager() { + state = new(zeromemory) uint8_t[input_limit]; +} + +InputManager::~InputManager() { + delete[] state; +} diff --git a/src/ui/interface.cpp b/src/ui/interface.cpp index 7952860c..f7b06188 100644 --- a/src/ui/interface.cpp +++ b/src/ui/interface.cpp @@ -10,11 +10,11 @@ SNESInterface snesinterface; //video bool SNESInterface::video_lock(uint16 *&data, uint &pitch) { - return uiVideo->lock(data, pitch); + return video.lock(data, pitch); } void SNESInterface::video_unlock() { - uiVideo->unlock(); + video.unlock(); } static uint frameskip_counter = 0; @@ -23,7 +23,7 @@ void SNESInterface::video_refresh() { if(ppu.renderer_enabled() == true) { SNES::video_info vi; snes.get_video_info(&vi); - uiVideo->refresh(vi.width, vi.height); + video.refresh(vi.width, vi.height); } frameskip_counter++; @@ -33,17 +33,21 @@ void SNESInterface::video_refresh() { //audio -void SNESInterface::audio_sample(uint16 l_sample, uint16 r_sample) { - uiAudio->sample(l_sample, r_sample); +void SNESInterface::audio_sample(uint16 l_sample, uint16 r_sample) { + if(config::audio.mute == true) { + l_sample = 0; + r_sample = 0; + } + audio.sample(l_sample, r_sample); } //input void SNESInterface::input_poll() { if(input_ready && input_ready() == false) { - uiInput->clear_input(); + input.clear(); } else { - uiInput->poll(); + input.poll(); } input_manager.poll(); } diff --git a/src/ui/miu/loader/ui_bsxloader.cpp b/src/ui/loader/ui_bsxloader.cpp similarity index 100% rename from src/ui/miu/loader/ui_bsxloader.cpp rename to src/ui/loader/ui_bsxloader.cpp diff --git a/src/ui/miu/loader/ui_bsxloader.h b/src/ui/loader/ui_bsxloader.h similarity index 100% rename from src/ui/miu/loader/ui_bsxloader.h rename to src/ui/loader/ui_bsxloader.h diff --git a/src/ui/miu/loader/ui_stloader.cpp b/src/ui/loader/ui_stloader.cpp similarity index 100% rename from src/ui/miu/loader/ui_stloader.cpp rename to src/ui/loader/ui_stloader.cpp diff --git a/src/ui/miu/loader/ui_stloader.h b/src/ui/loader/ui_stloader.h similarity index 100% rename from src/ui/miu/loader/ui_stloader.h rename to src/ui/loader/ui_stloader.h diff --git a/src/ui/main.cpp b/src/ui/main.cpp index 7a8e43bd..239fec64 100644 --- a/src/ui/main.cpp +++ b/src/ui/main.cpp @@ -1,34 +1,169 @@ -#define INTERFACE_MAIN - -#include "../base.h" -#include "config.cpp" - -void init_snes(); -void term_snes(); - -/***** - * hardware abstraction layer - *****/ - -#include "vai/video.h" -#include "vai/audio.h" -#include "vai/input.h" - -Video *uiVideo; -Audio *uiAudio; -Input *uiInput; - -#include "inputmgr.cpp" -#include "interface.cpp" - -/***** - * platform abstraction layer - *****/ - -#if defined(UI_MIU) - #include "../lib/miu.h" - using namespace ns_miu; - #include "miu/main.cpp" -#else - #error "unsupported platform" -#endif +#define INTERFACE_MAIN + +#include "../base.h" +#include "config.cpp" + +void init_snes(); +void term_snes(); + +/***** + * hardware abstraction layer + *****/ + +#include +using namespace ruby; + +#include "inputmgr.cpp" +#include "interface.cpp" + +/***** + * platform abstraction layer + *****/ + +#include +using namespace libhiro; + +/***** + * core + *****/ + +bool _term_ = false; +bool _pause_ = false; +bool _autopause_ = false; + +#include "ui.h" +#include "event.h" + +#include "ui.cpp" +#include "event.cpp" + +void alert(const char *s, ...) { + char str[4096]; + va_list args; + va_start(args, s); + vsprintf(str, s, args); + va_end(args); + + window_message.show(str); +} + +void dprintf(const char *s, ...) { + char str[4096]; + va_list args; + va_start(args, s); + vsprintf(str, s, args); + va_end(args); + fprintf(stdout, "%s\r\n", str); +} + +void dprintf(uint source, const char *s, ...) { + char str[4096]; + va_list args; + va_start(args, s); + vsprintf(str, s, args); + va_end(args); + fprintf(stdout, "[%d]: %s\r\n", source, str); +} + +void set_config_filename() { + userpath(config::filename); + strcat(config::filename, "/.bsnes"); + mkdir(config::filename); //always make directory in case it does not exist, fail silently if it does + strcat(config::filename, "/bsnes.cfg"); +} + +void get_base_path(const char *image) { + char full_name[PATH_MAX] = ""; + + #if defined(PLATFORM_WIN) + GetFullPathName(image, PATH_MAX, full_name, 0); + #elif defined(PLATFORM_X) + realpath(image, full_name); + #endif + + string t = full_name; + if(strlen(t) != 0) { + //remove program name + //TODO: rewrite this to be cleaner ... + replace(t, "\\", "/"); + for(int i = strlen(t) - 1; i >= 0; i--) { + if(t()[i] == '/' || t()[i] == '\\') { + t()[i] = 0; + break; + } + } + } + + if(strend(t, "/") == false) { strcat(t, "/"); } + config::path.base = t; +} + +void run() { + while(hiro().pending()) hiro().run(); + input_manager.refresh(); + event::update_frame_counter(); + + if(config::input.capture_mode == 2) { + bool inactive = window_main.focused() == false; + if(_autopause_ == false && inactive == true) { + audio.clear(); + if(cartridge.loaded()) window_main.status.set_text("(Paused)"); + _autopause_ = true; + } else if(_autopause_ == true && inactive == false) { + _autopause_ = false; + } + } else { + _autopause_ = false; + } + + if(cartridge.loaded() == false || _pause_ == true || _autopause_ == true) { + //prevent bsnes from consuming 100% CPU resources when idle + #if defined(PLATFORM_WIN) + Sleep(20); + #elif defined(PLATFORM_X) + usleep(20); + #endif + } else { + snes.runtoframe(); + } +} + +#if defined(PLATFORM_WIN) +int __stdcall WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { +int argc = __argc; +char **argv = __argv; +#else +int main(int argc, char *argv[]) { +#endif +/* +int main(int argc, char *argv[]) { */ + set_config_filename(); + get_base_path(argv[0]); + + hiro().init(); + config::config().load(config::filename); + if(fexists(config::filename) == false) { + //in case program crashes on first run, save config file + //settings, so that they can be modified by hand ... + config::config().save(config::filename); + } + snes.init(); + ui_init(); + + if(argc >= 2) { + cartridge.load_cart_normal(argv[1]); + snes.power(); + } + + while(_term_ == false) { + run(); + } + + event::unload_rom(); + + config::config().save(config::filename); + snes.term(); + ui_term(); + hiro().term(); + return 0; +} diff --git a/src/ui/miu/main.cpp b/src/ui/miu/main.cpp deleted file mode 100644 index e3cfc836..00000000 --- a/src/ui/miu/main.cpp +++ /dev/null @@ -1,127 +0,0 @@ -void run(); -bool _term_ = false; - -#include "ui.h" -#include "event.h" - -#include "ui.cpp" -#include "event.cpp" - -void alert(const char *s, ...) { -char str[4096]; -va_list args; - va_start(args, s); - vsprintf(str, s, args); - va_end(args); -#if defined(PLATFORM_WIN) - MessageBox(0, str, "bsnes", MB_OK); -#else - fprintf(stdout, "%s\r\n", str); -#endif -} - -void dprintf(const char *s, ...) { -char str[4096]; -va_list args; - va_start(args, s); - vsprintf(str, s, args); - va_end(args); - fprintf(stdout, "%s\r\n", str); -} - -void dprintf(uint source, const char *s, ...) { -char str[4096]; -va_list args; - va_start(args, s); - vsprintf(str, s, args); - va_end(args); - fprintf(stdout, "[%d]: %s\r\n", source, str); -} - -void set_config_filename() { - userpath(config::filename); - strcat(config::filename, "/.bsnes"); - mkdir(config::filename); //always make directory in case it does not exist, fail silently if it does - strcat(config::filename, "/bsnes.cfg"); -} - -void get_base_path(const char *image) { -char full_name[PATH_MAX] = ""; - -#if defined(PLATFORM_WIN) - GetFullPathName(image, PATH_MAX, full_name, 0); -#elif defined(PLATFORM_X) - realpath(image, full_name); -#endif - -string t = full_name; - if(strlen(t) != 0) { - //remove program name - //TODO: rewrite this to be cleaner ... - replace(t, "\\", "/"); - for(int i = strlen(t) - 1; i >= 0; i--) { - if(t()[i] == '/' || t()[i] == '\\') { - t()[i] = 0; - break; - } - } - } - - if(strend(t, "/") == false) { strcat(t, "/"); } - config::path.base = t; -} - -void run() { - while(miu().pending()) miu().run(); - - if(cartridge.loaded() == true) { - snes.runtoframe(); - event::update_frame_counter(); - } else { //prevent bsnes from consuming 100% CPU resources when idle - #if defined(PLATFORM_WIN) - Sleep(1); - #elif defined(PLATFORM_X) - usleep(20); - #endif - } -} - -#if defined(PLATFORM_WIN) -int __stdcall WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { -int argc = __argc; -char **argv = __argv; -#else -int main(int argc, char *argv[]) { -#endif - -//int main(int argc, char *argv[]) { - set_config_filename(); - get_base_path(argv[0]); - - miu().init(); - config::config().load(config::filename); - if(fexists(config::filename) == false) { - //in case program crashes on first run, save config file - //settings, so that they can be modified by hand ... - config::config().save(config::filename); - } - snes.init(); - ui_init(); - - if(argc >= 2) { - cartridge.load_cart_normal(argv[1]); - snes.power(); - } - - while(_term_ == false) { - run(); - } - - event::unload_rom(); - - config::config().save(config::filename); - snes.term(); - ui_term(); - miu().term(); - return 0; -} diff --git a/src/ui/miu/settings/ui_inputconfig.cpp b/src/ui/miu/settings/ui_inputconfig.cpp deleted file mode 100644 index d201e42c..00000000 --- a/src/ui/miu/settings/ui_inputconfig.cpp +++ /dev/null @@ -1,214 +0,0 @@ -/* InputConfigWindow */ - -void InputConfigWindow::setup() { - create(0, 475, 355); - - lportA.create(0, 235, 20, "Controller Port A:"); - lportB.create(0, 235, 20, "Controller Port B:"); - - portA.create(0, 235, 30); - portA.add_item("None"); - portA.add_item("Joypad 1"); - portA.add_item("Joypad 2"); - portA.set_selection(1); - portA.disable(); - - portB.create(0, 235, 30); - portB.add_item("None"); - portB.add_item("Joypad 1"); - portB.add_item("Joypad 2"); - portB.set_selection(2); - portB.disable(); - - list.create(Listbox::Header | Listbox::VerticalScrollAlways, 475, 265, "Name\tValue"); - setkey.create(0, 235, 30, "Assign Key"); - setkey.disable(); - clrkey.create(0, 235, 30, "Unassign Key"); - clrkey.disable(); - -uint y = 0; - attach(lportA, 0, y); - attach(lportB, 240, y); y += 20; - attach(portA, 0, y); - attach(portB, 240, y); y += 30 + 5; - attach(list, 0, y); y += 265 + 5; - attach(setkey, 0, y); - attach(clrkey, 240, y); y += 30 + 5; - - list.on_change = bind(&InputConfigWindow::list_change, this); - list.on_activate = bind(&InputConfigWindow::set_tick, this); - setkey.on_tick = bind(&InputConfigWindow::set_tick, this); - clrkey.on_tick = bind(&InputConfigWindow::clr_tick, this); - - for(uint i = 0; i < 24; i++) list.add_item("???\t???"); - refresh_list(); - window_input_capture.setup(); -} - -void InputConfigWindow::refresh_list() { - for(uint i = 0; i < 24; i++) { - list.set_item(i, string() << list_index[i] << "\t" << keymap::find(get_value(i))); - } - list.autosize_columns(); -} - -uintptr_t InputConfigWindow::list_change(Event) { -int pos = list.get_selection(); - setkey.enable(pos >= 0); - clrkey.enable(pos >= 0); - return true; -} - -uintptr_t InputConfigWindow::set_tick(Event) { -int pos = list.get_selection(); - if(pos < 0) return true; - window_input_capture.index = pos; - window_input_capture.label.set_text(string() << "Press a key to assign to " << list_index[pos] << " ..."); - window_input_capture.show(); - return true; -} - -uintptr_t InputConfigWindow::clr_tick(Event) { -int pos = list.get_selection(); - if(pos < 0) return true; - set_value(pos, keymap::none); - refresh_list(); - return true; -} - -/* InputCaptureWindow */ - -void InputCaptureWindow::setup() { - create(Window::AutoCenter, 350, 100, "bsnes Key Capture"); - label.create(0, 340, 90); - attach(label, 5, 5); - on_close = bind(&InputCaptureWindow::close, this); -} - -void InputCaptureWindow::show() { - uiInput->clear_input(); - -//enter and spacebar can be used to activate key capture, -//set lock on these keys if they are held down to prevent -//them from being instantly assigned to selected entry ... - uiInput->poll(); - key_lock = (uiInput->key_down(keymap::enter) || uiInput->key_down(keymap::space)); - Window::focus(); - - while(_term_ == false && visible() == true) { - run(); - uint16 key = input_manager.scan(); - if(key == keymap::none) { key_lock = false; continue; } - if(key_lock && (key == keymap::enter || key == keymap::space)) { continue; } - hide(); - window_input_config.set_value(index, key); - window_input_config.refresh_list(); - break; - } - - uiInput->clear_input(); -} - -uintptr_t InputCaptureWindow::close(Event) { - hide(); - return false; -} - -InputCaptureWindow::InputCaptureWindow() { - index = 0; - key_lock = false; -} - -/* Misc */ - -const char InputConfigWindow::list_index[][64] = { - "Joypad 1 Up", - "Joypad 1 Down", - "Joypad 1 Left", - "Joypad 1 Right", - "Joypad 1 A", - "Joypad 1 B", - "Joypad 1 X", - "Joypad 1 Y", - "Joypad 1 L", - "Joypad 1 R", - "Joypad 1 Select", - "Joypad 1 Start", - - "Joypad 2 Up", - "Joypad 2 Down", - "Joypad 2 Left", - "Joypad 2 Right", - "Joypad 2 A", - "Joypad 2 B", - "Joypad 2 X", - "Joypad 2 Y", - "Joypad 2 L", - "Joypad 2 R", - "Joypad 2 Select", - "Joypad 2 Start", -}; - -uint InputConfigWindow::get_value(uint index) { - switch(index) { - case 0: return keymap::find(config::input.joypad1.up); - case 1: return keymap::find(config::input.joypad1.down); - case 2: return keymap::find(config::input.joypad1.left); - case 3: return keymap::find(config::input.joypad1.right); - case 4: return keymap::find(config::input.joypad1.a); - case 5: return keymap::find(config::input.joypad1.b); - case 6: return keymap::find(config::input.joypad1.x); - case 7: return keymap::find(config::input.joypad1.y); - case 8: return keymap::find(config::input.joypad1.l); - case 9: return keymap::find(config::input.joypad1.r); - case 10: return keymap::find(config::input.joypad1.select); - case 11: return keymap::find(config::input.joypad1.start); - - case 12: return keymap::find(config::input.joypad2.up); - case 13: return keymap::find(config::input.joypad2.down); - case 14: return keymap::find(config::input.joypad2.left); - case 15: return keymap::find(config::input.joypad2.right); - case 16: return keymap::find(config::input.joypad2.a); - case 17: return keymap::find(config::input.joypad2.b); - case 18: return keymap::find(config::input.joypad2.x); - case 19: return keymap::find(config::input.joypad2.y); - case 20: return keymap::find(config::input.joypad2.l); - case 21: return keymap::find(config::input.joypad2.r); - case 22: return keymap::find(config::input.joypad2.select); - case 23: return keymap::find(config::input.joypad2.start); - } - - return keymap::none; -} - -void InputConfigWindow::set_value(uint index, uint16 value) { - switch(index) { - case 0: config::input.joypad1.up = keymap::find(value); break; - case 1: config::input.joypad1.down = keymap::find(value); break; - case 2: config::input.joypad1.left = keymap::find(value); break; - case 3: config::input.joypad1.right = keymap::find(value); break; - case 4: config::input.joypad1.a = keymap::find(value); break; - case 5: config::input.joypad1.b = keymap::find(value); break; - case 6: config::input.joypad1.x = keymap::find(value); break; - case 7: config::input.joypad1.y = keymap::find(value); break; - case 8: config::input.joypad1.l = keymap::find(value); break; - case 9: config::input.joypad1.r = keymap::find(value); break; - case 10: config::input.joypad1.select = keymap::find(value); break; - case 11: config::input.joypad1.start = keymap::find(value); break; - - case 12: config::input.joypad2.up = keymap::find(value); break; - case 13: config::input.joypad2.down = keymap::find(value); break; - case 14: config::input.joypad2.left = keymap::find(value); break; - case 15: config::input.joypad2.right = keymap::find(value); break; - case 16: config::input.joypad2.a = keymap::find(value); break; - case 17: config::input.joypad2.b = keymap::find(value); break; - case 18: config::input.joypad2.x = keymap::find(value); break; - case 19: config::input.joypad2.y = keymap::find(value); break; - case 20: config::input.joypad2.l = keymap::find(value); break; - case 21: config::input.joypad2.r = keymap::find(value); break; - case 22: config::input.joypad2.select = keymap::find(value); break; - case 23: config::input.joypad2.start = keymap::find(value); break; - } - - input_manager.bind(); -} diff --git a/src/ui/miu/ui.cpp b/src/ui/miu/ui.cpp deleted file mode 100644 index 93bb4e5c..00000000 --- a/src/ui/miu/ui.cpp +++ /dev/null @@ -1,114 +0,0 @@ -#include "ui_main.cpp" -#include "ui_about.cpp" - -#include "loader/ui_bsxloader.cpp" -#include "loader/ui_stloader.cpp" - -#include "settings/ui_settings.cpp" -#include "settings/ui_rastersettings.cpp" -#include "settings/ui_inputconfig.cpp" -#include "settings/ui_cheateditor.cpp" -#include "settings/ui_advanced.cpp" - -#if defined(PLATFORM_WIN) - #include "../vai/video/video.direct3d.h" - #include "../vai/video/video.directdraw.h" - #include "../vai/video/video.gdi.h" - #include "../vai/audio/audio.directsound.h" - #include "../vai/input/input.directinput.h" -#elif defined(PLATFORM_X) - #include "../vai/video/video.xv.h" - #include "../vai/video/video.gtk.h" - #include "../vai/audio/audio.ao.h" - #include "../vai/input/input.x.h" -#endif - -void ui_init() { - window_main.setup(); - window_about.setup(); - - window_bsxloader.setup(); - window_stloader.setup(); - - window_raster_settings.setup(); - window_input_config.setup(); - window_cheat_editor.setup(); - window_advanced.setup(); - window_settings.setup(); - - event::update_video_settings(); //call first time to resize main window and update menubar - window_main.show(); - while(miu().pending()) miu().run(); - -#if defined(PLATFORM_WIN) - if(config::system.video == "none") { - uiVideo = new Video(); - } else if(config::system.video == "gdi") { - uiVideo = new VideoGDI(); - } else if(config::system.video == "directdraw") { - uiVideo = new VideoDD(); - } else { - uiVideo = new VideoD3D(); - } - - if(config::system.audio == "none") { - uiAudio = new Audio(); - } else { - uiAudio = new AudioDS(); - } - - if(config::system.input == "none") { - uiInput = new Input(); - } else { - uiInput = new InputDI(); - } -#elif defined(PLATFORM_X) - if(config::system.video == "none") { - uiVideo = new Video(); - } else if(config::system.video == "gtk") { - uiVideo = new VideoGTK(); - } else { - uiVideo = new VideoXv(); - } - - if(config::system.audio == "none") { - uiAudio = new Audio(); - } else { - uiAudio = new AudioAO(); - } - - if(config::system.input == "none") { - uiInput = new Input(); - } else { - uiInput = new InputX(); - } -#endif - -//needed only by VideoGDI (default is RGB565) - if(config::system.video == "gdi") snes.set_video_pixel_format(SNES::PIXELFORMAT_RGB555); - - uiVideo->set(Video::Handle, window_main.view.handle()); - uiVideo->set(Video::Synchronize, false); - uiAudio->set(Audio::Handle, window_main.handle()); - uiAudio->set(Audio::Synchronize, config::system.regulate_speed); - uiAudio->set(Audio::Frequency, 32000); - uiInput->set(Input::Handle, window_main.handle()); - - uiVideo->init(); - uiAudio->init(); - uiInput->init(); - - event::update_video_settings(); //call second time to update uiVideo->settings -} - -void ui_term() { - window_main.hide(); - - uiVideo->term(); - uiAudio->term(); - uiInput->term(); - - safe_delete(uiVideo); - safe_delete(uiAudio); - safe_delete(uiInput); -} diff --git a/src/ui/miu/settings/ui_advanced.cpp b/src/ui/settings/ui_advanced.cpp similarity index 59% rename from src/ui/miu/settings/ui_advanced.cpp rename to src/ui/settings/ui_advanced.cpp index 2a49cd2d..c6c4340d 100644 --- a/src/ui/miu/settings/ui_advanced.cpp +++ b/src/ui/settings/ui_advanced.cpp @@ -2,18 +2,22 @@ uintptr_t AdvancedWindow::list_change(Event) { int pos = list.get_selection(); set_val.enable(pos >= 0); set_def.enable(pos >= 0); - if(pos >= 0 && pos < config::config().list_count) { - desc.set_text(string() << "(default = " << config::config().list[pos]->def << ")\n" << config::config().list[pos]->desc); - string val; - config::config().list[pos]->get(val); - edit_val.set_text(val); - } + if(pos >= 0 && pos < config::config().list.size()) { + string default_; + config::config().list[pos]->get_default(default_); + desc.set_text(string() << "(default = " << default_ << ")\n" << config::config().list[pos]->description); + string value_; + config::config().list[pos]->get(value_); + edit_val.set_text(value_); + } + return true; } uintptr_t AdvancedWindow::setval_tick(Event) { char t[4096]; edit_val.get_text(t, sizeof t); - update(list.get_selection(), t); + update(list.get_selection(), t); + return true; } uintptr_t AdvancedWindow::setdef_tick(Event) { @@ -23,27 +27,31 @@ uintptr_t AdvancedWindow::setdef_tick(Event) { void AdvancedWindow::read_config(uint pos, string &data) { data = "?\t?\t?"; - if(pos >= config::config().list_count) return; + if(pos >= config::config().list.size()) return; -string name, val; + string name, value_; name = config::config().list[pos]->name; - config::config().list[pos]->get(val); - if(val != config::config().list[pos]->def) { strcat(name, " (*)"); } + config::config().list[pos]->get(value_); + string default_; + config::config().list[pos]->get_default(default_); + if(value_ != default_) { strcat(name, " (*)"); } data = string() << name << "\t" - << (config::config().list[pos]->type == Setting::String ? "String" : "Integer") << "\t" - << val; + << (config::config().list[pos]->type == setting::string_type ? "string" : "integral") << "\t" + << value_; } void AdvancedWindow::update(uint pos, const char *data) { - if(pos >= config::config().list_count) return; - - config::config().list[pos]->set(data ? data : config::config().list[pos]->def); -string val; - config::config().list[pos]->get(val); - edit_val.set_text(val); - read_config(pos, val); - list.set_item(pos, val); + if(pos >= config::config().list.size()) return; + + string default_; + config::config().list[pos]->get_default(default_); + config::config().list[pos]->set(data ? data : (const char*)default_); + string value_; + config::config().list[pos]->get(value_); + edit_val.set_text(value_); + read_config(pos, value_); + list.set_item(pos, value_); list.autosize_columns(); } @@ -68,7 +76,7 @@ uint y = 0; attach(set_val, 270, y); attach(set_def, 375, y); y += 30 + 5; - for(int i = 0; i < config::config().list_count; i++) { + for(int i = 0; i < config::config().list.size(); i++) { string val; read_config(i, val); list.add_item(val); diff --git a/src/ui/miu/settings/ui_advanced.h b/src/ui/settings/ui_advanced.h similarity index 100% rename from src/ui/miu/settings/ui_advanced.h rename to src/ui/settings/ui_advanced.h diff --git a/src/ui/miu/settings/ui_cheateditor.cpp b/src/ui/settings/ui_cheateditor.cpp similarity index 89% rename from src/ui/miu/settings/ui_cheateditor.cpp rename to src/ui/settings/ui_cheateditor.cpp index ea1ce934..9594d09e 100644 --- a/src/ui/miu/settings/ui_cheateditor.cpp +++ b/src/ui/settings/ui_cheateditor.cpp @@ -82,10 +82,3 @@ int index = list.get_selection(); } return true; } - -/* -bool CheatEditorWindow::message(uint id, uintptr_t param) { - if((id == ui::Message::Clicked && control == &toggle_code) || - (id == ui::Message::DoubleClicked && control == &list)) {} -} -*/ diff --git a/src/ui/miu/settings/ui_cheateditor.h b/src/ui/settings/ui_cheateditor.h similarity index 100% rename from src/ui/miu/settings/ui_cheateditor.h rename to src/ui/settings/ui_cheateditor.h diff --git a/src/ui/settings/ui_inputconfig.cpp b/src/ui/settings/ui_inputconfig.cpp new file mode 100644 index 00000000..ed3278e6 --- /dev/null +++ b/src/ui/settings/ui_inputconfig.cpp @@ -0,0 +1,238 @@ +/* InputConfigWindow */ + +void InputConfigWindow::setup() { + create(0, 475, 355); + + capture_mode.create(0, 475, 15, "When emulation window does not have focus:"); + RadioboxGroup group; + group.add(&capture_always); + group.add(&capture_focus); + group.add(&capture_pause); + capture_always.create(group, 0, 155, 20, "Allow input"); + capture_focus.create(group, 0, 155, 20, "Ignore input"); + capture_pause.create(group, 0, 155, 20, "Pause emulation"); + + list.create(Listbox::Header | Listbox::VerticalScrollAlways, 475, 275, "Name\tValue"); + setkey.create(0, 235, 30, "Assign Key"); + setkey.disable(); + clrkey.create(0, 235, 30, "Unassign Key"); + clrkey.disable(); + +uint y = 0; + attach(capture_mode, 0, y); y += 15 + 5; + attach(capture_always, 0, y); + attach(capture_focus, 160, y); + attach(capture_pause, 320, y); y += 20 + 5; + attach(list, 0, y); y += 275 + 5; + attach(setkey, 0, y); + attach(clrkey, 240, y); y += 30 + 5; + + capture_always.on_tick = bind(&InputConfigWindow::capture_change, this); + capture_focus.on_tick = bind(&InputConfigWindow::capture_change, this); + capture_pause.on_tick = bind(&InputConfigWindow::capture_change, this); + list.on_change = bind(&InputConfigWindow::list_change, this); + list.on_activate = bind(&InputConfigWindow::set_tick, this); + setkey.on_tick = bind(&InputConfigWindow::set_tick, this); + clrkey.on_tick = bind(&InputConfigWindow::clr_tick, this); + + if(config::input.capture_mode == 1) capture_focus.check(); + else if(config::input.capture_mode == 2) capture_pause.check(); + else config::input.capture_mode = 0; //capture_always + + for(uint i = 0; i < list_size; i++) list.add_item("???\t???"); + refresh_list(); + window_input_capture.setup(); +} + +void InputConfigWindow::refresh_list() { + for(uint i = 0; i < list_size; i++) { + list.set_item(i, string() << list_index[i] << "\t" << input_find(get_value(i))); + } + list.autosize_columns(); +} + +uintptr_t InputConfigWindow::capture_change(Event e) { + if(e.widget == &capture_always) config::input.capture_mode = 0; + if(e.widget == &capture_focus) config::input.capture_mode = 1; + if(e.widget == &capture_pause) config::input.capture_mode = 2; + return true; +} + +uintptr_t InputConfigWindow::list_change(Event) { +int pos = list.get_selection(); + setkey.enable(pos >= 0); + clrkey.enable(pos >= 0); + return true; +} + +uintptr_t InputConfigWindow::set_tick(Event) { +int pos = list.get_selection(); + if(pos < 0) return true; + window_input_capture.index = pos; + window_input_capture.label.set_text(string() << "Press a key to assign to " << list_index[pos] << " ..."); + window_input_capture.show(); + return true; +} + +uintptr_t InputConfigWindow::clr_tick(Event) { +int pos = list.get_selection(); + if(pos < 0) return true; + set_value(pos, keyboard::none); + refresh_list(); + return true; +} + +/* InputCaptureWindow */ + +void InputCaptureWindow::assign(uint16_t key) { + waiting = false; + hide(); + window_input_config.set_value(index, key); + window_input_config.refresh_list(); + input.clear(); +} + +void InputCaptureWindow::show() { + input.poll(); + waiting = true; + locked = input.key_down(keyboard::return_) || input.key_down(keyboard::spacebar); + Window::focus(); +} + +uintptr_t InputCaptureWindow::close(Event) { + hide(); + return false; +} + +void InputCaptureWindow::setup() { + create(Window::AutoCenter, 350, 100, "bsnes Key Capture"); + label.create(0, 340, 90); + attach(label, 5, 5); + on_close = bind(&InputCaptureWindow::close, this); +} + +InputCaptureWindow::InputCaptureWindow() { + waiting = false; + locked = false; + index = 0; +} + +/* Misc */ + +const int InputConfigWindow::list_size = 31; + +const char InputConfigWindow::list_index[][64] = { + "Joypad 1 Up", + "Joypad 1 Down", + "Joypad 1 Left", + "Joypad 1 Right", + "Joypad 1 A", + "Joypad 1 B", + "Joypad 1 X", + "Joypad 1 Y", + "Joypad 1 L", + "Joypad 1 R", + "Joypad 1 Select", + "Joypad 1 Start", + + "Joypad 2 Up", + "Joypad 2 Down", + "Joypad 2 Left", + "Joypad 2 Right", + "Joypad 2 A", + "Joypad 2 B", + "Joypad 2 X", + "Joypad 2 Y", + "Joypad 2 L", + "Joypad 2 R", + "Joypad 2 Select", + "Joypad 2 Start", + + "Load Cartridge", + "Pause Emulation", + "Reset System", + "Power Cycle System", + "Toggle Fullscreen", + "Toggle Menubar", + "Toggle Statusbar", +}; + +uint InputConfigWindow::get_value(uint index) { + switch(index) { + case 0: return input_find(config::input.joypad1.up); + case 1: return input_find(config::input.joypad1.down); + case 2: return input_find(config::input.joypad1.left); + case 3: return input_find(config::input.joypad1.right); + case 4: return input_find(config::input.joypad1.a); + case 5: return input_find(config::input.joypad1.b); + case 6: return input_find(config::input.joypad1.x); + case 7: return input_find(config::input.joypad1.y); + case 8: return input_find(config::input.joypad1.l); + case 9: return input_find(config::input.joypad1.r); + case 10: return input_find(config::input.joypad1.select); + case 11: return input_find(config::input.joypad1.start); + + case 12: return input_find(config::input.joypad2.up); + case 13: return input_find(config::input.joypad2.down); + case 14: return input_find(config::input.joypad2.left); + case 15: return input_find(config::input.joypad2.right); + case 16: return input_find(config::input.joypad2.a); + case 17: return input_find(config::input.joypad2.b); + case 18: return input_find(config::input.joypad2.x); + case 19: return input_find(config::input.joypad2.y); + case 20: return input_find(config::input.joypad2.l); + case 21: return input_find(config::input.joypad2.r); + case 22: return input_find(config::input.joypad2.select); + case 23: return input_find(config::input.joypad2.start); + + case 24: return input_find(config::input.gui.load); + case 25: return input_find(config::input.gui.pause); + case 26: return input_find(config::input.gui.reset); + case 27: return input_find(config::input.gui.power); + case 28: return input_find(config::input.gui.toggle_fullscreen); + case 29: return input_find(config::input.gui.toggle_menubar); + case 30: return input_find(config::input.gui.toggle_statusbar); + } + + return keyboard::none; +} + +void InputConfigWindow::set_value(uint index, uint16 value) { + switch(index) { + case 0: config::input.joypad1.up = input_find(value); break; + case 1: config::input.joypad1.down = input_find(value); break; + case 2: config::input.joypad1.left = input_find(value); break; + case 3: config::input.joypad1.right = input_find(value); break; + case 4: config::input.joypad1.a = input_find(value); break; + case 5: config::input.joypad1.b = input_find(value); break; + case 6: config::input.joypad1.x = input_find(value); break; + case 7: config::input.joypad1.y = input_find(value); break; + case 8: config::input.joypad1.l = input_find(value); break; + case 9: config::input.joypad1.r = input_find(value); break; + case 10: config::input.joypad1.select = input_find(value); break; + case 11: config::input.joypad1.start = input_find(value); break; + + case 12: config::input.joypad2.up = input_find(value); break; + case 13: config::input.joypad2.down = input_find(value); break; + case 14: config::input.joypad2.left = input_find(value); break; + case 15: config::input.joypad2.right = input_find(value); break; + case 16: config::input.joypad2.a = input_find(value); break; + case 17: config::input.joypad2.b = input_find(value); break; + case 18: config::input.joypad2.x = input_find(value); break; + case 19: config::input.joypad2.y = input_find(value); break; + case 20: config::input.joypad2.l = input_find(value); break; + case 21: config::input.joypad2.r = input_find(value); break; + case 22: config::input.joypad2.select = input_find(value); break; + case 23: config::input.joypad2.start = input_find(value); break; + + case 24: config::input.gui.load = input_find(value); break; + case 25: config::input.gui.pause = input_find(value); break; + case 26: config::input.gui.reset = input_find(value); break; + case 27: config::input.gui.power = input_find(value); break; + case 28: config::input.gui.toggle_fullscreen = input_find(value); break; + case 29: config::input.gui.toggle_menubar = input_find(value); break; + case 30: config::input.gui.toggle_statusbar = input_find(value); break; + } + + input_manager.bind(); +} diff --git a/src/ui/miu/settings/ui_inputconfig.h b/src/ui/settings/ui_inputconfig.h similarity index 68% rename from src/ui/miu/settings/ui_inputconfig.h rename to src/ui/settings/ui_inputconfig.h index cb2b05a0..37060147 100644 --- a/src/ui/miu/settings/ui_inputconfig.h +++ b/src/ui/settings/ui_inputconfig.h @@ -1,20 +1,22 @@ class InputConfigWindow : public Window { -public: - Label lportA; - Label lportB; - Combobox portA; - Combobox portB; +public: + Label capture_mode; + Radiobox capture_always; + Radiobox capture_focus; + Radiobox capture_pause; Listbox list; Button setkey; Button clrkey; void setup(); void refresh_list(); - + + uintptr_t capture_change(Event); uintptr_t list_change(Event); uintptr_t set_tick(Event); uintptr_t clr_tick(Event); - + + static const int list_size; static const char list_index[][64]; uint get_value(uint index); void set_value(uint index, uint16 value); @@ -23,12 +25,14 @@ public: class InputCaptureWindow : public Window { public: Label label; - + + bool waiting; + bool locked; uint index; - bool key_lock; - + + void assign(uint16_t key); + void show(); void setup(); - void show(); uintptr_t close(Event); diff --git a/src/ui/miu/settings/ui_rastersettings.cpp b/src/ui/settings/ui_rastersettings.cpp similarity index 91% rename from src/ui/miu/settings/ui_rastersettings.cpp rename to src/ui/settings/ui_rastersettings.cpp index edd35b3d..45840b0e 100644 --- a/src/ui/miu/settings/ui_rastersettings.cpp +++ b/src/ui/settings/ui_rastersettings.cpp @@ -44,11 +44,11 @@ uint y = 0; void RasterSettingsWindow::sync_ui() { ui_lock = true; //supress event messages while syncing UI elements, prevents infinite recursion contrast.set_position(config::snes.contrast + 96); - lcontrast.set_text(string() << "Contrast: " << config::snes.contrast); + lcontrast.set_text(string() << "Contrast: " << (int)config::snes.contrast); brightness.set_position(config::snes.brightness + 96); - lbrightness.set_text(string() << "Brightness: " << config::snes.brightness); + lbrightness.set_text(string() << "Brightness: " << (int)config::snes.brightness); gamma.set_position(config::snes.gamma - 10); - lgamma.set_text(string() << "Gamma: " << config::snes.gamma); //TODO: print gamma as "%0.2f" / 100.0 + lgamma.set_text(string() << "Gamma: " << (int)config::snes.gamma); //TODO: print gamma as "%0.2f" / 100.0 gamma_ramp.check(config::snes.gamma_ramp); sepia.check(config::snes.sepia); grayscale.check(config::snes.grayscale); @@ -121,7 +121,8 @@ uintptr_t RasterSettingsWindow::optimal_tick(Event) { config::snes.sepia = false; config::snes.grayscale = false; config::snes.invert = false; - sync_ui(); + sync_ui(); + return true; } uintptr_t RasterSettingsWindow::standard_tick(Event) { @@ -132,7 +133,8 @@ uintptr_t RasterSettingsWindow::standard_tick(Event) { config::snes.sepia = false; config::snes.grayscale = false; config::snes.invert = false; - sync_ui(); + sync_ui(); + return true; } RasterSettingsWindow::RasterSettingsWindow() { diff --git a/src/ui/miu/settings/ui_rastersettings.h b/src/ui/settings/ui_rastersettings.h similarity index 100% rename from src/ui/miu/settings/ui_rastersettings.h rename to src/ui/settings/ui_rastersettings.h diff --git a/src/ui/miu/settings/ui_settings.cpp b/src/ui/settings/ui_settings.cpp similarity index 100% rename from src/ui/miu/settings/ui_settings.cpp rename to src/ui/settings/ui_settings.cpp diff --git a/src/ui/miu/settings/ui_settings.h b/src/ui/settings/ui_settings.h similarity index 100% rename from src/ui/miu/settings/ui_settings.h rename to src/ui/settings/ui_settings.h diff --git a/src/ui/ui.cpp b/src/ui/ui.cpp new file mode 100644 index 00000000..5761be2a --- /dev/null +++ b/src/ui/ui.cpp @@ -0,0 +1,64 @@ +#include "ui_main.cpp" +#include "ui_about.cpp" +#include "ui_message.cpp" + +#include "loader/ui_bsxloader.cpp" +#include "loader/ui_stloader.cpp" + +#include "settings/ui_settings.cpp" +#include "settings/ui_rastersettings.cpp" +#include "settings/ui_inputconfig.cpp" +#include "settings/ui_cheateditor.cpp" +#include "settings/ui_advanced.cpp" + +void ui_init() { + window_main.setup(); + window_about.setup(); + window_message.setup(); + + window_bsxloader.setup(); + window_stloader.setup(); + + window_raster_settings.setup(); + window_input_config.setup(); + window_cheat_editor.setup(); + window_advanced.setup(); + window_settings.setup(); + + event::update_video_settings(); //call first time to resize main window and update menubar + window_main.show(); + while(hiro().pending()) hiro().run(); + + //needed only by VideoGDI (default is RGB565) + if(config::system.video == "gdi") snes.set_video_pixel_format(SNES::PIXELFORMAT_RGB555); + + video.driver(config::system.video); + audio.driver(config::system.audio); + input.driver(config::system.input); + + video.set(Video::Handle, window_main.view.handle()); + video.set(Video::Synchronize, false); + audio.set(Audio::Handle, window_main.handle()); + audio.set(Audio::Synchronize, (bool)config::system.regulate_speed); + audio.set(Audio::Frequency, 32000); + input.set(Input::Handle, window_main.handle()); + + video.init(); + audio.init(); + input.init(); + + event::update_video_settings(); //call second time to update uiVideo->settings + + //UI setup complete, hook keyboard callbacks + snesinterface.input_ready = bind(&MainWindow::input_ready, &window_main); + input_manager.on_keydown = bind(&event::keydown); + input_manager.on_keyup = bind(&event::keyup); +} + +void ui_term() { + window_main.hide(); + + video.term(); + audio.term(); + input.term(); +} diff --git a/src/ui/miu/ui.h b/src/ui/ui.h similarity index 89% rename from src/ui/miu/ui.h rename to src/ui/ui.h index 983ad5ea..dd9715d8 100644 --- a/src/ui/miu/ui.h +++ b/src/ui/ui.h @@ -1,5 +1,6 @@ #include "ui_main.h" -#include "ui_about.h" +#include "ui_about.h" +#include "ui_message.h" #include "loader/ui_bsxloader.h" #include "loader/ui_stloader.h" diff --git a/src/ui/miu/ui_about.cpp b/src/ui/ui_about.cpp similarity index 100% rename from src/ui/miu/ui_about.cpp rename to src/ui/ui_about.cpp diff --git a/src/ui/miu/ui_about.h b/src/ui/ui_about.h similarity index 100% rename from src/ui/miu/ui_about.h rename to src/ui/ui_about.h diff --git a/src/ui/miu/ui_main.cpp b/src/ui/ui_main.cpp similarity index 90% rename from src/ui/miu/ui_main.cpp rename to src/ui/ui_main.cpp index 9015ecb8..f6221998 100644 --- a/src/ui/miu/ui_main.cpp +++ b/src/ui/ui_main.cpp @@ -1,14 +1,24 @@ -bool MainWindow::input_ready() { - return focused() == true; //only allow SNES to recognize input when main window is focused +bool MainWindow::input_ready() { + //allow input if main window has focus + if(focused() == true) return true; + //allow input if config set to never block input + if(config::input.capture_mode == 0) return true; + //block input + return false; +} + +uintptr_t MainWindow::close(Event) { + _term_ = true; + window_about.hide(); + window_message.hide(); + window_settings.hide(); + window_bsxloader.hide(); + window_stloader.hide(); + hide(); + return false; } uintptr_t MainWindow::event(Event e) { - if(e.type == Event::Close) { - _term_ = true; - hide(); - return false; - } - if(e.type == Event::Tick) { if(e.widget == &menu_file_load) { event::load_rom(); @@ -84,12 +94,12 @@ uintptr_t MainWindow::event(Event e) { if(e.widget == &menu_settings_videoframeskip_9) { config::video.frameskip = 9; } if(e.widget == &menu_settings_mute) { - config::snes.mute = menu_settings_mute.checked(); + config::audio.mute = menu_settings_mute.checked(); } if(e.widget == &menu_settings_speedreg_enable) { config::system.regulate_speed = menu_settings_speedreg_enable.checked(); - if(uiAudio) uiAudio->set(Audio::Synchronize, config::system.regulate_speed); + audio.set(Audio::Synchronize, (bool)config::system.regulate_speed); } if(e.widget == &menu_settings_speedreg_slowest) { event::update_speed_regulation(1); } @@ -105,11 +115,8 @@ uintptr_t MainWindow::event(Event e) { (menu_misc_logaudio.checked() == true) ? snes.log_audio_enable() : snes.log_audio_disable(); } - if(e.widget == &menu_misc_showfps) { - config::misc.show_frame_counter = menu_misc_showfps.checked(); - if(config::misc.show_frame_counter == false) { - set_text(BSNES_TITLE); - } + if(e.widget == &menu_misc_showstatus) { + status.show(config::misc.show_status = menu_misc_showstatus.checked()); } if(e.widget == &menu_misc_about) { @@ -121,17 +128,11 @@ uintptr_t MainWindow::event(Event e) { } uintptr_t MainWindow::block(Event) { - if(uiAudio) uiAudio->clear_audio(); + audio.clear(); return true; } -uintptr_t MainWindow::keydown(Event e) { - if(e.param == keymap::esc) { event::toggle_menu(); } - if(e.param == keymap::f11) { event::toggle_fullscreen(); } -} - void MainWindow::setup() { - snesinterface.input_ready = bind(&MainWindow::input_ready, this); locked = true; create(Window::AutoCenter, 256, 224, BSNES_TITLE); @@ -238,16 +239,17 @@ MenuRadioItemGroup group; attach(menu_misc.create("Misc")); menu_misc.attach(menu_misc_logaudio.create("Log Audio Data")); - menu_misc.attach(menu_misc_showfps.create("Show FPS")); + menu_misc.attach(menu_misc_showstatus.create("Show Statusbar")); menu_misc.attach(menu_misc_sep1.create()); menu_misc.attach(menu_misc_about.create("About ...")); view.create(0, 256, 224); attach(view, 0, 0); - on_close = bind(&MainWindow::event, this); + on_close = bind(&MainWindow::close, this); on_block = bind(&MainWindow::block, this); - on_keydown = bind(&MainWindow::keydown, this); + + menu_file_exit.on_tick = bind(&MainWindow::close, this); menu_file_load.on_tick = menu_file_load_bsx.on_tick = @@ -256,7 +258,6 @@ MenuRadioItemGroup group; menu_file_unload.on_tick = menu_file_reset.on_tick = menu_file_power.on_tick = - menu_file_exit.on_tick = menu_settings_videomode_1x.on_tick = menu_settings_videomode_2x.on_tick = @@ -295,7 +296,7 @@ MenuRadioItemGroup group; menu_settings_config.on_tick = menu_misc_logaudio.on_tick = - menu_misc_showfps.on_tick = + menu_misc_showstatus.on_tick = menu_misc_about.on_tick = bind(&MainWindow::event, this); @@ -332,12 +333,12 @@ void MainWindow::update_menu_settings() { case 3: menu_settings_videofilter_swscale2x.check(); break; } - menu_settings_mute.check(config::snes.mute); + menu_settings_mute.check(config::audio.mute); menu_settings_speedreg_enable.check(config::system.regulate_speed); menu_settings_speedreg_normal.check(); - menu_misc_showfps.check(config::misc.show_frame_counter); + menu_misc_showstatus.check(config::misc.show_status); locked = false; } diff --git a/src/ui/miu/ui_main.h b/src/ui/ui_main.h similarity index 95% rename from src/ui/miu/ui_main.h rename to src/ui/ui_main.h index c47f1e83..1a3dd7d2 100644 --- a/src/ui/miu/ui_main.h +++ b/src/ui/ui_main.h @@ -61,7 +61,7 @@ public: MenuGroup menu_misc; MenuCheckItem menu_misc_logaudio; - MenuCheckItem menu_misc_showfps; + MenuCheckItem menu_misc_showstatus; MenuSeparator menu_misc_sep1; MenuItem menu_misc_about; @@ -71,8 +71,8 @@ public: bool input_ready(); void setup(); - void update_menu_settings(); + void update_menu_settings(); + uintptr_t close(Event); uintptr_t event(Event); uintptr_t block(Event); - uintptr_t keydown(Event); } window_main; diff --git a/src/ui/ui_message.cpp b/src/ui/ui_message.cpp new file mode 100644 index 00000000..a8b213bb --- /dev/null +++ b/src/ui/ui_message.cpp @@ -0,0 +1,20 @@ +uintptr_t MessageWindow::close(Event) { + hide(); + return false; +} + +void MessageWindow::setup() { + create(Window::AutoCenter, 400, 100, ""); + message.create(0, 390, 60, "Test\nMessage"); + ok.create(0, 100, 30, "Ok"); + attach(message, 5, 5); + attach(ok, 295, 65); + + on_close = ok.on_tick = bind(&MessageWindow::close, this); +} + +void MessageWindow::show(const char *message_, const char *title_) { + message.set_text(message_); + set_text(title_); + focus(); +} diff --git a/src/ui/ui_message.h b/src/ui/ui_message.h new file mode 100644 index 00000000..04b38cf9 --- /dev/null +++ b/src/ui/ui_message.h @@ -0,0 +1,9 @@ +class MessageWindow : public Window { +public: + Label message; + Button ok; + + void setup(); + void show(const char *message, const char *title = "Warning"); + uintptr_t close(Event); +} window_message; diff --git a/src/ui/vai/audio/audio.directsound.h b/src/ui/vai/audio/audio.directsound.h deleted file mode 100644 index 0d2e4f41..00000000 --- a/src/ui/vai/audio/audio.directsound.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef AUDIO_DIRECTSOUND_H -#define AUDIO_DIRECTSOUND_H - -#include "../audio.h" - -class pAudioDS; - -class AudioDS : public Audio { -public: - bool cap(Setting); - uintptr_t get(Setting); - bool set(Setting, uintptr_t); - - void sample(uint16 left, uint16 right); - void clear_audio(); - void init(); - void term(); - - AudioDS(); - ~AudioDS(); - -private: - pAudioDS &p; -}; - -#endif //ifndef AUDIO_DIRECTSOUND_H diff --git a/src/ui/vai/input.h b/src/ui/vai/input.h deleted file mode 100644 index fd9d4199..00000000 --- a/src/ui/vai/input.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef INPUT_H -#define INPUT_H - -#include "../../lib/bbase.h" -#include "../../lib/bkeymap.h" - -class Input { -public: - enum Setting { - Handle, - }; - - virtual bool cap(Setting) { return false; } - virtual uintptr_t get(Setting) { return false; } - virtual bool set(Setting, uintptr_t) { return false; } - - virtual bool key_down(uint16 key) { return false; } - virtual bool key_up (uint16 key) { return !key_down(key); } - - virtual void clear_input() {} - virtual void poll() {} - virtual void init() {} - virtual void term() {} - - Input() {} - virtual ~Input() {} -}; - -#endif //ifndef INPUT_H diff --git a/src/ui/vai/input/input.directinput.cpp b/src/ui/vai/input/input.directinput.cpp deleted file mode 100644 index ff1b5899..00000000 --- a/src/ui/vai/input/input.directinput.cpp +++ /dev/null @@ -1,293 +0,0 @@ -#include "input.directinput.h" - -#define WIN32_LEAN_AND_MEAN -#include - -#define DIRECTINPUT_VERSION 0x0800 -#define DIRECTINPUT_JOYMAX 16 -#include - -BOOL CALLBACK DI_EnumJoypadsCallback(const DIDEVICEINSTANCE *instance, void *p); - -class pInputDI { -public: - InputDI &self; - uint8 keystate[65536]; - LPDIRECTINPUT8 di; - LPDIRECTINPUTDEVICE8 di_key, di_joy[DIRECTINPUT_JOYMAX]; - uint32 di_joy_count; - - struct { - HWND handle; - } settings; - - bool cap(Input::Setting setting) { - if(setting == Input::Handle) return true; - return false; - } - - uintptr_t get(Input::Setting setting) { - if(setting == Input::Handle) return (uintptr_t)settings.handle; - return false; - } - - bool set(Input::Setting setting, uintptr_t param) { - if(setting == Input::Handle) { - settings.handle = (HWND)param; - return true; - } - return false; - } - - void clear_input() { - memset(keystate, 0, sizeof keystate); - } - - void poll() { - clear_input(); - - HRESULT hr; - DIJOYSTATE2 js; - if(di_key) { - hr = di_key->GetDeviceState(256, keystate); - if(FAILED(hr)) { - di_key->Acquire(); - hr = di_key->GetDeviceState(256, keystate); - } - } - - for(int i = 0; i < di_joy_count; i++) { - if(!di_joy[i])continue; - - memset(js.rgbButtons, 0, 128); - - hr = di_joy[i]->Poll(); - if(FAILED(hr)) { - di_joy[i]->Acquire(); - di_joy[i]->Poll(); - } - di_joy[i]->GetDeviceState(sizeof(DIJOYSTATE2), &js); - - uint index = keymap::joypad_flag | (i << 8); //joypad index - memcpy(keystate + index, js.rgbButtons, 128); - - //map d-pad axes - int resistance = 75; //config::input.axis_resistance; - if(resistance < 1)resistance = 1; - if(resistance > 99)resistance = 99; - resistance = int32(double(resistance) * 32768.0 / 100.0); - int resistance_lo = 0x7fff - resistance; - int resistance_hi = 0x8000 + resistance; - keystate[index + keymap::joypad_up] = (js.lY <= resistance_lo) ? 0x80 : 0x00; - keystate[index + keymap::joypad_down] = (js.lY >= resistance_hi) ? 0x80 : 0x00; - keystate[index + keymap::joypad_left] = (js.lX <= resistance_lo) ? 0x80 : 0x00; - keystate[index + keymap::joypad_right] = (js.lX >= resistance_hi) ? 0x80 : 0x00; - - //map analog POV (analog directional pad) as well - uint pov = js.rgdwPOV[0]; - keystate[index + keymap::joypad_up] |= (pov == 0 || pov == 31500 || pov == 4500) ? 0x80 : 0x00; - keystate[index + keymap::joypad_down] |= (pov == 18000 || pov == 13500 || pov == 22500) ? 0x80 : 0x00; - keystate[index + keymap::joypad_left] |= (pov == 27000 || pov == 22500 || pov == 31500) ? 0x80 : 0x00; - keystate[index + keymap::joypad_right] |= (pov == 9000 || pov == 4500 || pov == 13500) ? 0x80 : 0x00; - } - } - - bool enum_joypads(const DIDEVICEINSTANCE *instance) { - HRESULT hr = di->CreateDevice(instance->guidInstance, &di_joy[di_joy_count], 0); - if(FAILED(hr)) { - return DIENUM_CONTINUE; - } - - di_joy[di_joy_count]->SetDataFormat(&c_dfDIJoystick2); - di_joy[di_joy_count]->SetCooperativeLevel(settings.handle, DISCL_NONEXCLUSIVE | DISCL_BACKGROUND); - - if(++di_joy_count >= DIRECTINPUT_JOYMAX) { - //too many joypads? - return DIENUM_STOP; - } - - return DIENUM_CONTINUE; - } - - void init() { - di_key = 0; - for(int i = 0; i < DIRECTINPUT_JOYMAX; i++)di_joy[i] = 0; - di = 0; - di_joy_count = 0; - - DirectInput8Create(GetModuleHandle(0), DIRECTINPUT_VERSION, - IID_IDirectInput8, (void**)&di, 0); - di->CreateDevice(GUID_SysKeyboard, &di_key, 0); - - di_key->SetDataFormat(&c_dfDIKeyboard); - di_key->SetCooperativeLevel(settings.handle, DISCL_NONEXCLUSIVE | DISCL_BACKGROUND); - di_key->Acquire(); - - di->EnumDevices(DI8DEVCLASS_GAMECTRL, DI_EnumJoypadsCallback, (void*)this, DIEDFL_ATTACHEDONLY); - } - - void term() { - if(di_key) { di_key->Unacquire(); di_key->Release(); di_key = 0; } - for(int i = 0; i < DIRECTINPUT_JOYMAX; i++) { - if(di_joy[i]) { di_joy[i]->Unacquire(); di_joy[i]->Release(); di_joy[i] = 0; } - } - if(di) { di->Release(); di = 0; } - di_joy_count = 0; - } - - bool key_down(uint16 key) { - return keystate[translate(key)] & 0x80; - } - - //translate keymap code to DirectInput code, to lookup key status in DI status table - uint16 translate(uint16 key) { - //DI joypad codes share 1:1 mapping with keymap codes - if(key & keymap::joypad_flag) { return key; } - - switch(key) { - case keymap::esc: return 0x01; - - case keymap::f1: return 0x3b; - case keymap::f2: return 0x3c; - case keymap::f3: return 0x3d; - case keymap::f4: return 0x3e; - case keymap::f5: return 0x3f; - case keymap::f6: return 0x40; - case keymap::f7: return 0x41; - case keymap::f8: return 0x42; - case keymap::f9: return 0x43; - case keymap::f10: return 0x44; - case keymap::f11: return 0x57; - case keymap::f12: return 0x58; - - case keymap::print_screen: return 0xb7; - case keymap::scroll_lock: return 0x46; - case keymap::pause: return 0xc5; - - case keymap::grave: return 0x29; - - case keymap::num_1: return 0x02; - case keymap::num_2: return 0x03; - case keymap::num_3: return 0x04; - case keymap::num_4: return 0x05; - case keymap::num_5: return 0x06; - case keymap::num_6: return 0x07; - case keymap::num_7: return 0x08; - case keymap::num_8: return 0x09; - case keymap::num_9: return 0x0a; - case keymap::num_0: return 0x0b; - - case keymap::minus: return 0x0c; - case keymap::equal: return 0x0d; - case keymap::backspace: return 0x0e; - - case keymap::ins: return 0xd2; - case keymap::del: return 0xd3; - case keymap::home: return 0xc7; - case keymap::end: return 0xcf; - case keymap::page_up: return 0xc9; - case keymap::page_down: return 0xd1; - - case keymap::a: return 0x1e; - case keymap::b: return 0x30; - case keymap::c: return 0x2e; - case keymap::d: return 0x20; - case keymap::e: return 0x12; - case keymap::f: return 0x21; - case keymap::g: return 0x22; - case keymap::h: return 0x23; - case keymap::i: return 0x17; - case keymap::j: return 0x24; - case keymap::k: return 0x25; - case keymap::l: return 0x26; - case keymap::m: return 0x32; - case keymap::n: return 0x31; - case keymap::o: return 0x18; - case keymap::p: return 0x19; - case keymap::q: return 0x10; - case keymap::r: return 0x13; - case keymap::s: return 0x1f; - case keymap::t: return 0x14; - case keymap::u: return 0x16; - case keymap::v: return 0x2f; - case keymap::w: return 0x11; - case keymap::x: return 0x2d; - case keymap::y: return 0x15; - case keymap::z: return 0x2c; - - case keymap::lbracket: return 0x1a; - case keymap::rbracket: return 0x1b; - case keymap::backslash: return 0x2b; - case keymap::semicolon: return 0x27; - case keymap::apostrophe: return 0x28; - case keymap::comma: return 0x33; - case keymap::period: return 0x34; - case keymap::slash: return 0x35; - - case keymap::kp_1: return 0x4f; - case keymap::kp_2: return 0x50; - case keymap::kp_3: return 0x51; - case keymap::kp_4: return 0x4b; - case keymap::kp_5: return 0x4c; - case keymap::kp_6: return 0x4d; - case keymap::kp_7: return 0x47; - case keymap::kp_8: return 0x48; - case keymap::kp_9: return 0x49; - case keymap::kp_0: return 0x52; - case keymap::kp_decimal: return 0x53; - - case keymap::kp_plus: return 0x4e; - case keymap::kp_minus: return 0x4a; - case keymap::kp_mul: return 0x37; - case keymap::kp_div: return 0xb5; - case keymap::kp_enter: return 0x9c; - - case keymap::num_lock : return 0x45; - case keymap::caps_lock: return 0x3a; - - case keymap::up: return 0xc8; - case keymap::down: return 0xd0; - case keymap::left: return 0xcb; - case keymap::right: return 0xcd; - - case keymap::tab: return 0x0f; - case keymap::enter: return 0x1c; - case keymap::space: return 0x39; - - case keymap::lctrl : return 0x1d; - case keymap::rctrl : return 0x9d; - case keymap::lalt : return 0x38; - case keymap::ralt : return 0xb8; - case keymap::lshift: return 0x2a; - case keymap::rshift: return 0x36; - case keymap::lsuper: return 0xdb; - case keymap::rsuper: return 0xdc; - case keymap::menu: return 0xdd; - } - - return 0x00; - } - - pInputDI(InputDI &self_) : self(self_) { - di = 0; - di_key = 0; - for(int i = 0; i < DIRECTINPUT_JOYMAX; i++) di_joy[i] = 0; - } - - ~pInputDI() { term(); } -}; - -BOOL CALLBACK DI_EnumJoypadsCallback(const DIDEVICEINSTANCE *instance, void *p) { - return ((pInputDI*)p)->enum_joypads(instance); -} - -bool InputDI::cap(Setting setting) { return p.cap(setting); } -uintptr_t InputDI::get(Setting setting) { return p.get(setting); } -bool InputDI::set(Setting setting, uintptr_t param) { return p.set(setting, param); } -bool InputDI::key_down(uint16 key) { return p.key_down(key); } -void InputDI::clear_input() { p.clear_input(); } -void InputDI::poll() { p.poll(); } -void InputDI::init() { p.init(); } -void InputDI::term() { p.term(); } -InputDI::InputDI() : p(*new pInputDI(*this)) {} -InputDI::~InputDI() { delete &p; } diff --git a/src/ui/vai/input/input.x.cpp b/src/ui/vai/input/input.x.cpp deleted file mode 100644 index 2cf9ddde..00000000 --- a/src/ui/vai/input/input.x.cpp +++ /dev/null @@ -1,168 +0,0 @@ -#include "input.x.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -class pInputX { -public: - InputX &self; - Display *display; - char keymap[32]; - - bool key_down(uint16 key) { - #define map(i) (keymap[i >> 3] & (1 << (i & 7))) - - switch(key) { - case keymap::esc: return map(0x09); - - case keymap::f1: return map(0x43); - case keymap::f2: return map(0x44); - case keymap::f3: return map(0x45); - case keymap::f4: return map(0x46); - case keymap::f5: return map(0x47); - case keymap::f6: return map(0x48); - case keymap::f7: return map(0x49); - case keymap::f8: return map(0x4a); - case keymap::f9: return map(0x4b); - case keymap::f10: return map(0x4c); - case keymap::f11: return map(0x5f); - case keymap::f12: return map(0x60); - - case keymap::print_screen: return map(0x6f); - case keymap::scroll_lock: return map(0x4e); - case keymap::pause: return map(0x6e); - - case keymap::grave: return map(0x31); - - case keymap::num_1: return map(0x0a); - case keymap::num_2: return map(0x0b); - case keymap::num_3: return map(0x0c); - case keymap::num_4: return map(0x0d); - case keymap::num_5: return map(0x0e); - case keymap::num_6: return map(0x0f); - case keymap::num_7: return map(0x10); - case keymap::num_8: return map(0x11); - case keymap::num_9: return map(0x12); - case keymap::num_0: return map(0x13); - - case keymap::minus: return map(0x14); - case keymap::equal: return map(0x15); - case keymap::backspace: return map(0x16); - - case keymap::ins: return map(0x6a); - case keymap::del: return map(0x6b); - case keymap::home: return map(0x61); - case keymap::end: return map(0x67); - case keymap::page_up: return map(0x63); - case keymap::page_down: return map(0x69); - - case keymap::a: return map(0x26); - case keymap::b: return map(0x38); - case keymap::c: return map(0x36); - case keymap::d: return map(0x28); - case keymap::e: return map(0x1a); - case keymap::f: return map(0x29); - case keymap::g: return map(0x2a); - case keymap::h: return map(0x2b); - case keymap::i: return map(0x1f); - case keymap::j: return map(0x2c); - case keymap::k: return map(0x2d); - case keymap::l: return map(0x2e); - case keymap::m: return map(0x3a); - case keymap::n: return map(0x39); - case keymap::o: return map(0x20); - case keymap::p: return map(0x21); - case keymap::q: return map(0x18); - case keymap::r: return map(0x1b); - case keymap::s: return map(0x27); - case keymap::t: return map(0x1c); - case keymap::u: return map(0x1e); - case keymap::v: return map(0x37); - case keymap::w: return map(0x19); - case keymap::x: return map(0x35); - case keymap::y: return map(0x1d); - case keymap::z: return map(0x34); - - case keymap::lbracket: return map(0x22); - case keymap::rbracket: return map(0x23); - case keymap::backslash: return map(0x33); - case keymap::semicolon: return map(0x2f); - case keymap::apostrophe: return map(0x30); - case keymap::comma: return map(0x3b); - case keymap::period: return map(0x3c); - case keymap::slash: return map(0x3d); - - case keymap::kp_1: return map(0x57); - case keymap::kp_2: return map(0x58); - case keymap::kp_3: return map(0x59); - case keymap::kp_4: return map(0x53); - case keymap::kp_5: return map(0x54); - case keymap::kp_6: return map(0x55); - case keymap::kp_7: return map(0x4f); - case keymap::kp_8: return map(0x50); - case keymap::kp_9: return map(0x51); - - case keymap::kp_plus: return map(0x56); - case keymap::kp_minus: return map(0x52); - case keymap::kp_mul: return map(0x3f); - case keymap::kp_div: return map(0x70); - case keymap::kp_enter: return map(0x6c); - - case keymap::num_lock: return map(0x4d); - case keymap::caps_lock: return map(0x42); - - case keymap::up: return map(0x62); - case keymap::down: return map(0x68); - case keymap::left: return map(0x64); - case keymap::right: return map(0x66); - - case keymap::tab: return map(0x17); - case keymap::enter: return map(0x24); - case keymap::space: return map(0x41); - - case keymap::lctrl: return map(0x25); - case keymap::rctrl: return map(0x6d); - case keymap::lalt: return map(0x40); - case keymap::ralt: return map(0x71); - case keymap::lshift: return map(0x32); - case keymap::rshift: return map(0x3e); - case keymap::lsuper: return map(0x73); - case keymap::rsuper: return map(0x74); - case keymap::menu: return map(0x75); - } - - #undef map - return false; - } - - void clear_input() { - memset(keymap, 0, sizeof keymap); - } - - void poll() { - XQueryKeymap(display, keymap); - } - - void init() { - display = XOpenDisplay(0); - } - - void term() { - } - - pInputX(InputX &self_) : self(self_) {} -}; - -bool InputX::key_down(uint16 key) { return p.key_down(key); } -void InputX::clear_input() { p.clear_input(); } -void InputX::poll() { p.poll(); } -void InputX::init() { p.init(); } -void InputX::term() { p.term(); } -InputX::InputX() : p(*new pInputX(*this)) {} -InputX::~InputX() { delete &p; } diff --git a/src/ui/vai/input/input.x.h b/src/ui/vai/input/input.x.h deleted file mode 100644 index 3ff94b29..00000000 --- a/src/ui/vai/input/input.x.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef INPUT_X_H -#define INPUT_X_H - -#include "../input.h" - -class pInputX; - -class InputX : public Input { -public: - bool key_down(uint16 key); - - void clear_input(); - void poll(); - void init(); - void term(); - - InputX(); - ~InputX(); - -private: - pInputX &p; -}; - -#endif //ifndef INPUT_X_H diff --git a/src/ui/vai/video/video.direct3d.h b/src/ui/vai/video/video.direct3d.h deleted file mode 100644 index e2cdc7ce..00000000 --- a/src/ui/vai/video/video.direct3d.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef VIDEO_DIRECT3D_H -#define VIDEO_DIRECT3D_H - -#include "../video.h" - -class pVideoD3D; - -class VideoD3D : public Video { -public: - bool cap(Setting); - uintptr_t get(Setting); - bool set(Setting, uintptr_t); - - bool lock(uint16 *&data, uint &pitch); - void unlock(); - - void clear_video(); - void refresh(uint width, uint height); - void init(); - void term(); - - VideoD3D(); - ~VideoD3D(); - -private: - pVideoD3D &p; -}; - -#endif //ifndef VIDEO_DIRECT3D_H diff --git a/src/ui/vai/video/video.directdraw.h b/src/ui/vai/video/video.directdraw.h deleted file mode 100644 index 304f123b..00000000 --- a/src/ui/vai/video/video.directdraw.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef VIDEO_DIRECTDRAW_H -#define VIDEO_DIRECTDRAW_H - -#include "../video.h" - -class pVideoDD; - -class VideoDD : public Video { -public: - bool cap(Setting); - uintptr_t get(Setting); - bool set(Setting, uintptr_t); - - bool lock(uint16 *&data, uint &pitch); - void unlock(); - - void clear_video(); - void refresh(uint width, uint height); - void init(); - void term(); - - VideoDD(); - ~VideoDD(); - -private: - pVideoDD &p; -}; - -#endif //ifndef VIDEO_DIRECTDRAW_H diff --git a/src/ui/vai/video/video.gtk.cpp b/src/ui/vai/video/video.gtk.cpp deleted file mode 100644 index 7e862e61..00000000 --- a/src/ui/vai/video/video.gtk.cpp +++ /dev/null @@ -1,120 +0,0 @@ -#include "video.gtk.h" - -#include -#include -#include -#include - -class pVideoGTK { -public: - VideoGTK &self; - GtkWidget *widget; - uint16 *buffer; - uint8 *gdkbuffer; - - struct { - Window handle; - } settings; - - bool cap(Video::Setting setting) { - if(setting == Video::Handle) return false; - return false; - } - - uintptr_t get(Video::Setting setting) { - if(setting == Video::Handle) return settings.handle; - return false; - } - - bool set(Video::Setting setting, uintptr_t param) { - if(setting == Video::Handle) { - settings.handle = param; - return false; - } - return false; - } - - bool lock(uint16 *&data, uint &pitch) { - pitch = 1024 * 2; - return data = buffer; - } - - void unlock() { - } - - void refresh(uint r_width, uint r_height) { - for(uint y = 0; y < r_height; y++) { - uint8 *dest = gdkbuffer + y * 1024 * 3; - uint16 *src = buffer + y * 1024; - for(uint x = 0; x < r_width; x++) { - uint32 p = *src++; - uint32 pix = ((p & 0xf800) << 8) | ((p & 0x07e0) << 5) | ((p & 0x001f) << 3); - *dest++ = pix >> 16; - *dest++ = pix >> 8; - *dest++ = pix; - } - } - - gdk_draw_rgb_image(GDK_DRAWABLE(widget->window), - widget->style->fg_gc[GTK_WIDGET_STATE(widget)], - 0, 0, r_width, r_height, - GDK_RGB_DITHER_NONE, gdkbuffer, 1024 * 3); - } - - void init_no_handle() { - GdkColor color; - color.pixel = color.red = color.green = color.blue = 0; - GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL); - gtk_window_set_title(GTK_WINDOW(window), "video.gtk"); - gtk_window_set_resizable(GTK_WINDOW(window), false); - gtk_widget_set_size_request(window, 512, 480); - GtkWidget *container = gtk_fixed_new(); - gtk_widget_set_size_request(container, 512, 480); - gtk_container_add(GTK_CONTAINER(window), container); - widget = gtk_drawing_area_new(); - gtk_fixed_put(GTK_FIXED(container), widget, 0, 0); - gtk_widget_set_size_request(widget, 512, 480); - gtk_widget_modify_bg(widget, GTK_STATE_NORMAL, &color); - gtk_widget_modify_bg(container, GTK_STATE_NORMAL, &color); - gtk_widget_modify_bg(window, GTK_STATE_NORMAL, &color); - gtk_widget_show(widget); - gtk_widget_show(container); - gtk_widget_show(window); - - if(settings.handle) { - /* below does not work, sadly ... - XReparentWindow( - GDK_WINDOW_XDISPLAY(window->window), - GDK_WINDOW_XWINDOW(window->window), - settings.handle, 0, 0); - */ - } - } - - void init() { - buffer = (uint16*)malloc(1024 * 1024 * 2); - gdkbuffer = (uint8*) malloc(1024 * 1024 * 3); - - init_no_handle(); - } - - void term() { - safe_free(buffer); - safe_free(gdkbuffer); - } - - pVideoGTK(VideoGTK &self_) : self(self_) { - settings.handle = 0; - } -}; - -bool VideoGTK::cap(Setting setting) { return p.cap(setting); } -uintptr_t VideoGTK::get(Setting setting) { return p.get(setting); } -bool VideoGTK::set(Setting setting, uintptr_t param) { return p.set(setting, param); } -bool VideoGTK::lock(uint16 *&data, uint &pitch) { return p.lock(data, pitch); } -void VideoGTK::unlock() { p.unlock(); } -void VideoGTK::refresh(uint width, uint height) { p.refresh(width, height); } -void VideoGTK::init() { p.init(); } -void VideoGTK::term() { p.term(); } -VideoGTK::VideoGTK() : p(*new pVideoGTK(*this)) {} -VideoGTK::~VideoGTK() { delete &p; } diff --git a/src/ui/vai/video/video.gtk.h b/src/ui/vai/video/video.gtk.h deleted file mode 100644 index 3014e7b5..00000000 --- a/src/ui/vai/video/video.gtk.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef VIDEO_GTK_H -#define VIDEO_GTK_H - -#include "../video.h" - -class pVideoGTK; - -class VideoGTK : public Video { -public: - bool cap(Setting); - uintptr_t get(Setting); - bool set(Setting, uintptr_t); - - bool lock(uint16 *&data, uint &pitch); - void unlock(); - - void refresh(uint width, uint height); - void init(); - void term(); - - VideoGTK(); - ~VideoGTK(); - -private: - pVideoGTK &p; -}; - -#endif //ifndef VIDEO_GTK_H diff --git a/src/ui/vai/video/video.xv.h b/src/ui/vai/video/video.xv.h deleted file mode 100644 index 816a587e..00000000 --- a/src/ui/vai/video/video.xv.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef VIDEO_XV_H -#define VIDEO_XV_H - -#include "../video.h" - -class pVideoXv; - -class VideoXv : public Video { -public: - bool cap(Setting); - uintptr_t get(Setting); - bool set(Setting, uintptr_t); - - bool lock(uint16 *&data, uint &pitch); - void unlock(); - - void clear_video(); - void refresh(uint width, uint height); - void init(); - void term(); - - VideoXv(); - ~VideoXv(); - -private: - pVideoXv &p; -}; - -#endif //ifndef VIDEO_XV_H diff --git a/src/ui/win/bsnes.cpp b/src/ui/win/bsnes.cpp deleted file mode 100644 index 0fb8af52..00000000 --- a/src/ui/win/bsnes.cpp +++ /dev/null @@ -1,55 +0,0 @@ -uint bSNES::get_state() { - return state; -} - -void bSNES::set_state(uint new_state) { - state = new_state; - - switch(state) { - case RUN: - SetWindowText(wMain.hwnd, BSNES_TITLE); - break; - case STOP: - uiAudio->clear_audio(); - SetWindowText(wMain.hwnd, BSNES_TITLE " (Paused)"); - break; - } - - wDebug.SetState(state); -} - -void bSNES::run() { - if(!r_mem->cart_loaded()) { - Sleep(1); - return; - } - - switch(state) { - case RUN: - snes.runtoframe(); - video_run(); - break; - case STOP: - Sleep(1); - break; - } -} - -void bSNES::video_run() { - if(r_ppu->status.frames_updated) { - char s[512], t[512]; - r_ppu->status.frames_updated = false; - if((bool)config::misc.show_fps == true) { - sprintf(s, "%s : %d fps", BSNES_TITLE, r_ppu->status.frames_executed); - if(wMain.frameskip != 0) { - sprintf(t, " (%d frames)", r_ppu->status.frames_rendered); - strcat(s, t); - } - SetWindowText(wMain.hwnd, s); - } - } - - wMain.frameskip_pos++; - wMain.frameskip_pos %= (wMain.frameskip + 1); - r_ppu->enable_renderer(wMain.frameskip_pos == 0); -} diff --git a/src/ui/win/bsnes.h b/src/ui/win/bsnes.h deleted file mode 100644 index e816420c..00000000 --- a/src/ui/win/bsnes.h +++ /dev/null @@ -1,11 +0,0 @@ -class bSNES { -public: -enum { RUN, STOP }; -uint state; - uint get_state(); - void set_state(uint new_state); - void run(); - void video_run(); - - bSNES() { state = RUN; } -} bsnes; diff --git a/src/ui/win/config.cpp b/src/ui/win/config.cpp deleted file mode 100644 index f34fc744..00000000 --- a/src/ui/win/config.cpp +++ /dev/null @@ -1,25 +0,0 @@ -namespace config { - -struct Debugger { - static Setting console_lines; -} debugger; -Setting Debugger::console_lines(&config_file, "debugger.console_lines", "Number of lines buffered for debugger console", - 100, Setting::DEC); - -struct Misc { - static Setting image_format; - static Setting window_style; - static Setting show_fps; - static Setting config_window_alpha_level; -} misc; -Setting Misc::image_format(&config_file, "misc.image_format", "Image format for screenshots\n" - "Valid formats: \"bmp\", \"png\", \"jpg\"", "png"); -Setting Misc::window_style(&config_file, "misc.window_style", "Window style for main emulation window", - "titlebar|frame|minimize|dragmove"); -Setting Misc::show_fps(&config_file, "misc.show_fps", "Show framerate", true, Setting::TRUE_FALSE); -Setting Misc::config_window_alpha_level(&config_file, "misc.config_window_alpha_level", - "Alpha level (opacity) of configuration window\n" - "Value must be between 64 (25% opaque, 75% transparent) and 255 (100% opaque)", - 255, Setting::DEC); - -}; diff --git a/src/ui/win/debugger/debugger.cpp b/src/ui/win/debugger/debugger.cpp deleted file mode 100644 index 4f03f610..00000000 --- a/src/ui/win/debugger/debugger.cpp +++ /dev/null @@ -1,105 +0,0 @@ -#include "ui_debugger.cpp" -#include "ui_tracer.cpp" -#include "ui_memory.cpp" - -void init_debugger() { - wDebug.SetIcon(100); - wDebug.Create(0, "bsnes_debug", "title|minimize", 0, 0, 735, 350, "bsnes Debugger"); - wDebug.MoveToBottom(); - wDebug.MoveToLeft(); - - wTracer.SetIcon(100); - wTracer.Create(0, "bsnes_tracer", "title|minimize", 0, 0, 335, 160, "bsnes Tracer"); - wTracer.Center(); - - wMemory.SetIcon(100); - wMemory.Create(0, "bsnes_memory", "title|minimize", 0, 0, 500, 245, "bsnes Memory Editor"); - wMemory.Center(); -} - -void setup_debugger() { - wDebug.Setup(); - wTracer.Setup(); - wMemory.Setup(); -} - -bool Debugger::active() { return status.active; } - -void Debugger::activate() { - if(status.active == true)return; - status.active = true; - - bsnes.set_state(bSNES::STOP); - wDebug.Show(); - wMain.CheckMenuItem(MENU_SETTINGS_DEBUGGER, true); -} - -void Debugger::deactivate() { - if(status.active == false)return; - status.active = false; - - wDebug.Hide(); - wTracer.Hide(); - wMemory.Hide(); - wMain.CheckMenuItem(MENU_SETTINGS_DEBUGGER, false); - bsnes.set_state(bSNES::RUN); -} - -void Debugger::refresh() { - wMemory.Refresh(); -} - -uint8 Debugger::read(uint8 mode, uint32 addr) { -uint8 r = 0x00; - status.debugger_access = true; - switch(mode) { - case DRAM: { - addr &= 0xffffff; - if(!(addr & 0x400000) && (addr & 0xffff) >= 0x2000 && (addr & 0xffff) <= 0x5fff)break; - r = r_mem->read(addr); - } break; - case SPCRAM: - r = r_smp->spcram[addr & 0xffff]; - break; - case VRAM: - r = r_ppu->vram_read(addr & 0xffff); - break; - case OAM: - r = r_ppu->oam_read(addr & 0x03ff); - break; - case CGRAM: - r = r_ppu->cgram_read(addr & 0x01ff); - break; - } - status.debugger_access = false; - return r; -} - -void Debugger::write(uint8 mode, uint32 addr, uint8 data) { - status.debugger_access = true; - switch(mode) { - case DRAM: - r_mem->cart_write_protect(false); - r_mem->write(addr & 0xffffff, data); - r_mem->cart_write_protect(true); - break; - case SPCRAM: - r_smp->spcram[addr & 0xffff] = data; - break; - case VRAM: - r_ppu->vram_write(addr & 0xffff, data); - break; - case OAM: - r_ppu->oam_write(addr & 0x03ff, data); - break; - case CGRAM: - r_ppu->cgram_write(addr & 0x01ff, data); - break; - } - status.debugger_access = false; -} - -Debugger::Debugger() { - status.active = false; - status.debugger_access = false; -} diff --git a/src/ui/win/debugger/debugger.h b/src/ui/win/debugger/debugger.h deleted file mode 100644 index 6b70ec8a..00000000 --- a/src/ui/win/debugger/debugger.h +++ /dev/null @@ -1,22 +0,0 @@ -class Debugger { -public: -struct { - bool active; - bool debugger_access; -} status; - - bool active(); - void activate(); - void deactivate(); - void refresh(); - -enum { DRAM, SPCRAM, VRAM, OAM, CGRAM }; - uint8 read(uint8 mode, uint32 addr); - void write(uint8 mode, uint32 addr, uint8 data); - - Debugger(); -} debugger; - -#include "ui_debugger.h" -#include "ui_tracer.h" -#include "ui_memory.h" diff --git a/src/ui/win/debugger/ui_debugger.cpp b/src/ui/win/debugger/ui_debugger.cpp deleted file mode 100644 index d7aef3c2..00000000 --- a/src/ui/win/debugger/ui_debugger.cpp +++ /dev/null @@ -1,131 +0,0 @@ -bool DebugWindow::Event(EventInfo &info) { - switch(info.event_id) { - - case EVENT_CLOSE: { - debugger.deactivate(); - return true; - } break; - - case EVENT_CLICKED: { - if(info.control == &Run) { - if(bsnes.get_state() == bSNES::RUN) { - bsnes.set_state(bSNES::STOP); - } else if(bsnes.get_state() == bSNES::STOP) { - bsnes.set_state(bSNES::RUN); - } - } else if(info.control == &Tracer) { - wTracer.Show(); - } else if(info.control == &Memory) { - wMemory.Show(); - } - } break; - - } - - return false; -} - -void DebugWindow::Update() { - if(Visible() == false)return; - -char t[250 * 132]; - sprintf(t, ""); - for(uint i = 0; i < buffer.count; i++) { - strcat(t, buffer.line[i]); - if(i != buffer.count - 1)strcat(t, "\r\n"); - } - Console.SetText(t); - Console.SetSelection(0, -1); //scroll cursor to bottom of window -} - -void DebugWindow::Print(uint source, const char *str) { - if(!hwnd)return; - - switch(source) { - case source::none: - break; - case source::debug: - if(output.debug == false)return; - break; - case source::cpu: - if(output.cpu == false)return; - break; - case source::smp: - if(output.smp == false)return; - break; - } - - for(uint i = 0; i < buffer.count - 1; i++) { - strcpy(buffer.line[i], buffer.line[i + 1]); - } - - strcpy(buffer.line[buffer.count - 1], str); -char *t = buffer.line[buffer.count - 1]; - if(strlen(t) > 100) { - t[ 97] = '.'; - t[ 98] = '.'; - t[ 99] = '.'; - t[100] = 0; - } - Update(); -} - -void DebugWindow::Clear() { - for(uint i = 0; i < buffer.count; i++) { - strcpy(buffer.line[i], ""); - } - Console.SetText(""); -} - -//called by bSNES::set_state() to update debug UI -void DebugWindow::SetState(uint state) { - if(Visible() == false)return; - - switch(state) { - case bSNES::RUN: Run.SetText(" Stop"); break; - case bSNES::STOP: Run.SetText(" Run"); break; - } -} - -void DebugWindow::Show() { - Run.SetText((bsnes.get_state() == bSNES::RUN) ? " Stop" : " Run"); - Window::Show(); - Update(); -} - -void DebugWindow::Setup() { -int x = 5, y = 5; -static int bnwidth = 80; - Run.Create(this, "visible|left", x, y, bnwidth, 20, " Run"); - x += bnwidth; - Tracer.Create(this, "visible|left", x, y, bnwidth, 20, " Tracer"); - x += bnwidth; - Memory.Create(this, "visible|left", x, y, bnwidth, 20, " Memory"); - x += bnwidth; - - x = 5; - y += 25; - - Console.Create(this, "visible|edge|multiline|vscroll|readonly", x, y, 725, 290); - Console.SetFont(global::fwf); - Console.SetBackgroundColor(32, 32, 32); - Console.SetTextColor(255, 255, 255); - y += 293; - - Command.Create(this, "visible|edge|disabled", x, y, 725, 22, ""); - Command.SetFont(global::fwf); - Command.SetBackgroundColor(32, 32, 32); - Command.SetTextColor(255, 255, 255); - y += 22; - - buffer.count = minmax<20, 250>((uint)config::debugger.console_lines); - Clear(); -} - -DebugWindow::DebugWindow() { - output.debug = true; - output.cpu = true; - output.smp = true; -} - -DebugWindow::~DebugWindow() {} diff --git a/src/ui/win/debugger/ui_debugger.h b/src/ui/win/debugger/ui_debugger.h deleted file mode 100644 index b8368be6..00000000 --- a/src/ui/win/debugger/ui_debugger.h +++ /dev/null @@ -1,34 +0,0 @@ -class DebugWindow : public Window { -public: -Button Run; -Button Tracer; -Button Memory; - -Editbox Console; -Editbox Command; - -struct { - uint count; - char line[250][512]; -} buffer; - -struct { - bool debug; - bool cpu; - bool smp; -} output; - - bool Event(EventInfo &info); - - void Update(); - void Print(uint source, const char *str); - void Clear(); - - void SetState(uint state); - - void Show(); - void Setup(); - - DebugWindow(); - ~DebugWindow(); -} wDebug; diff --git a/src/ui/win/debugger/ui_memory.cpp b/src/ui/win/debugger/ui_memory.cpp deleted file mode 100644 index 55813dea..00000000 --- a/src/ui/win/debugger/ui_memory.cpp +++ /dev/null @@ -1,270 +0,0 @@ -namespace NSMemoryEditor { -WNDPROC wndproc_old_memory_view = 0; - -long __stdcall wndproc_new_memory_view(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { - return wMemory.wndproc_view(hwnd, msg, wparam, lparam); -} - -}; - -long MemoryEditor::wndproc_view(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { - switch(msg) { - - case WM_KEYDOWN: { - if(r_mem->cart_loaded() == false)break; - - int pos, len, xpos, ypos, t, data, read; - pos = SendMessage(hwnd, EM_GETSEL, 0, 0); - pos = LOWORD(pos); - ypos = pos / 57; - xpos = pos % 57; - - if(wparam == VK_UP) { - if(ypos != 0)break; - status.addr -= 16; - status.addr &= status.mask; - Refresh(); - SendMessage(hwnd, EM_SETSEL, pos, pos); - break; - } - - if(wparam == VK_DOWN) { - if(ypos != 15)break; - status.addr += 16; - status.addr &= status.mask; - Refresh(); - SendMessage(hwnd, EM_SETSEL, pos, pos); - break; - } - - if(wparam == VK_PRIOR) { - if(KeyDown(VK_CONTROL))len = 65536; - else if(KeyDown(VK_SHIFT))len = 4096; - else len = 256; - status.addr -= len; - status.addr &= status.mask; - Refresh(); - SendMessage(hwnd, EM_SETSEL, pos, pos); - break; - } - - if(wparam == VK_NEXT) { - if(KeyDown(VK_CONTROL))len = 65536; - else if(KeyDown(VK_SHIFT))len = 4096; - else len = 256; - status.addr += len; - status.addr &= status.mask; - Refresh(); - SendMessage(hwnd, EM_SETSEL, pos, pos); - break; - } - - if(xpos < 8)break; - xpos -= 8; - t = xpos % 3; - xpos /= 3; - if(xpos > 15)break; - - if(wparam >= '0' && wparam <= '9')read = wparam - '0'; - else if(wparam >= 'A' && wparam <= 'F')read = wparam - 'A' + 0x0a; - else if(wparam >= 'a' && wparam <= 'f')read = wparam - 'a' + 0x0a; - else break; - - data = debugger.read(status.mode, status.addr + ypos * 16 + xpos); - if(t == 0) { - data = (read << 4) | (data & 0x0f); - pos++; - } else { - data = (data & 0xf0) | (read); - if(xpos == 15) { //go to new line - if(ypos == 15) { //so long as we aren't on the last line - pos++; - } else { - pos += 11; - } - } else { //go to next byte - pos += 2; - } - } - debugger.write(status.mode, status.addr + ypos * 16 + xpos, data); - Refresh(); - SendMessage(hwnd, EM_SETSEL, pos, pos); - } break; - - } - - if(!NSMemoryEditor::wndproc_old_memory_view)return DefWindowProc(hwnd, msg, wparam, lparam); - return CallWindowProc(NSMemoryEditor::wndproc_old_memory_view, hwnd, msg, wparam, lparam); -} - -bool MemoryEditor::Event(EventInfo &info) { - switch(info.event_id) { - - case EVENT_CLOSE: { - Hide(); - return true; - } break; - - case EVENT_CHANGED: - case EVENT_CLICKED: { - if(info.control == &Mode && info.event_id == EVENT_CHANGED) { - switch(Mode.GetSelection()) { - case 0: - status.mode = Debugger::DRAM; - status.addr = 0x7e0000; - status.mask = 0xffffff; - break; - case 1: - status.mode = Debugger::DRAM; - status.addr = 0x008000; - status.mask = 0xffffff; - break; - case 2: - status.mode = Debugger::DRAM; - status.addr = 0x700000; - status.mask = 0xffffff; - break; - case 3: - status.mode = Debugger::SPCRAM; - status.addr = 0x0000; - status.mask = 0xffff; - break; - case 4: - status.mode = Debugger::VRAM; - status.addr = 0x0000; - status.mask = 0xffff; - break; - case 5: - status.mode = Debugger::OAM; - status.addr = 0x0000; - status.mask = 0x03ff; - break; - case 6: - status.mode = Debugger::CGRAM; - status.addr = 0x0000; - status.mask = 0x01ff; - break; - } - - Refresh(); - } else if(info.control == &GotoAddr && info.event_id == EVENT_CHANGED) { - char t[16 + 1]; - GotoAddr.GetText(t, 16); - status.addr = strhex(t) & status.mask; - Refresh(); - } else if(info.control == &EditMem) { - char t[16 + 1]; - Offset.GetText(t, 16); - uint32 addr = strhex(t) & status.mask; - Data.GetText(t, 16); - debugger.write(status.mode, addr, strhex(t)); - Refresh(); - } else if(info.control == &ExportMem) { - ExportMemory(); - } else if(info.control == &Update) { - Refresh(); - } - } break; - - } - - return false; -} - -void MemoryEditor::Refresh() { -char s[4096], t[256]; - if(r_mem->cart_loaded() == false) { - View.SetText(""); - return; - } - if(Visible() == false)return; - - strcpy(s, ""); - for(int y = 0; y < 16; y++) { - sprintf(t, "%0.6x: ", (status.addr + y * 16) & status.mask); - strcat(s, t); - for(int x = 0; x < 16; x++) { - sprintf(t, "%0.2x", debugger.read(status.mode, status.addr + y * 16 + x)); - strcat(s, t); - if(x != 15)strcat(s, " "); - } - if(y != 15)strcat(s, "\r\n"); - } - View.SetText(s); -} - -void MemoryEditor::ExportMemory() { -FILE *fp; - fp = fopen("dram.bin", "wb"); - if(fp) { - for(int i = 0x7e0000; i <= 0x7fffff; i++) { - fputc(debugger.read(Debugger::DRAM, i), fp); - } - fclose(fp); - } - fp = fopen("spcram.bin", "wb"); - if(fp) { - for(int i = 0; i <= 0xffff; i++) { - fputc(debugger.read(Debugger::SPCRAM, i), fp); - } - fclose(fp); - } - fp = fopen("vram.bin", "wb"); - if(fp) { - for(int i = 0; i <= 0xffff; i++) { - fputc(debugger.read(Debugger::VRAM, i), fp); - } - fclose(fp); - } - fp = fopen("oam.bin", "wb"); - if(fp) { - for(int i = 0; i <= 0x03ff; i++) { - fputc(debugger.read(Debugger::OAM, i), fp); - } - fclose(fp); - } - fp = fopen("cgram.bin", "wb"); - if(fp) { - for(int i = 0; i <= 0x01ff; i++) { - fputc(debugger.read(Debugger::CGRAM, i), fp); - } - fclose(fp); - } -} - -void MemoryEditor::Show() { -//Window will not refresh unless it is visible, so call Show() first - Window::Show(); - Refresh(); -} - -void MemoryEditor::Setup() { - View.Create(this, "visible|edge|multiline|readonly", 5, 5, 395, 235); - View.SetFont(global::fwf); - View.SetBackgroundColor(32, 32, 32); - View.SetTextColor(255, 255, 255); - NSMemoryEditor::wndproc_old_memory_view = (WNDPROC)GetWindowLong(View.hwnd, GWL_WNDPROC); - SetWindowLong(View.hwnd, GWL_WNDPROC, (long)NSMemoryEditor::wndproc_new_memory_view); - - Mode.Create(this, "visible", 405, 5, 90, 200, "DRAM|ROM|SRAM|SPCRAM|VRAM|OAM|CGRAM"); - GotoLabel.Create(this, "visible", 405, 26 + 4, 35, 15, "Goto:"); - GotoAddr.Create(this, "visible|edge", 440, 26, 55, 20, "000000"); - GotoAddr.SetFont(global::fwf); - - OffsetLabel.Create(this, "visible", 405, 50, 90, 15, "Offset: Data:"); - Offset.Create(this, "visible|edge", 405, 65, 55, 20, "000000"); - Offset.SetFont(global::fwf); - Data.Create(this, "visible|edge", 460, 65, 35, 20, "00"); - Data.SetFont(global::fwf); - EditMem.Create(this, "visible", 405, 85, 90, 20, "Edit Memory"); - ExportMem.Create(this, "visible", 405, 105, 90, 20, "Export Memory"); - - AutoUpdate.Create(this, "visible|disabled", 405, 203, 90, 15, "Auto Update"); - Update.Create(this, "visible", 405, 220, 90, 20, "Update"); -} - -MemoryEditor::MemoryEditor() { - status.mode = Debugger::DRAM; - status.addr = 0x000000; - status.mask = 0xffffff; -} diff --git a/src/ui/win/debugger/ui_memory.h b/src/ui/win/debugger/ui_memory.h deleted file mode 100644 index 6a15f387..00000000 --- a/src/ui/win/debugger/ui_memory.h +++ /dev/null @@ -1,40 +0,0 @@ -enum { - MEMORYMODE_DRAM = 0, - MEMORYMODE_ROM = 1, - MEMORYMODE_SRAM = 2, - MEMORYMODE_SPCRAM = 3, - MEMORYMODE_VRAM = 4, - MEMORYMODE_OAM = 5, - MEMORYMODE_CGRAM = 6, -}; - -class MemoryEditor : public Window { -public: -Editbox View; -Combobox Mode; -Label GotoLabel; -Editbox GotoAddr; -Label OffsetLabel; -Editbox Offset; -Editbox Data; -Button EditMem; -Button ExportMem; -Checkbox AutoUpdate; -Button Update; - -struct { - uint8 mode; - uint32 addr, mask; -} status; - - bool Event(EventInfo &info); - - long wndproc_view(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam); - void Refresh(); - void ExportMemory(); - - void Show(); - void Setup(); - - MemoryEditor(); -} wMemory; diff --git a/src/ui/win/debugger/ui_tracer.cpp b/src/ui/win/debugger/ui_tracer.cpp deleted file mode 100644 index bd4f934d..00000000 --- a/src/ui/win/debugger/ui_tracer.cpp +++ /dev/null @@ -1,48 +0,0 @@ -bool TracerSettings::Event(EventInfo &info) { - switch(info.event_id) { - - case EVENT_CLOSE: { - Hide(); - return true; - } break; - - case EVENT_CLICKED: { - if(info.control == &TracerEnable) { - tracer.enable(!tracer.enabled()); - TracerEnable.SetText("%s", tracer.enabled() ? "Disable Tracer" : "Enable Tracer"); - } else if(info.control == &CPUTraceOp) { - tracer.cpuop_enable(CPUTraceOp.Checked()); - } else if(info.control == &CPUTraceOpMask) { - tracer.cpuopmask_enable(CPUTraceOpMask.Checked()); - } else if(info.control == &CPUTraceDMA) { - tracer.cpudma_enable(CPUTraceDMA.Checked()); - } else if(info.control == &SMPTraceOp) { - tracer.smpop_enable(SMPTraceOp.Checked()); - } else if(info.control == &SMPTraceOpMask) { - tracer.smpopmask_enable(SMPTraceOpMask.Checked()); - } - } break; - - } - - return false; -} - -void TracerSettings::Setup() { -int x = 5, y = 5; - TracerEnable.Create(this, "visible", x, y, 120, 25); - TracerEnable.SetText("%s", tracer.enabled() ? "Disable Tracer" : "Enable Tracer"); - y += 30; - - CPUGroup.Create(this, "visible", x, y, 160, 120, "S-CPU"); - CPUTraceOp.Create(this, "visible|auto", x + 5, y + 15, 150, 15, "Opcodes"); - CPUTraceOpMask.Create(this, "visible|auto", x + 5, y + 30, 150, 15, "Opcode mask"); - CPUTraceDMA.Create(this, "visible|auto", x + 5, y + 45, 150, 15, "DMA"); - CPUTraceHDMA.Create(this, "visible|auto|disabled", x + 5, y + 60, 150, 15, "HDMA"); - x += 165; - - SMPGroup.Create(this, "visible", x, y, 160, 120, "S-SMP"); - SMPTraceOp.Create(this, "visible|auto", x + 5, y + 15, 150, 15, "Opcodes"); - SMPTraceOpMask.Create(this, "visible|auto", x + 5, y + 30, 150, 15, "Opcode mask"); - x += 165; -} diff --git a/src/ui/win/debugger/ui_tracer.h b/src/ui/win/debugger/ui_tracer.h deleted file mode 100644 index 6ff90f6c..00000000 --- a/src/ui/win/debugger/ui_tracer.h +++ /dev/null @@ -1,18 +0,0 @@ -class TracerSettings : public Window { -public: -Button TracerEnable; - -Groupbox CPUGroup; -Checkbox CPUTraceOp; -Checkbox CPUTraceOpMask; -Checkbox CPUTraceDMA; -Checkbox CPUTraceHDMA; - -Groupbox SMPGroup; -Checkbox SMPTraceOp; -Checkbox SMPTraceOpMask; - - bool Event(EventInfo &info); - - void Setup(); -} wTracer; diff --git a/src/ui/win/event.cpp b/src/ui/win/event.cpp deleted file mode 100644 index 7ef20593..00000000 --- a/src/ui/win/event.cpp +++ /dev/null @@ -1,145 +0,0 @@ -/***** - * event namespace - * - * Used to invoke common functions from anywhere within - * the bsnes user interface. - * For example, when unloading a ROM image, many things - * must happen. The video, audio, and input buffers must - * be cleared, the debugger must be disabled, and the - * main window must be updated. Rather than binding this - * functionality inside the main window class, it is - * added here. This then makes it possible to easily add - * an option to the main window, as well as a key binding, - * as well as an option elsewhere to unload the ROM. - * - * The main purpose of the event namespace is to simplify - * binding common functions to user-specified keyboard - * combinations. - *****/ - -namespace event { - -void update_video_settings() { -uint width = 256; -uint height = config::video.region == 0 ? 224 : 239; -uint multiplier = minmax<1, 5>(uint(config::video.multiplier)); - width *= multiplier; - height *= multiplier; - if(config::video.aspect_correction == true) { - width = uint( double(width) * 8.0 / 7.0 ); - } - wMain.Resize(width, height, true); -} - -bool load_rom(char *fn) { -OPENFILENAME ofn; -stringarray dir; - strcpy(fn, ""); - strcpy(dir, config::path.rom); - replace(dir, "\\", "/"); - if(strlen(dir) && !strend(dir, "/")) { strcat(dir, "/"); } - -//append base_path if rom_path is relative - if(strbegin(dir, "./")) { - strltrim(dir, "./"); - strcpy(dir[1], dir[0]); - strcpy(dir[0], config::path.base); - strcat(dir[0], dir[1]); - } - -//GetOpenFileName doesn't like forward slashes in its directory path - replace(dir, "/", "\\"); - - memset(&ofn, 0, sizeof(ofn)); - - ofn.lStructSize = sizeof(ofn); - ofn.hwndOwner = wMain.hwnd; - ofn.lpstrFilter = "SNES ROM Images (*.smc;*.sfc;*.swc;*.fig;*.ufo;*.gd3;*.078;*.st" -#ifdef GZIP_SUPPORT - ";.gz;.z;.zip" -#endif -#ifdef JMA_SUPPORT - ";.jma" -#endif - ")\0" - "*.smc;*.sfc;*.swc;*.fig;*.ufo;*.gd3;*.078;*.st" -#ifdef GZIP_SUPPORT - ";*.gz;*.z;*.zip" -#endif -#ifdef JMA_SUPPORT - ";*.jma" -#endif - "\0" - "All Files (*.*)\0" - "*.*\0"; - ofn.lpstrFile = fn; - ofn.lpstrInitialDir = strptr(dir); - ofn.nMaxFile = MAX_PATH; - ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST; - ofn.lpstrDefExt = "smc"; - - if(!GetOpenFileName(&ofn))return false; - return true; -} - -void load_rom_normal() { -char fn[MAX_PATH]; - if(load_rom(fn) == false)return; - - if(cartridge.loaded() == true)cartridge.unload(); - wDebug.Clear(); - - cartridge.load_begin(Cartridge::CART_NORMAL); - cartridge.load(fn); - cartridge.load_end(); - snes.power(); - - wCheatEditor.Refresh(); -} - -void load_rom_st() { -char fn[MAX_PATH]; - if(load_rom(fn) == false)return; - - if(cartridge.loaded() == true)cartridge.unload(); - wDebug.Clear(); - - cartridge.load_begin(Cartridge::CART_ST); - cartridge.load(fn); - cartridge.load_end(); - snes.power(); - - wCheatEditor.Refresh(); -} - -void load_rom_stdual() { -char fn_a[MAX_PATH], fn_b[MAX_PATH]; - if(load_rom(fn_a) == false)return; - if(load_rom(fn_b) == false)return; - - if(cartridge.loaded() == true)cartridge.unload(); - wDebug.Clear(); - - cartridge.load_begin(Cartridge::CART_STDUAL); - cartridge.load(fn_a); - cartridge.load(fn_b); - cartridge.load_end(); - snes.power(); - - wCheatEditor.Refresh(); -} - -void unload_rom() { - if(cartridge.loaded() == false)return; - - cartridge.unload(); - uiVideo->clear_video(); - uiAudio->clear_audio(); - uiInput->clear_input(); - SetWindowText(wMain.hwnd, BSNES_TITLE); - - debugger.refresh(); - wCheatEditor.Clear(); -} - -}; diff --git a/src/ui/win/event.h b/src/ui/win/event.h deleted file mode 100644 index e3429fed..00000000 --- a/src/ui/win/event.h +++ /dev/null @@ -1,14 +0,0 @@ -namespace event { - -void capture_screenshot(); - -void update_video_settings(); -void toggle_fullscreen(); - -void load_rom(const char *fn); -void load_rom_normal(); -void load_rom_st(); -void load_rom_stdual(); -void unload_rom(); - -}; diff --git a/src/ui/win/libwin32/libwin32.cpp b/src/ui/win/libwin32/libwin32.cpp deleted file mode 100644 index c1c001b1..00000000 --- a/src/ui/win/libwin32/libwin32.cpp +++ /dev/null @@ -1,107 +0,0 @@ -#include "libbase.h" -#include "libwin32.h" - -#include "libwin32_misc.cpp" -#include "libwin32_file.cpp" -#include "libwin32_window.cpp" -#include "libwin32_control.cpp" -#include "libwin32_label.cpp" -#include "libwin32_groupbox.cpp" -#include "libwin32_editbox.cpp" -#include "libwin32_button.cpp" -#include "libwin32_checkbox.cpp" -#include "libwin32_radiobox.cpp" -#include "libwin32_slider.cpp" -#include "libwin32_combobox.cpp" -#include "libwin32_listbox.cpp" -#include "libwin32_listview.cpp" - -void alert(char *s, ...) { -char str[4096]; -va_list args; - va_start(args, s); - vsprintf(str, s, args); - va_end(args); - MessageBox(0, str, "bsnes", MB_OK); -} - -uint GetScreenWidth() { return GetSystemMetrics(SM_CXSCREEN); } -uint GetScreenHeight() { return GetSystemMetrics(SM_CYSCREEN); } - -void ShowCursor() { - if(global::cursor_visible == false) { - global::cursor_visible = true; - ShowCursor(TRUE); - } -} - -void HideCursor() { - if(global::cursor_visible == true) { - global::cursor_visible = false; - ShowCursor(FALSE); - } -} - -void ParseStyleParam(const char *style, stringarray &output) { -string temp; - strcpy(temp, style); - strlower(temp); - replace(temp, " ", ""); - strltrim(temp, "|"); - strrtrim(temp, "|"); - replace(temp, "||", "|"); - split(output, "|", temp); -} - -long __stdcall CoreWindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { - return WindowList.WndProc(hwnd, msg, wparam, lparam); -} - -bool WindowManager::Add(Window *window) { - if(window_count >= WINDOW_LIMIT)return false; - list[window_count++] = window; - return true; -} - -long WindowManager::WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { - for(int i = 0; i < window_count; i++) { - if(list[i]->hwnd == hwnd) { - return list[i]->WndProc(msg, wparam, lparam); - } - } - - return DefWindowProc(hwnd, msg, wparam, lparam); -} - -WindowManager::WindowManager() { - window_count = 0; -} - -Font CreateFont(const char *name, uint height, const char *style) { -HDC hdc = GetDC(0); -Font font = CreateFont(-MulDiv(height, GetDeviceCaps(hdc, LOGPIXELSY), 72), - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, name); - ReleaseDC(0, hdc); - return font; -} - -libwin32_init::libwin32_init() { - WindowList.list = (Window**)malloc((WINDOW_LIMIT + 1) * sizeof(Window*)); - memset(WindowList.list, 0, (WINDOW_LIMIT + 1) * sizeof(Window*)); - - InitCommonControls(); - global::font_default = CreateFont("Tahoma", 8); - -WNDCLASS wc; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1); - wc.hCursor = LoadCursor(0, IDC_ARROW); - wc.hIcon = LoadIcon(0, IDI_APPLICATION); - wc.hInstance = GetModuleHandle(0); - wc.lpfnWndProc = CoreWindowProc; - wc.lpszClassName = "resize_class"; - wc.lpszMenuName = 0; - wc.style = CS_HREDRAW | CS_VREDRAW; - RegisterClass(&wc); -} diff --git a/src/ui/win/libwin32/libwin32.h b/src/ui/win/libwin32/libwin32.h deleted file mode 100644 index ff1fe2c8..00000000 --- a/src/ui/win/libwin32/libwin32.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - libwin32 : version 0.03 ~byuu (04/14/06) -*/ - -#ifndef __LIBWIN32 -#define __LIBWIN32 - -#include "libstring.h" - -#define WINVER 0x0400 -#define _WIN32_WINNT 0x0400 -#define _WIN32_IE 0x0400 -#include -#include -#include - -#define WINDOW_LIMIT 4095 -#define CONTROL_LIMIT 4095 - -#define WINDOWID_INDEX 10000 -#define CONTROLID_INDEX 20000 - -typedef HFONT Font; - -namespace global { -bool cursor_visible = true; -Font font_default; -}; - -void alert(char *s, ...); -uint GetScreenWidth(); -uint GetScreenHeight(); -void ShowCursor(); -void HideCursor(); -void ParseStyleParam(const char *style, stringarray &output); - -class Window; -class Control; - -#include "libwin32_window.h" -#include "libwin32_control.h" - -long __stdcall CoreWindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam); - -class WindowManager { -public: -uint window_count; -Window **list; - - long WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam); - bool Add(Window *window); - - WindowManager(); -} WindowList; - -Font CreateFont(const char *name, uint height, const char *style = ""); - -class libwin32_init { -public: - libwin32_init(); -} __libwin32_init; - -#endif diff --git a/src/ui/win/libwin32/libwin32_button.cpp b/src/ui/win/libwin32/libwin32_button.cpp deleted file mode 100644 index 7deff61a..00000000 --- a/src/ui/win/libwin32/libwin32_button.cpp +++ /dev/null @@ -1,32 +0,0 @@ -bool Button::Create(Window *parent_window, const char *style, int x, int y, int width, int height, const char *text) { - if(!parent_window)return false; - - parent = parent_window; - id = CONTROLID_INDEX + parent->control_count; - type = BUTTON; - state.ws = WS_CHILD; - state.es = 0; - state.x = x; - state.y = y; - state.width = width; - state.height = height; - -stringarray part; - ParseStyleParam(style, part); - for(int i = 0; i < count(part); i++) { - if(!strcmp(part[i], "visible"))state.ws |= WS_VISIBLE; - if(!strcmp(part[i], "disabled"))state.ws |= WS_DISABLED; - - if(!strcmp(part[i], "left"))state.ws |= BS_LEFT; - if(!strcmp(part[i], "center"))state.ws |= BS_CENTER; - if(!strcmp(part[i], "right"))state.ws |= BS_RIGHT; - } - - hwnd = CreateWindowEx(state.es, "BUTTON", text, state.ws, - state.x, state.y, state.width, state.height, - parent->hwnd, (HMENU)id, GetModuleHandle(0), 0); - if(!hwnd)return false; - - PostCreate(); - return true; -} diff --git a/src/ui/win/libwin32/libwin32_checkbox.cpp b/src/ui/win/libwin32/libwin32_checkbox.cpp deleted file mode 100644 index 77fab37f..00000000 --- a/src/ui/win/libwin32/libwin32_checkbox.cpp +++ /dev/null @@ -1,40 +0,0 @@ -bool Checkbox::Checked() { return SendMessage(hwnd, BM_GETCHECK, 0, 0); } -void Checkbox::Check(bool state) { SendMessage(hwnd, BM_SETCHECK, (WPARAM)state, 0); } -void Checkbox::Check() { Check(true); } -void Checkbox::Uncheck() { Check(false); } -void Checkbox::ToggleCheck() { Check(!Checked()); } - -bool Checkbox::Create(Window *parent_window, const char *style, int x, int y, int width, int height, const char *text) { - if(!parent_window)return false; - - parent = parent_window; - id = CONTROLID_INDEX + parent->control_count; - type = CHECKBOX; - state.ws = WS_CHILD; - state.es = 0; - state.x = x; - state.y = y; - state.width = width; - state.height = height; - -stringarray part; - ParseStyleParam(style, part); - for(int i = 0; i < count(part); i++) { - if(!strcmp(part[i], "visible"))state.ws |= WS_VISIBLE; - if(!strcmp(part[i], "disabled"))state.ws |= WS_DISABLED; - - if(!strcmp(part[i], "left"))state.ws |= BS_LEFT; - if(!strcmp(part[i], "center"))state.ws |= BS_CENTER; - if(!strcmp(part[i], "right"))state.ws |= BS_RIGHT; - if(!strcmp(part[i], "auto"))state.ws |= BS_AUTOCHECKBOX; - } - if(!(state.ws & BS_AUTOCHECKBOX))state.ws |= BS_CHECKBOX; - - hwnd = CreateWindowEx(state.es, "BUTTON", text, state.ws, - state.x, state.y, state.width, state.height, - parent->hwnd, (HMENU)id, GetModuleHandle(0), 0); - if(!hwnd)return false; - - PostCreate(); - return true; -} diff --git a/src/ui/win/libwin32/libwin32_combobox.cpp b/src/ui/win/libwin32/libwin32_combobox.cpp deleted file mode 100644 index d6083a00..00000000 --- a/src/ui/win/libwin32/libwin32_combobox.cpp +++ /dev/null @@ -1,66 +0,0 @@ -void Combobox::AddItem(const char *text) { - SendMessage(hwnd, CB_ADDSTRING, 0, (LPARAM)text); -} - -void Combobox::DeleteItem(uint id) { - SendMessage(hwnd, CB_DELETESTRING, id, 0); -} - -void Combobox::DeleteAllItems() { - SendMessage(hwnd, CB_RESETCONTENT, 0, 0); -} - -uint Combobox::GetItemCount() { - return SendMessage(hwnd, CB_GETCOUNT, 0, 0); -} - -void Combobox::SetSelection(uint id) { - SendMessage(hwnd, CB_SETCURSEL, id, 0); -} - -int Combobox::GetSelection() { - return SendMessage(hwnd, CB_GETCURSEL, 0, 0); -} - -bool Combobox::Create(Window *parent_window, const char *style, int x, int y, int width, int height, const char *text) { - if(!parent_window)return false; - - parent = parent_window; - id = CONTROLID_INDEX + parent->control_count; - type = COMBOBOX; - state.ws = WS_CHILD | CBS_DROPDOWNLIST | CBS_HASSTRINGS; - state.es = 0; - state.x = x; - state.y = y; - state.width = width; - state.height = height; - -stringarray part; - ParseStyleParam(style, part); - for(int i = 0; i < count(part); i++) { - if(!strcmp(part[i], "visible"))state.ws |= WS_VISIBLE; - if(!strcmp(part[i], "disabled"))state.ws |= WS_DISABLED; - if(!strcmp(part[i], "border"))state.ws |= WS_BORDER; - if(!strcmp(part[i], "raised"))state.ws |= WS_DLGFRAME; - - if(!strcmp(part[i], "sunken"))state.es |= WS_EX_STATICEDGE; - if(!strcmp(part[i], "edge"))state.es |= WS_EX_CLIENTEDGE; - } - - hwnd = CreateWindowEx(state.es, "COMBOBOX", text, state.ws, - state.x, state.y, state.width, state.height, - parent->hwnd, (HMENU)id, GetModuleHandle(0), 0); - if(!hwnd)return false; - - if(!strcmp(text, "") == false) { - stringarray t; - split(t, "|", text); - for(int i = 0; i < ::count(t); i++) { - AddItem(strptr(t[i])); - } - } - SetSelection(0); - - PostCreate(); - return true; -} diff --git a/src/ui/win/libwin32/libwin32_control.cpp b/src/ui/win/libwin32/libwin32_control.cpp deleted file mode 100644 index 4ec39712..00000000 --- a/src/ui/win/libwin32/libwin32_control.cpp +++ /dev/null @@ -1,99 +0,0 @@ -/* - * called after custom control type successfully creates - * control, used to initialize common control defaults - */ -void Control::PostCreate() { - SetFont(global::font_default); - parent->Add(*this); -} - -uint Control::GetID() { return id; } -uint Control::GetType() { return type; } - -void Control::SetFont(Font font) { - SendMessage(hwnd, WM_SETFONT, (WPARAM)font, 0); -} - -void Control::Show(bool do_show) { - if(do_show == true) { - ShowWindow(hwnd, SW_NORMAL); - state.ws |= WS_VISIBLE; - } else { - ShowWindow(hwnd, SW_HIDE); - state.ws &= ~WS_VISIBLE; - } -} - -bool Control::Visible() { - return !!(GetWindowLong(hwnd, GWL_STYLE) & WS_VISIBLE); -} - -void Control::Show() { Show(true); } -void Control::Hide() { Show(false); } -void Control::Focus() { SetFocus(hwnd); } - -void Control::Enable(bool do_enable) { - if(do_enable == true) { - EnableWindow(hwnd, TRUE); - state.ws &= ~WS_DISABLED; - } else { - EnableWindow(hwnd, FALSE); - state.ws |= WS_DISABLED; - } -} - -bool Control::Enabled() { - return !(GetWindowLong(hwnd, GWL_STYLE) & WS_DISABLED); -} - -void Control::Enable() { Enable(true); } -void Control::Disable() { Enable(false); } - -void Control::SetBackgroundColor(uint r, uint g, uint b) { - state.use_backcolor = true; - state.backcolor = (r << 16) | (g << 8) | b; - if(backbrush)DeleteObject((HGDIOBJ)backbrush); - backbrush = CreateSolidBrush(RGB(r, g, b)); - if(hwnd)InvalidateRect(hwnd, 0, TRUE); -} - -void Control::SetTextColor(uint r, uint g, uint b) { - state.use_textcolor = true; - state.textcolor = (r << 16) | (g << 8) | b; - if(hwnd)InvalidateRect(hwnd, 0, TRUE); -} - -const char *Control::GetText() { -static char t[256 + 1]; - GetWindowText(hwnd, t, 256); - return t; -} - -void Control::GetText(char *text, uint length) { - GetWindowText(hwnd, text, length ? length : 255); -} - -void Control::SetText(const char *text, ...) { -string str; -va_list args; - va_start(args, text); - vsprintf(str, text, args); - va_end(args); - SetWindowText(hwnd, strptr(str)); -} - -Control::Control() { - hwnd = 0; - backbrush = 0; - state.use_backcolor = false; - state.use_textcolor = false; - state.backcolor = 0; - state.textcolor = 0; -} - -Control::~Control() { - if(backbrush) { - DeleteObject((HGDIOBJ)backbrush); - backbrush = 0; - } -} diff --git a/src/ui/win/libwin32/libwin32_control.h b/src/ui/win/libwin32/libwin32_control.h deleted file mode 100644 index c4ebe025..00000000 --- a/src/ui/win/libwin32/libwin32_control.h +++ /dev/null @@ -1,186 +0,0 @@ -class Control { -public: -enum { - LABEL, - EDITBOX, - BUTTON, - CHECKBOX, - RADIOBOX, - SLIDER, - COMBOBOX, - LISTBOX, - LISTVIEW, -}; - -HWND hwnd; -HBRUSH backbrush; -Window *parent; -uint id, type; - -struct State { - uint x, y, width, height; - uint es, ws; - bool use_backcolor, use_textcolor; - uint backcolor, textcolor; -} state; - - virtual bool Create(Window *parent_window, const char *style, int x, int y, int width, int height, const char *text = "") = 0; - void PostCreate(); - - virtual void Show(bool do_show); - virtual bool Visible(); - virtual void Show(); - virtual void Hide(); - virtual void Focus(); - - virtual void Enable(bool do_enable); - virtual bool Enabled(); - virtual void Enable(); - virtual void Disable(); - - uint GetID(); - uint GetType(); - void SetBackgroundColor(uint r, uint g, uint b); - void SetTextColor(uint r, uint g, uint b); - void SetFont(Font font); - const char *GetText(); - void GetText(char *text, uint length = 0); - void SetText(const char *text, ...); - -/* Functions for all controls are defined as empty virtual functions - * inside the base control class, so that event handler can directly - * invoke derived control class functions without the need for a - * static_cast. Not the best programming practice, but nothing bad - * should result from unintentionally calling an empty function. - */ - -//Editbox - virtual void SetSelection(int begin, int end) {} - -//Checkbox, Radiobox - virtual bool Checked() { return false; } - virtual void Check(bool state) {} - virtual void Check() {} - virtual void Uncheck() {} - virtual void ToggleCheck() {} - -//Slider - virtual void SetRange(int min, int max) {} - virtual void SetPos(int pos) {} - virtual int GetPos() { return 0; } - -//Combobox, Listbox, Listview - virtual void AddItem(const char *text) {} - virtual void DeleteItem(uint id) {} - virtual void DeleteAllItems() {} - virtual uint GetItemCount() { return 0; } - virtual void SetSelection(uint id) {} - virtual int GetSelection() { return 0; } - -//Listview - virtual void AddColumn(uint align, uint width, const char *text) {} - virtual void SetItemText(uint id, const char *text) {} - - Control(); - ~Control(); -}; - -class Label : public Control { -public: - bool Create(Window *parent_window, const char *style, int x, int y, int width, int height, const char *text = ""); -}; - -class Groupbox : public Control { -public: - bool Create(Window *parent_window, const char *style, int x, int y, int width, int height, const char *text = ""); -}; - -class Editbox : public Control { -public: - bool Create(Window *parent_window, const char *style, int x, int y, int width, int height, const char *text = ""); - - void SetSelection(int begin, int end); -}; - -class Button : public Control { -public: - bool Create(Window *parent_window, const char *style, int x, int y, int width, int height, const char *text = ""); -}; - -class Checkbox : public Control { -public: - bool Create(Window *parent_window, const char *style, int x, int y, int width, int height, const char *text = ""); - - bool Checked(); - void Check(bool state); - void Check(); - void Uncheck(); - void ToggleCheck(); -}; - -class Radiobox : public Control { -public: - bool Create(Window *parent_window, const char *style, int x, int y, int width, int height, const char *text = ""); - - bool Checked(); - void Check(bool state); - void Check(); - void Uncheck(); - void ToggleCheck(); -}; - -class Slider : public Control { -public: - bool Create(Window *parent_window, const char *style, int x, int y, int width, int height, const char *text = ""); - - void SetRange(int min, int max); - void SetPos(int pos); - int GetPos(); -}; - -class Combobox : public Control { -public: - bool Create(Window *parent_window, const char *style, int x, int y, int width, int height, const char *text = ""); - - void AddItem(const char *text); - void DeleteItem(uint id); - void DeleteAllItems(); - uint GetItemCount(); - - void SetSelection(uint id); - int GetSelection(); -}; - -class Listbox : public Control { -public: - bool Create(Window *parent_window, const char *style, int x, int y, int width, int height, const char *text = ""); - - void AddItem(const char *text); - void DeleteItem(uint id); - void DeleteAllItems(); - uint GetItemCount(); - - void SetSelection(uint id); - int GetSelection(); -}; - -class Listview : public Control { -private: -uint column_count; - -public: - bool Create(Window *parent_window, const char *style, int x, int y, int width, int height, const char *text = ""); - -enum { LEFT, RIGHT }; -enum { NONE = -1 }; - void AddColumn(uint align, uint width, const char *text); - void AddItem(const char *text); - void SetItemText(uint id, const char *text); - void DeleteAllItems(); - uint GetItemCount(); - - void SetSelection(uint id); - int GetSelection(); - - Listview() : column_count(0) {} -}; diff --git a/src/ui/win/libwin32/libwin32_editbox.cpp b/src/ui/win/libwin32/libwin32_editbox.cpp deleted file mode 100644 index 66b3e61a..00000000 --- a/src/ui/win/libwin32/libwin32_editbox.cpp +++ /dev/null @@ -1,43 +0,0 @@ -void Editbox::SetSelection(int begin, int end) { - SendMessage(hwnd, EM_SETSEL, begin, end); - SendMessage(hwnd, EM_SCROLLCARET, 0, 0); -} - -bool Editbox::Create(Window *parent_window, const char *style, int x, int y, int width, int height, const char *text) { - if(!parent_window)return false; - - parent = parent_window; - id = CONTROLID_INDEX + parent->control_count; - type = EDITBOX; - state.ws = WS_CHILD; - state.es = 0; - state.x = x; - state.y = y; - state.width = width; - state.height = height; - -stringarray part; - ParseStyleParam(style, part); - for(int i = 0; i < count(part); i++) { - if(!strcmp(part[i], "visible"))state.ws |= WS_VISIBLE; - if(!strcmp(part[i], "disabled"))state.ws |= WS_DISABLED; - if(!strcmp(part[i], "border"))state.ws |= WS_BORDER; - if(!strcmp(part[i], "raised"))state.ws |= WS_DLGFRAME; - if(!strcmp(part[i], "vscroll"))state.ws |= WS_VSCROLL; - if(!strcmp(part[i], "hscroll"))state.ws |= WS_HSCROLL; - - if(!strcmp(part[i], "multiline"))state.ws |= ES_MULTILINE; - if(!strcmp(part[i], "readonly"))state.ws |= ES_READONLY; - - if(!strcmp(part[i], "sunken"))state.es |= WS_EX_STATICEDGE; - if(!strcmp(part[i], "edge"))state.es |= WS_EX_CLIENTEDGE; - } - - hwnd = CreateWindowEx(state.es, "EDIT", text, state.ws, - state.x, state.y, state.width, state.height, - parent->hwnd, (HMENU)id, GetModuleHandle(0), 0); - if(!hwnd)return false; - - PostCreate(); - return true; -} diff --git a/src/ui/win/libwin32/libwin32_file.cpp b/src/ui/win/libwin32/libwin32_file.cpp deleted file mode 100644 index 60223144..00000000 --- a/src/ui/win/libwin32/libwin32_file.cpp +++ /dev/null @@ -1,48 +0,0 @@ -/* FileOpen() - * - * Filter format: - * "Text documents;*.txt,*.inf|All files;*.*" - * - * Return values: - * true - File was selected - * false - File was not selected - */ -bool FileOpen(Window *owner, const char *filter, const char *default_dir, char *output) { -string dir, f; - strcpy(dir, default_dir ? default_dir : ""); - replace(dir, "/", "\\"); - -stringarray type, part; - strcpy(f, ""); - split(type, "|", filter); - for(int i = 0; i < count(type); i++) { - split(part, ";", type[i]); - if(count(part) != 2)continue; - - strcat(f, part[0]); - strcat(f, " ("); - strcat(f, part[1]); - strcat(f, ")|"); - replace(part[1], ",", ";"); - strcat(f, part[1]); - strcat(f, "|"); - } -char *pf = strptr(f); - for(int i = strlen(pf) - 1; i >= 0; i--) { - if(pf[i] == '|')pf[i] = '\0'; - } - -OPENFILENAME ofn; - strcpy(output, ""); - memset(&ofn, 0, sizeof(ofn)); - ofn.lStructSize = sizeof(ofn); - ofn.hwndOwner = (owner) ? owner->hwnd : 0; - ofn.lpstrFilter = pf; - ofn.lpstrInitialDir = strptr(dir); - ofn.lpstrFile = output; - ofn.nMaxFile = MAX_PATH; - ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST; - ofn.lpstrDefExt = ""; - - return GetOpenFileName(&ofn); -} diff --git a/src/ui/win/libwin32/libwin32_groupbox.cpp b/src/ui/win/libwin32/libwin32_groupbox.cpp deleted file mode 100644 index 50e08b94..00000000 --- a/src/ui/win/libwin32/libwin32_groupbox.cpp +++ /dev/null @@ -1,33 +0,0 @@ -bool Groupbox::Create(Window *parent_window, const char *style, int x, int y, int width, int height, const char *text) { - if(!parent_window)return false; - - parent = parent_window; - id = CONTROLID_INDEX + parent->control_count; - type = LABEL; - state.ws = WS_CHILD | BS_GROUPBOX; - state.es = 0; - state.x = x; - state.y = y; - state.width = width; - state.height = height; - -stringarray part; - ParseStyleParam(style, part); - for(int i = 0; i < count(part); i++) { - if(!strcmp(part[i], "visible"))state.ws |= WS_VISIBLE; - if(!strcmp(part[i], "disabled"))state.ws |= WS_DISABLED; - if(!strcmp(part[i], "border"))state.ws |= WS_BORDER; - if(!strcmp(part[i], "raised"))state.ws |= WS_DLGFRAME; - - if(!strcmp(part[i], "sunken"))state.es |= WS_EX_STATICEDGE; - if(!strcmp(part[i], "edge"))state.es |= WS_EX_CLIENTEDGE; - } - - hwnd = CreateWindowEx(state.es, "BUTTON", text, state.ws, - state.x, state.y, state.width, state.height, - parent->hwnd, (HMENU)id, GetModuleHandle(0), 0); - if(!hwnd)return false; - - PostCreate(); - return true; -} diff --git a/src/ui/win/libwin32/libwin32_label.cpp b/src/ui/win/libwin32/libwin32_label.cpp deleted file mode 100644 index 84d31d94..00000000 --- a/src/ui/win/libwin32/libwin32_label.cpp +++ /dev/null @@ -1,38 +0,0 @@ -bool Label::Create(Window *parent_window, const char *style, int x, int y, int width, int height, const char *text) { - if(!parent_window)return false; - - parent = parent_window; - id = CONTROLID_INDEX + parent->control_count; - type = LABEL; - state.ws = WS_CHILD | SS_NOPREFIX | SS_ENDELLIPSIS; - state.es = 0; - state.x = x; - state.y = y; - state.width = width; - state.height = height; - -stringarray part; - ParseStyleParam(style, part); - for(int i = 0; i < count(part); i++) { - if(!strcmp(part[i], "visible"))state.ws |= WS_VISIBLE; - if(!strcmp(part[i], "disabled"))state.ws |= WS_DISABLED; - if(!strcmp(part[i], "border"))state.ws |= WS_BORDER; - if(!strcmp(part[i], "raised"))state.ws |= WS_DLGFRAME; - - if(!strcmp(part[i], "left"))state.ws |= SS_LEFT; - if(!strcmp(part[i], "center"))state.ws |= SS_CENTER; - if(!strcmp(part[i], "right"))state.ws |= SS_RIGHT; - if(!strcmp(part[i], "etched"))state.ws |= SS_ETCHEDFRAME; - - if(!strcmp(part[i], "sunken"))state.es |= WS_EX_STATICEDGE; - if(!strcmp(part[i], "edge"))state.es |= WS_EX_CLIENTEDGE; - } - - hwnd = CreateWindowEx(state.es, "STATIC", text, state.ws, - state.x, state.y, state.width, state.height, - parent->hwnd, (HMENU)id, GetModuleHandle(0), 0); - if(!hwnd)return false; - - PostCreate(); - return true; -} diff --git a/src/ui/win/libwin32/libwin32_listbox.cpp b/src/ui/win/libwin32/libwin32_listbox.cpp deleted file mode 100644 index 40edd490..00000000 --- a/src/ui/win/libwin32/libwin32_listbox.cpp +++ /dev/null @@ -1,66 +0,0 @@ -void Listbox::AddItem(const char *text) { - SendMessage(hwnd, LB_ADDSTRING, 0, (LPARAM)text); -} - -void Listbox::DeleteItem(uint id) { - SendMessage(hwnd, LB_DELETESTRING, id, 0); -} - -void Listbox::DeleteAllItems() { - SendMessage(hwnd, LB_RESETCONTENT, 0, 0); -} - -uint Listbox::GetItemCount() { - return SendMessage(hwnd, LB_GETCOUNT, 0, 0); -} - -void Listbox::SetSelection(uint id) { - SendMessage(hwnd, LB_SETCURSEL, id, 0); -} - -int Listbox::GetSelection() { - return SendMessage(hwnd, LB_GETCURSEL, 0, 0); -} - -bool Listbox::Create(Window *parent_window, const char *style, int x, int y, int width, int height, const char *text) { - if(!parent_window)return false; - - parent = parent_window; - id = CONTROLID_INDEX + parent->control_count; - type = LISTBOX; - state.ws = WS_CHILD | LBS_NOTIFY; - state.es = 0; - state.x = x; - state.y = y; - state.width = width; - state.height = height; - -stringarray part; - ParseStyleParam(style, part); - for(int i = 0; i < count(part); i++) { - if(!strcmp(part[i], "visible"))state.ws |= WS_VISIBLE; - if(!strcmp(part[i], "disabled"))state.ws |= WS_DISABLED; - if(!strcmp(part[i], "border"))state.ws |= WS_BORDER; - if(!strcmp(part[i], "raised"))state.ws |= WS_DLGFRAME; - - if(!strcmp(part[i], "sunken"))state.es |= WS_EX_STATICEDGE; - if(!strcmp(part[i], "edge"))state.es |= WS_EX_CLIENTEDGE; - } - - hwnd = CreateWindowEx(state.es, "LISTBOX", text, state.ws, - state.x, state.y, state.width, state.height, - parent->hwnd, (HMENU)id, GetModuleHandle(0), 0); - if(!hwnd)return false; - - if(!strcmp(text, "") == false) { - stringarray t; - split(t, "|", text); - for(int i = 0; i < ::count(t); i++) { - AddItem(strptr(t[i])); - } - } - SetSelection(0); - - PostCreate(); - return true; -} diff --git a/src/ui/win/libwin32/libwin32_listview.cpp b/src/ui/win/libwin32/libwin32_listview.cpp deleted file mode 100644 index 566f2627..00000000 --- a/src/ui/win/libwin32/libwin32_listview.cpp +++ /dev/null @@ -1,96 +0,0 @@ -void Listview::AddColumn(uint align, uint width, const char *text) { -LVCOLUMN column; - column.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; - column.fmt = (align == RIGHT) ? LVCFMT_RIGHT : LVCFMT_LEFT; - column.iSubItem = column_count; - column.pszText = (LPSTR)text; - column.cx = width; - ListView_InsertColumn(hwnd, column_count++, &column); -} - -void Listview::AddItem(const char *text) { -stringarray t; - split(t, "|", text); - -LVITEM item; -uint pos = ListView_GetItemCount(hwnd); - item.mask = LVIF_TEXT; - item.iItem = pos; - item.iSubItem = 0; - item.pszText = (LPSTR)strptr(t[0]); - ListView_InsertItem(hwnd, &item); - - for(int i = 1; i < count(t); i++) { - ListView_SetItemText(hwnd, pos, i, (LPSTR)strptr(t[i])); - } -} - -void Listview::SetItemText(uint id, const char *text) { -stringarray t; - split(t, "|", text); - - for(int i = 0; i < count(t); i++) { - ListView_SetItemText(hwnd, id, i, (LPSTR)strptr(t[i])); - } -} - -void Listview::DeleteAllItems() { - ListView_DeleteAllItems(hwnd); -} - -uint Listview::GetItemCount() { - return ListView_GetItemCount(hwnd); -} - -void Listview::SetSelection(uint id) { -uint count = ListView_GetItemCount(hwnd); - for(int i = 0; i < count; i++) { - uint state = ListView_GetItemState(hwnd, i, LVIS_FOCUSED); - ListView_SetItemState(hwnd, i, LVIS_FOCUSED, (i == id) ? LVIS_FOCUSED : 0); - ListView_SetItemState(hwnd, i, LVIS_SELECTED, (i == id) ? LVIS_SELECTED : 0); - } -} - -int Listview::GetSelection() { -uint count = ListView_GetItemCount(hwnd); - for(int i = 0; i < count; i++) { - if(ListView_GetItemState(hwnd, i, LVIS_SELECTED))return i; - } - return NONE; -} - -bool Listview::Create(Window *parent_window, const char *style, int x, int y, int width, int height, const char *text) { - if(!parent_window)return false; - - parent = parent_window; - id = CONTROLID_INDEX + parent->control_count; - type = LISTVIEW; - state.ws = WS_CHILD | LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS; - state.es = 0; - state.x = x; - state.y = y; - state.width = width; - state.height = height; - -stringarray part; - ParseStyleParam(style, part); - for(int i = 0; i < count(part); i++) { - if(!strcmp(part[i], "visible"))state.ws |= WS_VISIBLE; - if(!strcmp(part[i], "disabled"))state.ws |= WS_DISABLED; - if(!strcmp(part[i], "border"))state.ws |= WS_BORDER; - if(!strcmp(part[i], "raised"))state.ws |= WS_DLGFRAME; - - if(!strcmp(part[i], "sunken"))state.es |= WS_EX_STATICEDGE; - if(!strcmp(part[i], "edge"))state.es |= WS_EX_CLIENTEDGE; - } - - hwnd = CreateWindowEx(state.es, WC_LISTVIEW, text, state.ws, - state.x, state.y, state.width, state.height, - parent->hwnd, (HMENU)id, GetModuleHandle(0), 0); - if(!hwnd)return false; - - ListView_SetExtendedListViewStyle(hwnd, LVS_EX_FULLROWSELECT); - - PostCreate(); - return true; -} diff --git a/src/ui/win/libwin32/libwin32_misc.cpp b/src/ui/win/libwin32/libwin32_misc.cpp deleted file mode 100644 index 02f0e39c..00000000 --- a/src/ui/win/libwin32/libwin32_misc.cpp +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef WS_EX_LAYERED -#define WS_EX_LAYERED 0x00080000 -#endif - -typedef BOOL (WINAPI *SLWAProc)(HWND hwnd, COLORREF crKey, BYTE bAlpha, DWORD dwFlags); - -#ifndef LWA_COLORKEY -#define LWA_COLORKEY 0x00000001 -#endif - -#ifndef LWA_ALPHA -#define LWA_ALPHA 0x0000002 -#endif - -BOOL SetWindowAlphaLevel(HWND hwnd, uint level) { -SLWAProc pSLWA; -HMODULE handle = GetModuleHandle("USER32.DLL"); -BOOL result; - if(!handle)return FALSE; - pSLWA = (SLWAProc)GetProcAddress(handle, (char*)"SetLayeredWindowAttributes"); - if(pSLWA == 0)return FALSE; - - level &= 255; - if(level != 255) { - SetWindowLong(hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_LAYERED); - result = pSLWA(hwnd, 0, level, LWA_ALPHA); - } else { - SetWindowLong(hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE) & ~WS_EX_LAYERED); - result = pSLWA(hwnd, 0, 0, 0); - } - InvalidateRect(hwnd, 0, TRUE); - return result; -} diff --git a/src/ui/win/libwin32/libwin32_radiobox.cpp b/src/ui/win/libwin32/libwin32_radiobox.cpp deleted file mode 100644 index d16d9edc..00000000 --- a/src/ui/win/libwin32/libwin32_radiobox.cpp +++ /dev/null @@ -1,39 +0,0 @@ -bool Radiobox::Checked() { return SendMessage(hwnd, BM_GETCHECK, 0, 0); } -void Radiobox::Check(bool state) { SendMessage(hwnd, BM_SETCHECK, (WPARAM)state, 0); } -void Radiobox::Check() { Check(true); } -void Radiobox::Uncheck() { Check(false); } -void Radiobox::ToggleCheck() { Check(!Checked()); } - -bool Radiobox::Create(Window *parent_window, const char *style, int x, int y, int width, int height, const char *text) { - if(!parent_window)return false; - - parent = parent_window; - id = CONTROLID_INDEX + parent->control_count; - type = RADIOBOX; - state.ws = WS_CHILD; - state.es = 0; - state.x = x; - state.y = y; - state.width = width; - state.height = height; - -stringarray part; - ParseStyleParam(style, part); - for(int i = 0; i < count(part); i++) { - if(!strcmp(part[i], "visible"))state.ws |= WS_VISIBLE; - if(!strcmp(part[i], "disabled"))state.ws |= WS_DISABLED; - - if(!strcmp(part[i], "left"))state.ws |= BS_LEFT; - if(!strcmp(part[i], "center"))state.ws |= BS_CENTER; - if(!strcmp(part[i], "right"))state.ws |= BS_RIGHT; - } - state.ws |= BS_RADIOBUTTON; - - hwnd = CreateWindowEx(state.es, "BUTTON", text, state.ws, - state.x, state.y, state.width, state.height, - parent->hwnd, (HMENU)id, GetModuleHandle(0), 0); - if(!hwnd)return false; - - PostCreate(); - return true; -} diff --git a/src/ui/win/libwin32/libwin32_slider.cpp b/src/ui/win/libwin32/libwin32_slider.cpp deleted file mode 100644 index c2fde39e..00000000 --- a/src/ui/win/libwin32/libwin32_slider.cpp +++ /dev/null @@ -1,47 +0,0 @@ -void Slider::SetRange(int min, int max) { - SendMessage(hwnd, TBM_SETRANGE, (WPARAM)true, (LPARAM)MAKELONG(min, max)); - SendMessage(hwnd, TBM_SETPAGESIZE, 0, (LPARAM)((max - min) >> 4)); - SendMessage(hwnd, TBM_SETPOS, (WPARAM)true, (LPARAM)min); -} - -void Slider::SetPos(int pos) { - SendMessage(hwnd, TBM_SETPOS, (WPARAM)true, (LPARAM)pos); -} - -int Slider::GetPos() { - return SendMessage(hwnd, TBM_GETPOS, 0, 0); -} - -bool Slider::Create(Window *parent_window, const char *style, int x, int y, int width, int height, const char *text) { - if(!parent_window)return false; - - parent = parent_window; - id = CONTROLID_INDEX + parent->control_count; - type = SLIDER; - state.ws = WS_CHILD | TBS_NOTICKS; - state.es = 0; - state.x = x; - state.y = y; - state.width = width; - state.height = height; - -stringarray part; - ParseStyleParam(style, part); - for(int i = 0; i < count(part); i++) { - if(!strcmp(part[i], "visible"))state.ws |= WS_VISIBLE; - if(!strcmp(part[i], "disabled"))state.ws |= WS_DISABLED; - if(!strcmp(part[i], "border"))state.ws |= WS_BORDER; - if(!strcmp(part[i], "raised"))state.ws |= WS_DLGFRAME; - - if(!strcmp(part[i], "sunken"))state.es |= WS_EX_STATICEDGE; - if(!strcmp(part[i], "edge"))state.es |= WS_EX_CLIENTEDGE; - } - - hwnd = CreateWindowEx(state.es, TRACKBAR_CLASS, text, state.ws, - state.x, state.y, state.width, state.height, - parent->hwnd, (HMENU)id, GetModuleHandle(0), 0); - if(!hwnd)return false; - - PostCreate(); - return true; -} diff --git a/src/ui/win/libwin32/libwin32_window.cpp b/src/ui/win/libwin32/libwin32_window.cpp deleted file mode 100644 index ebbda013..00000000 --- a/src/ui/win/libwin32/libwin32_window.cpp +++ /dev/null @@ -1,456 +0,0 @@ -long Window::WndProc(UINT msg, WPARAM wparam, LPARAM lparam) { -EventInfo info; - info.window = this; - info.window_id = id; - info.control = 0; - info.control_id = 0; - -static bool rbn_down = false; -static int32 coord_x, coord_y; - - if(state.dragmove == true) - switch(msg) { - - case WM_MOUSEMOVE: { - if(rbn_down == true) { - POINT p; - GetCursorPos(&p); - RECT rc; - GetWindowRect(hwnd, &rc); - SetWindowPos(hwnd, 0, - rc.left - (coord_x - p.x), rc.top - (coord_y - p.y), - 0, 0, SWP_NOZORDER | SWP_NOSIZE); - coord_x = p.x; - coord_y = p.y; - } - } break; - - case WM_RBUTTONDOWN: { - POINT p; - GetCursorPos(&p); - coord_x = p.x; - coord_y = p.y; - rbn_down = true; - SetCapture(hwnd); - } break; - - case WM_CAPTURECHANGED: - case WM_RBUTTONUP: { - rbn_down = false; - ReleaseCapture(); - } break; - - } - -bool result = false; - switch(msg) { - - case WM_CLOSE: { - info.event_id = EVENT_CLOSE; - result = Event(info); - } break; - - case WM_DESTROY: { - info.event_id = EVENT_DESTROY; - result = Event(info); - } break; - - case WM_PAINT: { - info.event_id = EVENT_DRAW; - result = Event(info); - } break; - - case WM_COMMAND: { - for(int i = 0; i < menu_count; i++) { - if(LOWORD(wparam) == menu_list[i]) { - info.event_id = EVENT_MENUCLICKED; - info.control_id = menu_list[i]; - result = Event(info); - break; - } - } - - for(int i = 0; i < control_count; i++) { - if(LOWORD(wparam) == list[i]->id) { - if((list[i]->type == Control::EDITBOX && HIWORD(wparam) == EN_CHANGE) || - (list[i]->type == Control::COMBOBOX && HIWORD(wparam) == CBN_SELCHANGE) || - (list[i]->type == Control::LISTBOX && HIWORD(wparam) == LBN_SELCHANGE)) { - info.event_id = EVENT_CHANGED; - info.control = list[i]; - info.control_id = list[i]->id; - result = Event(info); - break; - } else { - info.event_id = EVENT_CLICKED; - info.control = list[i]; - info.control_id = list[i]->id; - result = Event(info); - break; - } - } - } - } break; - - case WM_HSCROLL: { - for(int i = 0; i < control_count; i++) { - if((HWND)lparam == list[i]->hwnd) { - info.event_id = EVENT_CHANGED; - info.control = list[i]; - info.control_id = list[i]->id; - result = Event(info); - break; - } - } - } break; - - case WM_NOTIFY: { - for(int i = 0; i < control_count; i++) { - if(LOWORD(wparam) == list[i]->id) { - if(list[i]->type == Control::LISTVIEW) { - if(((LPNMHDR)lparam)->code == LVN_ITEMCHANGED) { - if(SendMessage(list[i]->hwnd, LVM_GETNEXTITEM, -1, LVNI_FOCUSED) != -1) { - info.event_id = EVENT_CHANGED; - info.control = list[i]; - info.control_id = list[i]->id; - result = Event(info); - break; - } - } else if(((LPNMHDR)lparam)->code == NM_DBLCLK) { - info.event_id = EVENT_DOUBLECLICKED; - info.control = list[i]; - info.control_id = list[i]->id; - result = Event(info); - break; - } - } - } - } - } break; - - case WM_ENTERMENULOOP: { - info.event_id = EVENT_MENUENTER; - result = Event(info); - } break; - - case WM_EXITMENULOOP: { - info.event_id = EVENT_MENUEXIT; - result = Event(info); - } break; - - case WM_CTLCOLORBTN: - case WM_CTLCOLOREDIT: - case WM_CTLCOLORLISTBOX: - case WM_CTLCOLORSTATIC: { - for(int i = 0; i < control_count; i++) { - if((HWND)lparam != list[i]->hwnd)continue; - HDC hdc = (HDC)wparam; - if(list[i]->state.use_textcolor == true) { - SetTextColor(hdc, - RGB((list[i]->state.textcolor >> 16) & 255, - (list[i]->state.textcolor >> 8) & 255, - (list[i]->state.textcolor >> 0) & 255)); - } - if(list[i]->state.use_backcolor == true) { - SetBkColor(hdc, - RGB((list[i]->state.backcolor >> 16) & 255, - (list[i]->state.backcolor >> 8) & 255, - (list[i]->state.backcolor >> 0) & 255)); - } - if(list[i]->backbrush)return (long)list[i]->backbrush; - } - } break; - - } - -//did event handler process message? - return (result == true) ? (long)true : DefWindowProc(hwnd, msg, wparam, lparam); -} - -void Window::Resize(uint width, uint height, bool center) { - state.width = width; - state.height = height; - -//actual windows are resized so that their client size is exactly as requested. -//windows inside of windows are resized as controls are, thusly the window style -//takes away from their total client area size. - if(!parent) { - SetWindowPos(hwnd_resize, 0, 0, 0, width, height, SWP_NOZORDER | SWP_NOMOVE); - RECT rc; - GetClientRect(hwnd_resize, &rc); - width += width - (rc.right - rc.left); - height += height - (rc.bottom - rc.top); - uint x = (GetSystemMetrics(SM_CXSCREEN) - width) >> 1; - uint y = (GetSystemMetrics(SM_CYSCREEN) - height) >> 1; - SetWindowPos(hwnd, 0, x, y, width, height, SWP_NOZORDER | ((center == false) ? SWP_NOMOVE : 0)); - } else { - SetWindowPos(hwnd, 0, 0, 0, width, height, SWP_NOZORDER | SWP_NOMOVE); - } - - if(Visible())Focus(); - - state.window_width = width; - state.window_height = height; -} - -void Window::Resize() { Resize(state.width, state.height); } - -void Window::Move(uint x, uint y) { - state.x = x; - state.y = y; - - SetWindowPos(hwnd, 0, x, y, 0, 0, SWP_NOZORDER | SWP_NOSIZE); -} - -void Window::MoveToTop() { -RECT rc, workarea; - SystemParametersInfo(SPI_GETWORKAREA, 0, &workarea, 0); - GetWindowRect(hwnd, &rc); -uint x = rc.left; -uint y = workarea.top; - Move(x, y); -} - -void Window::MoveToBottom() { -RECT rc, workarea; - SystemParametersInfo(SPI_GETWORKAREA, 0, &workarea, 0); - GetWindowRect(hwnd, &rc); -uint x = rc.left; -uint y = workarea.bottom - (rc.bottom - rc.top); - Move(x, y); -} - -void Window::MoveToLeft() { -RECT rc, workarea; - SystemParametersInfo(SPI_GETWORKAREA, 0, &workarea, 0); - GetWindowRect(hwnd, &rc); -uint x = workarea.left; -uint y = rc.top; - Move(x, y); -} - -void Window::MoveToRight() { -RECT rc, workarea; - SystemParametersInfo(SPI_GETWORKAREA, 0, &workarea, 0); - GetWindowRect(hwnd, &rc); -uint x = workarea.right - (rc.right - rc.left); -uint y = rc.top; - Move(x, y); -} - -void Window::Center() { -RECT workarea, rc; -//SystemParametersInfo(SPI_GETWORKAREA, 0, &workarea, 0); - GetWindowRect(hwnd, &rc); -uint x = (GetSystemMetrics(SM_CXSCREEN) - (rc.right - rc.left)) >> 1; -uint y = (GetSystemMetrics(SM_CYSCREEN) - (rc.bottom - rc.top)) >> 1; - Move(x, y); -} - -void Window::SetStyle(const char *style) { - state.ws = WS_SYSMENU; - state.es = 0; - - state.dragmove = false; - - if(parent)state.ws |= WS_CHILD; - -stringarray part; - ParseStyleParam(style, part); - for(int i = 0; i < count(part); i++) { - if(!strcmp(part[i], "visible")) state.ws |= WS_VISIBLE; - if(!strcmp(part[i], "popup")) state.ws |= WS_POPUP; - if(!strcmp(part[i], "border")) state.ws |= WS_BORDER; - if(!strcmp(part[i], "frame")) state.ws |= WS_DLGFRAME; - if(!strcmp(part[i], "titlebar"))state.ws |= WS_CAPTION; - if(!strcmp(part[i], "minimize"))state.ws |= WS_MINIMIZEBOX; - if(!strcmp(part[i], "maximize"))state.ws |= WS_MAXIMIZEBOX; - - if(!strcmp(part[i], "topmost")) state.es |= WS_EX_TOPMOST; - if(!strcmp(part[i], "layered")) state.es |= WS_EX_LAYERED; - if(!strcmp(part[i], "sunken")) state.es |= WS_EX_STATICEDGE; - if(!strcmp(part[i], "edge")) state.es |= WS_EX_CLIENTEDGE; - - if(!strcmp(part[i], "dragmove"))state.dragmove = true; - } - - if(!hwnd)return; - -//never show resize window - SetWindowLong(hwnd_resize, GWL_STYLE, state.ws & ~WS_VISIBLE); - SetWindowLong(hwnd_resize, GWL_EXSTYLE, state.es); - SetWindowPos (hwnd_resize, (state.es & WS_EX_TOPMOST) ? HWND_TOPMOST : HWND_NOTOPMOST, - 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE); - - SetWindowLong(hwnd, GWL_STYLE, state.ws); - SetWindowLong(hwnd, GWL_EXSTYLE, state.es); - SetWindowPos (hwnd, (state.es & WS_EX_TOPMOST) ? HWND_TOPMOST : HWND_NOTOPMOST, - 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE); - - Resize(); -} - -void Window::SetAlphaLevel(uint level) { - level &= 255; - if(level == 255) { - state.es &= ~WS_EX_LAYERED; - } else { - state.es |= WS_EX_LAYERED; - } - SetWindowAlphaLevel(hwnd, level); -} - -void Window::SetBackgroundColor(uint r, uint g, uint b) { - backbrush = (HBRUSH)CreateSolidBrush(RGB(r, g, b)); -} - -void Window::SetIcon(uint resource_id) { - state.use_icon = true; - state.icon_id = resource_id; -} - -void Window::Show(bool do_show) { - if(do_show == true) { - if(Visible() == false)Resize(); - ShowWindow(hwnd, SW_NORMAL); - state.ws |= WS_VISIBLE; - } else { - ShowWindow(hwnd, SW_HIDE); - state.ws &= ~WS_VISIBLE; - } -} - -bool Window::Visible() { - return !!(GetWindowLong(hwnd, GWL_STYLE) & WS_VISIBLE); -} - -void Window::Show() { Show(true); } -void Window::Hide() { Show(false); } -void Window::Focus() { SetFocus(hwnd); } - -bool Window::Create(Window *parent_window, const char *classname, const char *style, uint x, uint y, uint width, uint height, const char *title) { - parent = parent_window; - id = WINDOWID_INDEX + WindowList.window_count; - - strcpy(state.classname, classname); - strcpy(state.title, title); - strcpy(state.style, style); - - state.x = x; - state.y = y; - state.width = width; - state.height = height; - SetStyle(style); - -WNDCLASS wc; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hbrBackground = backbrush; - wc.hCursor = LoadCursor(0, IDC_ARROW); - wc.hIcon = (state.use_icon) ? LoadIcon(GetModuleHandle(0), MAKEINTRESOURCE(state.icon_id)) : LoadIcon(0, IDI_APPLICATION); - wc.hInstance = GetModuleHandle(0); - wc.lpfnWndProc = CoreWindowProc; - wc.lpszClassName = strptr(state.classname); - wc.lpszMenuName = 0; - wc.style = CS_HREDRAW | CS_VREDRAW; - RegisterClass(&wc); - - hwnd = CreateWindowEx(state.es, strptr(state.classname), strptr(state.title), state.ws, - state.x, state.y, state.width, state.height, parent ? parent->hwnd : 0, 0, wc.hInstance, 0); - hwnd_resize = CreateWindowEx(state.es, "resize_class", "", state.ws & ~WS_VISIBLE, - state.x, state.y, state.width, state.height, parent ? parent->hwnd : 0, 0, wc.hInstance, 0); - if(!hwnd || !hwnd_resize)return false; - - Resize(); - - WindowList.Add(this); - return true; -} - -bool Window::Add(Control &control) { - if(control_count >= CONTROL_LIMIT)return false; - list[control_count++] = &control; - return true; -} - -/* - * menu functions - */ - -void Window::CreateMenu() { - menu = ::CreateMenu(); - submenu_pos = 0; - for(int i = 0; i < 16; i++)submenu[i].handle = 0; -} - -void Window::AddMenuGroup(const char *text) { - submenu[submenu_pos].handle = CreatePopupMenu(); - strcpy(submenu[submenu_pos].text, text); - submenu_pos++; -} - -void Window::EndMenuGroup() { - submenu_pos--; - AppendMenu((submenu_pos == 0) ? menu : submenu[submenu_pos - 1].handle, MF_STRING | MF_POPUP, - (uint)submenu[submenu_pos].handle, submenu[submenu_pos].text); -} - -void Window::AddMenuItem(uint id, const char *text) { - if(menu_count >= CONTROL_LIMIT)return; - - menu_list[menu_count++] = id; - AppendMenu((submenu_pos == 0) ? menu : submenu[submenu_pos - 1].handle, MF_STRING, - (uint)id, text); -} - -void Window::AddMenuSeparator() { - AppendMenu((submenu_pos == 0) ? menu : submenu[submenu_pos - 1].handle, MF_SEPARATOR, 0, ""); -} - -void Window::CheckMenuItem(uint id, bool do_check) { - ::CheckMenuItem(menu, id, (do_check == true) ? MF_CHECKED : MF_UNCHECKED); -} - -bool Window::MenuItemChecked(uint id) { - return ::CheckMenuItem(menu, id, 0); -} - -void Window::CheckMenuItem(uint id) { CheckMenuItem(id, true); } -void Window::UncheckMenuItem(uint id) { CheckMenuItem(id, false); } - -void Window::ShowMenu(bool state) { - SetMenu(hwnd_resize, (state == true) ? menu : 0); - SetMenu(hwnd, (state == true) ? menu : 0); - Resize(); -} - -bool Window::MenuVisible() { return GetMenu(hwnd) != 0; } -void Window::ShowMenu() { ShowMenu(true); } -void Window::HideMenu() { ShowMenu(false); } - -void Window::SetEventCallback(EventCallback ecb) { - event_callback = ecb; -} - -bool Window::Event(EventInfo &info) { - return (event_callback) ? event_callback(info) : false; -} - -Window::Window() { - hwnd = 0; - hwnd_resize = 0; - backbrush = (HBRUSH)(COLOR_3DFACE + 1); - control_count = 0; - event_callback = 0; - - state.use_icon = false; - - list = (Control**)malloc((CONTROL_LIMIT + 1) * sizeof(Control*)); - memset(list, 0, (CONTROL_LIMIT + 1) * sizeof(Control*)); - menu_list = (uint*)malloc((CONTROL_LIMIT + 1) * sizeof(uint)); - memset(menu_list, 0, (CONTROL_LIMIT + 1) * sizeof(uint)); - - for(int i = 0; i < 16; i++) { - submenu[i].text = (char*)malloc(256); - strcpy(submenu[i].text, ""); - } -} diff --git a/src/ui/win/libwin32/libwin32_window.h b/src/ui/win/libwin32/libwin32_window.h deleted file mode 100644 index 556ddb4b..00000000 --- a/src/ui/win/libwin32/libwin32_window.h +++ /dev/null @@ -1,97 +0,0 @@ -enum { - EVENT_CLOSE, - EVENT_DESTROY, - EVENT_DRAW, - - EVENT_CLICKED, - EVENT_DOUBLECLICKED, - EVENT_MENUCLICKED, - EVENT_MENUENTER, - EVENT_MENUEXIT, - EVENT_CHANGED, - - EVENT_USER = 0x80000000, -}; - -struct EventInfo { - uint event_id; - uint event_type; - Window *window; - uint window_id; - Control *control; - uint control_id; -}; - -typedef bool (*EventCallback)(EventInfo &info); - -class Window { -public: -HWND hwnd, hwnd_resize; -HMENU menu; -HBRUSH backbrush; -Window *parent; -uint id; - -uint control_count; -Control **list; -uint menu_count; -uint *menu_list; - -struct State { - string classname, title, style; - uint x, y, width, height; - uint window_width, window_height; - uint ws, es; - - bool dragmove; - - bool use_icon; - uint icon_id; -} state; - long WndProc(UINT msg, WPARAM wparam, LPARAM lparam); - bool Add(Control &control); - Window(); - - void SetAlphaLevel(uint level); - void SetBackgroundColor(uint r, uint g, uint b); - void SetIcon(uint resource_id); - bool Create(Window *parent_window, const char *classname, const char *style, uint x, uint y, uint width, uint height, const char *title = ""); - void SetStyle(const char *style); - void Resize(uint width, uint height, bool center = false); - void Resize(); - void Move(uint x, uint y); - void MoveToTop(); - void MoveToBottom(); - void MoveToLeft(); - void MoveToRight(); - void Center(); - - virtual void Show(bool do_show); - virtual bool Visible(); - virtual void Show(); - virtual void Hide(); - virtual void Focus(); - -struct { - HMENU handle; - char *text; -} submenu[16]; -uint submenu_pos; - void CreateMenu(); - void AddMenuGroup(const char *text); - void EndMenuGroup(); - void AddMenuItem(uint id, const char *text); - void AddMenuSeparator(); - void CheckMenuItem(uint id, bool do_check); - bool MenuItemChecked(uint id); - void CheckMenuItem(uint id); - void UncheckMenuItem(uint id); - void ShowMenu(bool state); - bool MenuVisible(); - void ShowMenu(); - void HideMenu(); - -EventCallback event_callback; - void SetEventCallback(EventCallback ecb); - virtual bool Event(EventInfo &info); -}; diff --git a/src/ui/win/main.cpp b/src/ui/win/main.cpp deleted file mode 100644 index 99307c48..00000000 --- a/src/ui/win/main.cpp +++ /dev/null @@ -1,104 +0,0 @@ -#include "../../lib/libwin32.h" -#include "../../lib/libwin32.cpp" - -#include "config.cpp" - -#include "bsnes.h" - -#include "event.h" -#include "ui.h" - -#include "bsnes.cpp" - -#include "../video/d3d.h" -#include "../video/ddraw.h" -#include "../audio/dsound.h" -#include "../input/dinput.h" - -#include "../video/d3d.cpp" -#include "../video/ddraw.cpp" -#include "../audio/dsound.cpp" -#include "../input/dinput.cpp" - -#include "event.cpp" -#include "ui.cpp" - -void dprintf(char *s, ...) { -char str[4096]; -va_list args; - va_start(args, s); - vsprintf(str, s, args); - va_end(args); - wDebug.Print(source::none, str); -} - -void dprintf(uint source, char *s, ...) { -char str[4096]; -va_list args; - va_start(args, s); - vsprintf(str, s, args); - va_end(args); - wDebug.Print(source, str); -} - -void get_base_path() { -char full_name[4095]; - GetFullPathName(__argv[0], 4095, full_name, 0); - -string t; - strcpy(t, full_name); - - if(strlen(t) != 0) { - //remove program name - replace(t, "\\", "/"); - for(int i = strlen(t) - 1; i >= 0; i--) { - if(strptr(t)[i] == '/' || strptr(t)[i] == '\\') { - strptr(t)[i] = 0; - break; - } - } - } - - if(strend(t, "/") == false) { strcat(t, "/"); } - config::path.base = strptr(t); -} - -int __stdcall WinMain(HINSTANCE hinstance, HINSTANCE hprevinstance, LPSTR lpcmdline, int ncmdshow) { - timeBeginPeriod(1); - InitCommonControls(); - get_base_path(); - -string cfg_fn; - strcpy(cfg_fn, config::path.base); - strcat(cfg_fn, "bsnes.cfg"); - config_file.load(cfg_fn); - - init_snes(); - init_ui(); - - if(__argc >= 2) { - cartridge.load_begin(Cartridge::CART_NORMAL); - cartridge.load(__argv[1]); - cartridge.load_end(); - snes.power(); - } - -MSG msg; - while(1) { - while(PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) { - if(msg.message == WM_QUIT)goto end; - TranslateMessage(&msg); - DispatchMessage(&msg); - } - bsnes.run(); - } - -end: - if(cartridge.loaded() == true)cartridge.unload(); - - term_ui(); - term_snes(); - config_file.save(cfg_fn); - timeEndPeriod(1); - return 0; -} diff --git a/src/ui/win/settings/settings.cpp b/src/ui/win/settings/settings.cpp deleted file mode 100644 index 8d57206b..00000000 --- a/src/ui/win/settings/settings.cpp +++ /dev/null @@ -1,61 +0,0 @@ -#include "ui_settings.cpp" -#include "ui_videosettings.cpp" -#include "ui_coloradjust.cpp" -#include "ui_rastersettings.cpp" -#include "ui_emusettings.cpp" -#include "ui_inputconfig.cpp" -#include "ui_cheateditor.cpp" - -void init_settings() { - wSettings.SetIcon(100); - wSettings.Create(0, "bsnes_settings", "topmost|title|minimize", - 0, 0, 640, 365, "bsnes Configuration Settings"); - wSettings.SetAlphaLevel(config::misc.config_window_alpha_level); - wSettings.MoveToBottom(); - wSettings.MoveToRight(); - - wVideoSettings.Create(&wSettings, "bsnes_videosettings", "", 160, 5, 475, 355); - wColorAdjust.Create(&wSettings, "bsnes_coloradjust", "", 160, 5, 475, 355); - wRasterSettings.Create(&wSettings, "bsnes_rastersettings", "", 160, 5, 475, 355); - wEmuSettings.Create(&wSettings, "bsnes_emusettings", "", 160, 5, 475, 355); - wInputConfig.Create(&wSettings, "bsnes_inputconfig", "", 160, 5, 475, 355); - wCheatEditor.Create(&wSettings, "bsnes_cheateditor", "", 160, 5, 475, 355); -} - -void setup_settings() { - wSettings.Setup(); - - wVideoSettings.Setup(); - wColorAdjust.Setup(); - wRasterSettings.Setup(); - wEmuSettings.Setup(); - wInputConfig.Setup(); - wCheatEditor.Setup(); -} - -void Settings::set_active_panel(Window *panel) { - if(active_panel) { - active_panel->Hide(); - active_panel = 0; - } - if(panel) { - active_panel = panel; - active_panel->Show(); - } -} - -void Settings::show_active_panel() { - if(active_panel) { - active_panel->Show(); - } -} - -void Settings::hide_active_panel() { - if(active_panel) { - active_panel->Hide(); - } -} - -Settings::Settings() { - active_panel = 0; -} diff --git a/src/ui/win/settings/settings.h b/src/ui/win/settings/settings.h deleted file mode 100644 index b8fb8a4b..00000000 --- a/src/ui/win/settings/settings.h +++ /dev/null @@ -1,17 +0,0 @@ -class Settings { -public: -Window *active_panel; - void set_active_panel(Window *panel); - void show_active_panel(); - void hide_active_panel(); - - Settings(); -} settings; - -#include "ui_settings.h" -#include "ui_videosettings.h" -#include "ui_coloradjust.h" -#include "ui_rastersettings.h" -#include "ui_emusettings.h" -#include "ui_inputconfig.h" -#include "ui_cheateditor.h" diff --git a/src/ui/win/settings/ui_cheateditor.cpp b/src/ui/win/settings/ui_cheateditor.cpp deleted file mode 100644 index 2d155858..00000000 --- a/src/ui/win/settings/ui_cheateditor.cpp +++ /dev/null @@ -1,169 +0,0 @@ -bool CheatEditorWindow::Event(EventInfo &info) { - switch(info.event_id) { - - case EVENT_DOUBLECLICKED: { - if(info.control == &CheatList && CheatList.GetItemCount() != 0) { - int sel = CheatList.GetSelection(); - if(sel == -1 || sel >= cheat.count())break; - - bool enabled = cheat.enabled(sel); - (enabled == true) ? cheat.disable(sel) : cheat.enable(sel); - UpdateItem(sel); - LoadItem(sel); - } - } break; - - case EVENT_CHANGED: { - if(info.control == &CheatList) { - LoadItem(CheatList.GetSelection()); - } - } break; - - case EVENT_CLICKED: { - if(info.control == &AddCode) CheatAdd(); - if(info.control == &EditCode) CheatEdit(); - if(info.control == &DeleteCode)CheatDelete(); - if(info.control == &ClearCode) CheatClear(); - } break; - - } - - return false; -} - -void CheatEditorWindow::CheatAdd() { -char code[16 + 1], desc[128 + 1]; - Code.GetText(code, 16); - Desc.GetText(desc, 128); - if(!strcmp(code, ""))return; - - cheat.add(Enabled.Checked(), code, desc); - Refresh(); -} - -void CheatEditorWindow::CheatEdit() { -int sel = CheatList.GetSelection(); - if(sel == -1 || sel >= cheat.count())return; - -char code[16 + 1], desc[128 + 1]; - Code.GetText(code, 16); - Desc.GetText(desc, 128); - - cheat.edit(sel, Enabled.Checked(), code, desc); - UpdateItem(sel); -} - -void CheatEditorWindow::CheatDelete() { -int sel = CheatList.GetSelection(); - if(sel == -1 || sel >= cheat.count())return; - - cheat.remove(sel); - Refresh(); -} - -void CheatEditorWindow::CheatClear() { - Enabled.Uncheck(); - Code.SetText(""); - Desc.SetText(""); -} - -void CheatEditorWindow::Refresh() { - Clear(); - -char status[16 + 1], desc[128 + 1], code[16 + 1], result[16 + 1]; -uint32 addr; -uint8 data; -bool enabled; - for(uint i = 0; i < cheat.count(); i++) { - cheat.get(i, enabled, addr, data, code, desc); - strcpy(status, enabled == true ? "On" : "Off"); - sprintf(result, "%0.6x = %0.2x", addr, data); - AddItem(status, desc, code, result); - } - - if(cheat.count()) { - CheatList.SetSelection(0); - } -} - -void CheatEditorWindow::Clear() { - CheatList.DeleteAllItems(); - CheatClear(); -} - -void CheatEditorWindow::LoadItem(int n) { - if(n == -1 || n >= cheat.count()) { - CheatClear(); - return; - } - -char status[16 + 1], desc[128 + 1], code[16 + 1], result[16 + 1]; -uint32 addr; -uint8 data; -bool enabled; - cheat.get(n, enabled, addr, data, code, desc); - - Enabled.Check(enabled); - Code.SetText(code); - Desc.SetText(desc); -} - -void CheatEditorWindow::UpdateItem(int n) { - if(n == -1 || n >= cheat.count())return; - -char status[16 + 1], desc[128 + 1], code[16 + 1], result[16 + 1]; -uint32 addr; -uint8 data; -bool enabled; - cheat.get(n, enabled, addr, data, code, desc); - -char t[256]; - sprintf(t, "%s|%s|%s|%0.6x = %0.2x", enabled == true ? "On" : "Off", desc, code, addr, data); - CheatList.SetItemText(n, t); -} - -void CheatEditorWindow::AddItem(const char *status, const char *desc, const char *code, const char *result) { -char t[256]; - sprintf(t, "%s|%s|%s|%s", status, desc, code, result); - CheatList.AddItem(t); -} - -void CheatEditorWindow::Show() { - Refresh(); - Window::Show(); -} - -void CheatEditorWindow::Setup() { - Header.Create(this, "visible", 0, 0, 475, 30, "Cheat Code Editor"); - Header.SetFont(global::font_header); - -int x = 15, y = 30; - CheatList.Create(this, "visible|edge", x, y, 460, 205); - CheatList.AddColumn(Listview::LEFT, 50, "Status"); - CheatList.AddColumn(Listview::LEFT, 246, "Description"); - CheatList.AddColumn(Listview::LEFT, 80, "Code"); - CheatList.AddColumn(Listview::LEFT, 80, "Result"); - y += 210; - - Enabled.Create(this, "visible", x, y, 460, 15, "Enabled"); - y += 15; - CodeLabel.Create(this, "visible", x, y + 4, 65, 15, "Code:"); - Code.Create(this, "visible|edge", x + 65, y, 75, 20); - Code.SetFont(global::fwf); - y += 20; - DescLabel.Create(this, "visible", x, y + 4, 65, 15, "Description:"); - Desc.Create(this, "visible|edge", x + 65, y, 250, 20); - y += 25; - - AddCode.Create (this, "visible", x, y, 65, 25, "Add"); - EditCode.Create (this, "visible", x + 65, y, 65, 25, "Edit"); - DeleteCode.Create(this, "visible", x + 130, y, 65, 25, "Delete"); - ClearCode.Create (this, "visible", x + 195, y, 65, 25, "Clear"); - y += 30; - - GlobalEnable.Create(this, "visible|disabled", x, y, 460, 15, "Enable cheat system"); - GlobalEnable.Check(); - y += 15; - - Clear(); -} diff --git a/src/ui/win/settings/ui_cheateditor.h b/src/ui/win/settings/ui_cheateditor.h deleted file mode 100644 index ac31a105..00000000 --- a/src/ui/win/settings/ui_cheateditor.h +++ /dev/null @@ -1,30 +0,0 @@ -class CheatEditorWindow : public Window { -public: -Label Header; -Listview CheatList; -Checkbox Enabled; -Label CodeLabel; -Editbox Code; -Label DescLabel; -Editbox Desc; -Button AddCode; -Button EditCode; -Button DeleteCode; -Button ClearCode; -Checkbox GlobalEnable; - - bool Event(EventInfo &info); - - void CheatAdd(); - void CheatEdit(); - void CheatDelete(); - void CheatClear(); - void Refresh(); - void Clear(); - void LoadItem(int n); - void UpdateItem(int n); - void AddItem(const char *status, const char *desc, const char *code, const char *result); - - void Show(); - void Setup(); -} wCheatEditor; diff --git a/src/ui/win/settings/ui_coloradjust.cpp b/src/ui/win/settings/ui_coloradjust.cpp deleted file mode 100644 index 9bfaf2fe..00000000 --- a/src/ui/win/settings/ui_coloradjust.cpp +++ /dev/null @@ -1,102 +0,0 @@ -bool ColorAdjustWindow::Event(EventInfo &info) { - switch(info.event_id) { - - case EVENT_CHANGED: { - if(info.control == &ContrastSlider) { - config::snes.contrast = ContrastSlider.GetPos(); - ContrastLabel.SetText("Contrast: %d", int32(config::snes.contrast)); - snes.update_color_lookup_table(); - } else if(info.control == &BrightnessSlider) { - config::snes.brightness = BrightnessSlider.GetPos(); - BrightnessLabel.SetText("Brightness: %d", int32(config::snes.brightness)); - snes.update_color_lookup_table(); - } else if(info.control == &GammaSlider) { - config::snes.gamma = GammaSlider.GetPos(); - GammaLabel.SetText("Gamma: %0.2f", double(config::snes.gamma) / 100.0); - snes.update_color_lookup_table(); - } - } break; - - case EVENT_CLICKED: { - if(info.control == &GammaRamp) { - config::snes.gamma_ramp.toggle(); - GammaRamp.Check(config::snes.gamma_ramp); - snes.update_color_lookup_table(); - } else if(info.control == &Sepia) { - config::snes.sepia.toggle(); - Sepia.Check(config::snes.sepia); - snes.update_color_lookup_table(); - } else if(info.control == &Grayscale) { - config::snes.grayscale.toggle(); - Grayscale.Check(config::snes.grayscale); - snes.update_color_lookup_table(); - } else if(info.control == &Invert) { - config::snes.invert.toggle(); - Invert.Check(config::snes.invert); - snes.update_color_lookup_table(); - } else if(info.control == &Restore) { - config::snes.contrast = 0; - config::snes.brightness = 0; - config::snes.gamma = 80; - config::snes.gamma_ramp = true; - config::snes.sepia = false; - config::snes.grayscale = false; - config::snes.invert = false; - ContrastSlider.SetPos(config::snes.contrast); - BrightnessSlider.SetPos(config::snes.brightness); - GammaSlider.SetPos(config::snes.gamma); - ContrastLabel.SetText("Contrast: %d", int32(config::snes.contrast)); - BrightnessLabel.SetText("Brightness: %d", int32(config::snes.brightness)); - GammaLabel.SetText("Gamma: %0.2f", double(config::snes.gamma) / 100.0); - GammaRamp.Check(config::snes.gamma_ramp); - Sepia.Check(config::snes.sepia); - Grayscale.Check(config::snes.grayscale); - Invert.Check(config::snes.invert); - snes.update_color_lookup_table(); - } - } break; - - } - - return false; -} - -void ColorAdjustWindow::Setup() { - Header.Create(this, "visible", 0, 0, 475, 30, "Color Adjustment"); - Header.SetFont(global::font_header); - -int x = 15, y = 30; - ContrastLabel.Create(this, "visible", x, y, 100, 15); - ContrastLabel.SetText("Contrast: %d", int32(config::snes.contrast)); - ContrastSlider.Create(this, "visible", x + 105, y - 3, 355, 25); - ContrastSlider.SetRange(-96, 95); - ContrastSlider.SetPos(int32(config::snes.contrast)); - - BrightnessLabel.Create(this, "visible", x, y + 25, 100, 15); - BrightnessLabel.SetText("Brightness: %d", int32(config::snes.brightness)); - BrightnessSlider.Create(this, "visible", x + 105, y - 3 + 25, 355, 25); - BrightnessSlider.SetRange(-96, 95); - BrightnessSlider.SetPos(int32(config::snes.brightness)); - - GammaLabel.Create(this, "visible", x, y + 50, 100, 15); - GammaLabel.SetText("Gamma: %0.2f", double(config::snes.gamma) / 100.0); - GammaSlider.Create(this, "visible", x + 105, y - 3 + 50, 355, 25); - GammaSlider.SetRange(10, 500); - GammaSlider.SetPos(int32(config::snes.gamma)); - y += 75; - - GammaRamp.Create(this, "visible", x, y, 475, 15, "Half gamma adjust (darkens image, helps prevent washed out colors)"); - GammaRamp.Check(config::snes.gamma_ramp); - y += 15; - Sepia.Create(this, "visible", x, y, 475, 15, "Sepia"); - Sepia.Check(config::snes.sepia); - y += 15; - Grayscale.Create(this, "visible", x, y, 475, 15, "Grayscale"); - Grayscale.Check(config::snes.grayscale); - y += 15; - Invert.Create(this, "visible", x, y, 475, 15, "Invert colors"); - Invert.Check(config::snes.invert); - y += 20; - - Restore.Create(this, "visible", x, y, 120, 25, "Restore Defaults"); -} diff --git a/src/ui/win/settings/ui_coloradjust.h b/src/ui/win/settings/ui_coloradjust.h deleted file mode 100644 index c3089a62..00000000 --- a/src/ui/win/settings/ui_coloradjust.h +++ /dev/null @@ -1,19 +0,0 @@ -class ColorAdjustWindow : public Window { -public: -Label Header; -Label ContrastLabel; -Slider ContrastSlider; -Label BrightnessLabel; -Slider BrightnessSlider; -Label GammaLabel; -Slider GammaSlider; -Checkbox GammaRamp; -Checkbox Sepia; -Checkbox Grayscale; -Checkbox Invert; -Button Restore; - - bool Event(EventInfo &info); - - void Setup(); -} wColorAdjust; diff --git a/src/ui/win/settings/ui_emusettings.cpp b/src/ui/win/settings/ui_emusettings.cpp deleted file mode 100644 index 1a237043..00000000 --- a/src/ui/win/settings/ui_emusettings.cpp +++ /dev/null @@ -1,100 +0,0 @@ -bool EmuSettingsWindow::Event(EventInfo &info) { - switch(info.event_id) { - - case EVENT_CHANGED: { - if(info.control == &Port1) { - config::snes.controller_port0 = Port1.GetSelection(); - snes.port_set_deviceid(0, config::snes.controller_port0); - } else if(info.control == &Port2) { - config::snes.controller_port1 = Port2.GetSelection(); - snes.port_set_deviceid(1, config::snes.controller_port1); - } - } break; - - case EVENT_CLICKED: { - if(info.control == &HDMAEnable || info.control == &OffsetEnable || - info.control == &BG1P0 || info.control == &BG1P1 || - info.control == &BG2P0 || info.control == &BG2P1 || - info.control == &BG3P0 || info.control == &BG3P1 || - info.control == &BG4P0 || info.control == &BG4P1 || - info.control == &OAMP0 || info.control == &OAMP1 || - info.control == &OAMP2 || info.control == &OAMP3 - ) { - config::cpu.hdma_enable = HDMAEnable.Checked(); - config::ppu.opt_enable = OffsetEnable.Checked(); - config::ppu.bg1_pri0_enable = BG1P0.Checked(); - config::ppu.bg1_pri1_enable = BG1P1.Checked(); - config::ppu.bg2_pri0_enable = BG2P0.Checked(); - config::ppu.bg2_pri1_enable = BG2P1.Checked(); - config::ppu.bg3_pri0_enable = BG3P0.Checked(); - config::ppu.bg3_pri1_enable = BG3P1.Checked(); - config::ppu.bg4_pri0_enable = BG4P0.Checked(); - config::ppu.bg4_pri1_enable = BG4P1.Checked(); - config::ppu.oam_pri0_enable = OAMP0.Checked(); - config::ppu.oam_pri1_enable = OAMP1.Checked(); - config::ppu.oam_pri2_enable = OAMP2.Checked(); - config::ppu.oam_pri3_enable = OAMP3.Checked(); - } - } break; - - } - - return false; -} - -void EmuSettingsWindow::Setup() { - Header.Create(this, "visible", 0, 0, 475, 30, "Emulation Settings"); - Header.SetFont(global::font_header); - -int x = 15, y = 30; - PortSelectionLabel.Create(this, "visible", x, y, 460, 15, "Controller port selection:"); - y += 18; - - Port1Label.Create(this, "visible", x, y + 3, 90, 15, "Controller Port 1:"); - Port1.Create(this, "visible", x + 90, y, 135, 400, "None|Joypad 1|Joypad 2"); - Port2Label.Create(this, "visible", x + 230, y + 3, 90, 15, "Controller Port 2:"); - Port2.Create(this, "visible", x + 320, y, 135, 400, "None|Joypad 1|Joypad 2"); - y += 26; - - Separator1.Create(this, "visible|sunken", x, y, 460, 3); - y += 8; - - HDMAEnable.Create(this, "visible|auto", x, y, 460, 15, "Enable HDMA"); - OffsetEnable.Create(this, "visible|auto", x, y + 15, 460, 15, "Enable offset-per-tile effects"); - y += 35; - - Separator2.Create(this, "visible|sunken", x, y, 460, 3); - y += 8; - - PPULayerSettings.Create(this, "visible", x, y, 460, 15, "PPU layer enable settings:"); - BG1P0.Create(this, "visible|auto", x, y + 15, 100, 15, "BG1 Priority 0"); - BG1P1.Create(this, "visible|auto", x + 100, y + 15, 100, 15, "BG1 Priority 1"); - BG2P0.Create(this, "visible|auto", x, y + 30, 100, 15, "BG2 Priority 0"); - BG2P1.Create(this, "visible|auto", x + 100, y + 30, 100, 15, "BG2 Priority 1"); - BG3P0.Create(this, "visible|auto", x, y + 45, 100, 15, "BG3 Priority 0"); - BG3P1.Create(this, "visible|auto", x + 100, y + 45, 100, 15, "BG3 Priority 1"); - BG4P0.Create(this, "visible|auto", x, y + 60, 100, 15, "BG4 Priority 0"); - BG4P1.Create(this, "visible|auto", x + 100, y + 60, 100, 15, "BG4 Priority 1"); - OAMP0.Create(this, "visible|auto", x, y + 75, 100, 15, "OAM Priority 0"); - OAMP1.Create(this, "visible|auto", x + 100, y + 75, 100, 15, "OAM Priority 1"); - OAMP2.Create(this, "visible|auto", x + 200, y + 75, 100, 15, "OAM Priority 2"); - OAMP3.Create(this, "visible|auto", x + 300, y + 75, 100, 15, "OAM Priority 3"); - - HDMAEnable.Check(); - OffsetEnable.Check(); - BG1P0.Check(); - BG1P1.Check(); - BG2P0.Check(); - BG2P1.Check(); - BG3P0.Check(); - BG3P1.Check(); - BG4P0.Check(); - BG4P1.Check(); - OAMP0.Check(); - OAMP1.Check(); - OAMP2.Check(); - OAMP3.Check(); - - Port1.SetSelection(config::snes.controller_port0); - Port2.SetSelection(config::snes.controller_port1); -} diff --git a/src/ui/win/settings/ui_emusettings.h b/src/ui/win/settings/ui_emusettings.h deleted file mode 100644 index 38183be7..00000000 --- a/src/ui/win/settings/ui_emusettings.h +++ /dev/null @@ -1,21 +0,0 @@ -class EmuSettingsWindow : public Window { -public: -Label PortSelectionLabel; -Label Port1Label; -Combobox Port1; -Label Port2Label; -Combobox Port2; -Label Separator1; -Label Header; -Checkbox HDMAEnable; -Checkbox OffsetEnable; -Label Separator2; -Label PPULayerSettings; -Checkbox BG1P0, BG1P1; -Checkbox BG2P0, BG2P1; -Checkbox BG3P0, BG3P1; -Checkbox BG4P0, BG4P1; -Checkbox OAMP0, OAMP1, OAMP2, OAMP3; - bool Event(EventInfo &info); - void Setup(); -} wEmuSettings; diff --git a/src/ui/win/settings/ui_inputconfig.cpp b/src/ui/win/settings/ui_inputconfig.cpp deleted file mode 100644 index 321f94ca..00000000 --- a/src/ui/win/settings/ui_inputconfig.cpp +++ /dev/null @@ -1,249 +0,0 @@ -void CALLBACK wInputConfigInputTimerProc(HWND hwnd, UINT msg, UINT event, DWORD time) { - if(!uiInput)return; - ui_poll_input(&wInputConfig, false); -} - -uint InputConfigWindow::SelectionToDevice(uint selection) { - switch(selection) { - case 0: return SNES::DEVICEID_JOYPAD1; - case 1: return SNES::DEVICEID_JOYPAD2; - default: return SNES::DEVICEID_NONE; - } -} - -uint InputConfigWindow::DeviceToSelection(uint device) { - switch(device) { - case SNES::DEVICEID_JOYPAD1: return 0; - case SNES::DEVICEID_JOYPAD2: return 1; - default: return 0; - } -} - -bool InputConfigWindow::Event(EventInfo &info) { - switch(info.event_id) { - - case EVENT_DRAW: { - PAINTSTRUCT ps; - HDC hdc = BeginPaint(hwnd, &ps); - HDC hdcsrc = CreateCompatibleDC(hdc); - HBITMAP hbm = LoadBitmap(GetModuleHandle(0), MAKEINTRESOURCE(101)); - SelectObject(hdcsrc, hbm); - BitBlt(hdc, 285, 169, 190, 100, hdcsrc, 0, 0, SRCCOPY); - DeleteDC(hdcsrc); - DeleteObject(hbm); - EndPaint(hwnd, &ps); - } break; - - case EVENT_INPUTKEYDOWN: { - if(button_update.active == true) { - button_update.id = info.control_id; - ButtonUpdateEnd(); - } - } break; - - case EVENT_CHANGED: { - if(info.control == &Resistance) { - config::input.axis_resistance = Resistance.GetPos(); - ResistanceLabel.SetText("Joypad axis resistance: %d%%", (uint)config::input.axis_resistance); - } else if(info.control == &Selected) { - switch(SelectionToDevice(Selected.GetSelection())) { - case SNES::DEVICEID_JOYPAD1: AllowBadInput.Check(config::input.joypad1.allow_invalid_input); break; - case SNES::DEVICEID_JOYPAD2: AllowBadInput.Check(config::input.joypad2.allow_invalid_input); break; - } - UpdateButtonList(); - } - } break; - - case EVENT_DOUBLECLICKED: { - if(info.control == &ButtonList) { - int sel = ButtonList.GetSelection(); - if(sel != -1) { - button_update.primary = true; - ButtonUpdateBegin(sel); - } - } - } break; - - case EVENT_CLICKED: { - if(info.control == &ButtonUpdatePrimary || - info.control == &ButtonUpdateSecondary) { - int sel = ButtonList.GetSelection(); - if(sel != -1) { - button_update.primary = (info.control == &ButtonUpdatePrimary); - ButtonUpdateBegin(sel); - } - } else if(info.control == &ButtonClear) { - int sel = ButtonList.GetSelection(); - if(sel != -1) { - button_update.primary = true; - ButtonUpdateBegin(sel); - button_update.id = uiInput->key.esc; - ButtonUpdateEnd(); - - button_update.primary = false; - ButtonUpdateBegin(sel); - button_update.id = uiInput->key.esc; - ButtonUpdateEnd(); - } - } else if(info.control == &AllowBadInput) { - switch(SelectionToDevice(Selected.GetSelection())) { - case SNES::DEVICEID_JOYPAD1: - config::input.joypad1.allow_invalid_input.toggle(); - AllowBadInput.Check(config::input.joypad1.allow_invalid_input); - break; - case SNES::DEVICEID_JOYPAD2: - config::input.joypad2.allow_invalid_input.toggle(); - AllowBadInput.Check(config::input.joypad2.allow_invalid_input); - break; - } - } - } break; - - } - - return false; -} - -const char *InputConfigWindow::GetCaption(uint button) { - switch(button) { - case SNES::JOYPAD_UP: return "Up"; - case SNES::JOYPAD_DOWN: return "Down"; - case SNES::JOYPAD_LEFT: return "Left"; - case SNES::JOYPAD_RIGHT: return "Right"; - case SNES::JOYPAD_A: return "A"; - case SNES::JOYPAD_B: return "B"; - case SNES::JOYPAD_X: return "X"; - case SNES::JOYPAD_Y: return "Y"; - case SNES::JOYPAD_L: return "L"; - case SNES::JOYPAD_R: return "R"; - case SNES::JOYPAD_SELECT: return "Select"; - case SNES::JOYPAD_START: return "Start"; - } - return ""; -} - -void InputConfigWindow::UpdateButtonList() { - ButtonList.DeleteAllItems(); -char t[512], tmp[512]; -stringarray str, part; -uint device = SelectionToDevice(Selected.GetSelection()); - -#define add(__label, __bn) \ - strcpy(tmp, uiInput->key.find((uiInput->get_key(device, SNES::JOYPAD_##__bn) >> 0) & 4095)); \ - strcat(tmp, " | "); \ - strcat(tmp, uiInput->key.find((uiInput->get_key(device, SNES::JOYPAD_##__bn) >> 16) & 4095)); \ - split(part, " | ", tmp); \ - replace(part[0], "null", ""); \ - replace(part[1], "null", ""); \ - if(count(part) < 2)strcpy(part[1], ""); \ - sprintf(t, #__label "|%s|%s", strptr(part[0]), strptr(part[1])); \ - ButtonList.AddItem(t) - - add(Up, UP); add(Down, DOWN); add(Left, LEFT); add(Right, RIGHT); - add(Y, Y); add(X, X); add(B, B); add(A, A); - add(L, L); add(R, R); add(Select, SELECT); add(Start, START); - -#undef add -} - -void InputConfigWindow::ButtonUpdateBegin(uint button) { - if(button_update.active == true)return; - -// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 -//convert Up, Down, Left, Right, Y, X, B, A, L, R, Select, Start -//to B, Y, Select, Start, Up, Down, Left, Right, A, X, L, R -uint translate_table[12] = { 4, 5, 6, 7, 1, 9, 0, 8, 10, 11, 2, 3 }; - button_update.active = true; - button_update.controller = SelectionToDevice(Selected.GetSelection()); - button_update.button = translate_table[button]; - - Message.SetText("Press key or button for '%s', " - "or press escape to clear button assignment.", - GetCaption(button_update.button)); - SetFocus(Message.hwnd); - SetTimer(hwnd, 0, 50, wInputConfigInputTimerProc); -} - -void InputConfigWindow::ButtonUpdateEnd() { - if(button_update.active == false)return; - - button_update.active = false; - KillTimer(hwnd, 0); - -uint id = button_update.id; - if(id == uiInput->key.esc) { id = 0; } - -uint old_id = uiInput->get_key(button_update.controller, button_update.button); - if(button_update.primary == true) { - id &= 0xffff; - id |= old_id & ~0xffff; - } else { - id <<= 16; - id |= old_id & 0xffff; - } - - uiInput->set_key(button_update.controller, button_update.button, id); - - Message.SetText("Button updated. Select another button to update."); -int sel = ButtonList.GetSelection(); - UpdateButtonList(); - ButtonList.SetSelection(sel); -} - -void InputConfigWindow::Show() { - Selected.SetSelection(0); - AllowBadInput.Check(config::input.joypad1.allow_invalid_input); - Message.SetText("Select button to update."); - UpdateButtonList(); - Window::Show(); -} - -void InputConfigWindow::Hide() { - if(button_update.active == true) { - button_update.active = false; - KillTimer(hwnd, 0); - } - Window::Hide(); -} - -void InputConfigWindow::Setup() { - Header.Create(this, "visible", 0, 0, 475, 30, "Input Configuration"); - Header.SetFont(global::font_header); - -int x = 15, y = 30; - ResistanceLabel.Create(this, "visible", x, y + 3, 150, 15); - ResistanceLabel.SetText("Joypad axis resistance: %d%%", uint(config::input.axis_resistance)); - Resistance.Create(this, "visible", x + 150, y, 310, 25); - Resistance.SetRange(10, 90); - Resistance.SetPos(config::input.axis_resistance); - y += 25; - - SelectLabel.Create(this, "visible", x, y + 3, 150, 15, "Select controller to configure:"); - Selected.Create(this, "visible", x + 150, y, 100, 200); - Selected.AddItem("Controller 1"); - Selected.AddItem("Controller 2"); - y += 25; - - Separator.Create(this, "visible|sunken", x, y + 1, 460, 3); - y += 9; - - Message.Create(this, "visible", x, y, 460, 15); - y += 20; - - ButtonList.Create(this, "visible|edge", x, y, 265, 195); - ButtonList.AddColumn(Listview::LEFT, 61, "Button"); - ButtonList.AddColumn(Listview::LEFT, 100, "Primary"); - ButtonList.AddColumn(Listview::LEFT, 100, "Secondary"); - ButtonUpdatePrimary.Create(this, "visible", x + 270, y, 92, 25, "Set Primary"); - ButtonUpdateSecondary.Create(this, "visible", x + 270 + 98, y, 92, 25, "Set Secondary"); - ButtonClear.Create(this, "visible", x + 270, y + 30, 190, 25, "Clear Primary + Secondary"); - y += 200; - - AllowBadInput.Create(this, "visible", x, y, 460, 15, - "Allow up+down and left+right button combinations (not recommended -- can trigger bugs)"); - y += 15; -} - -InputConfigWindow::InputConfigWindow() { - button_update.active = false; -} diff --git a/src/ui/win/settings/ui_inputconfig.h b/src/ui/win/settings/ui_inputconfig.h deleted file mode 100644 index d20a1654..00000000 --- a/src/ui/win/settings/ui_inputconfig.h +++ /dev/null @@ -1,38 +0,0 @@ -class InputConfigWindow : public Window { -public: -Label Header; -Label ResistanceLabel; -Slider Resistance; -Label SelectLabel; -Combobox Selected; -Label Separator; -Label Message; -Listview ButtonList; -Button ButtonUpdatePrimary; -Button ButtonUpdateSecondary; -Button ButtonClear; -Checkbox AllowBadInput; - -struct { - bool primary; - bool active; - uint controller; - uint button; - uint id; -} button_update; - - uint SelectionToDevice(uint selection); - uint DeviceToSelection(uint device); - - bool Event(EventInfo &info); - void Show(); - void Hide(); - - const char *GetCaption(uint button); - void UpdateButtonList(); - void ButtonUpdateBegin(uint button); - void ButtonUpdateEnd(); - void Setup(); - - InputConfigWindow(); -} wInputConfig; diff --git a/src/ui/win/settings/ui_rastersettings.cpp b/src/ui/win/settings/ui_rastersettings.cpp deleted file mode 100644 index 87ddb49a..00000000 --- a/src/ui/win/settings/ui_rastersettings.cpp +++ /dev/null @@ -1,33 +0,0 @@ -bool RasterSettingsWindow::Event(EventInfo &info) { - switch(info.event_id) { - - case EVENT_CHANGED: { - if(info.control == &PScanlineSlider) { - } else if(info.control == &IScanlineSlider) { - } - } break; - - } - - return false; -} - -void RasterSettingsWindow::Setup() { - Header.Create(this, "visible", 0, 0, 475, 30, "Raster Settings"); - Header.SetFont(global::font_header); - -int x = 15, y = 30; - ScanlineLabel.Create(this, "visible", x, y, 460, 15, - "Scanline intensity adjust: (0% = no scanlines, 100% = full scanlines)"); - y += 20; - - PScanlineLabel.Create(this, "visible", x, y, 100, 15); - PScanlineSlider.Create(this, "visible", x + 105, y - 3, 355, 25); - PScanlineSlider.SetRange(0, 100); - y += 25; - - IScanlineLabel.Create(this, "visible", x, y, 100, 15); - IScanlineSlider.Create(this, "visible", x + 105, y - 3, 355, 25); - IScanlineSlider.SetRange(0, 100); - y += 25; -} diff --git a/src/ui/win/settings/ui_rastersettings.h b/src/ui/win/settings/ui_rastersettings.h deleted file mode 100644 index a538f5b3..00000000 --- a/src/ui/win/settings/ui_rastersettings.h +++ /dev/null @@ -1,13 +0,0 @@ -class RasterSettingsWindow : public Window { -public: -Label Header; -Label ScanlineLabel; -Label PScanlineLabel; -Slider PScanlineSlider; -Label IScanlineLabel; -Slider IScanlineSlider; - - bool Event(EventInfo &info); - - void Setup(); -} wRasterSettings; diff --git a/src/ui/win/settings/ui_settings.cpp b/src/ui/win/settings/ui_settings.cpp deleted file mode 100644 index 21956074..00000000 --- a/src/ui/win/settings/ui_settings.cpp +++ /dev/null @@ -1,52 +0,0 @@ -bool SettingsWindow::Event(EventInfo &info) { - switch(info.event_id) { - - case EVENT_CLOSE: { - Hide(); - return true; - } break; - - case EVENT_CHANGED: { - if(info.control == &Panel) { - switch(Panel.GetSelection()) { - case PANEL_VIDEOSETTINGS: settings.set_active_panel(&wVideoSettings); break; - case PANEL_COLORADJUST: settings.set_active_panel(&wColorAdjust); break; - case PANEL_RASTERSETTINGS: settings.set_active_panel(&wRasterSettings); break; - case PANEL_EMUSETTINGS: settings.set_active_panel(&wEmuSettings); break; - case PANEL_INPUTCONFIG: settings.set_active_panel(&wInputConfig); break; - case PANEL_CHEATEDITOR: settings.set_active_panel(&wCheatEditor); break; - default: settings.set_active_panel(0); break; - } - SetFocus(Panel.hwnd); - } - } break; - - } - - return false; -} - -void SettingsWindow::Show() { - settings.show_active_panel(); - Window::Show(); - Panel.Focus(); -} - -void SettingsWindow::Hide() { - Window::Hide(); - settings.hide_active_panel(); -} - -void SettingsWindow::Setup() { - Panel.Create(this, "visible|edge", 5, 5, 150, 360, - "Video Settings|" - "Color Adjustment|" - "Raster Settings|" - "Emulation Settings|" - "Input Configuration|" - "Cheat Code Editor" - ); -//Panel.SetFont(global::font_list); - - settings.set_active_panel(&wVideoSettings); -} diff --git a/src/ui/win/settings/ui_settings.h b/src/ui/win/settings/ui_settings.h deleted file mode 100644 index 06f973de..00000000 --- a/src/ui/win/settings/ui_settings.h +++ /dev/null @@ -1,19 +0,0 @@ -enum { - PANEL_VIDEOSETTINGS = 0, - PANEL_COLORADJUST, - PANEL_RASTERSETTINGS, - PANEL_EMUSETTINGS, - PANEL_INPUTCONFIG, - PANEL_CHEATEDITOR, -}; - -class SettingsWindow : public Window { -public: -Listbox Panel; - - bool Event(EventInfo &info); - - void Show(); - void Hide(); - void Setup(); -} wSettings; diff --git a/src/ui/win/settings/ui_videosettings.cpp b/src/ui/win/settings/ui_videosettings.cpp deleted file mode 100644 index 2d1a97ce..00000000 --- a/src/ui/win/settings/ui_videosettings.cpp +++ /dev/null @@ -1,99 +0,0 @@ -bool VideoSettingsWindow::Event(EventInfo &info) { - switch(info.event_id) { - - case EVENT_CHANGED: - case EVENT_CLICKED: { - if(info.control == &VideoProfile) { - //LoadSettings(VideoProfile.GetSelection()); - } else if(info.control == &ApplySettings) { - //SaveSettings(VideoProfile.GetSelection()); - } else if(info.control == &SelectProfile) { - //event::set_video_profile(VideoProfile.GetSelection()); - } else if(info.control == &ManualRenderSize) { - UpdateControls(); - } - } break; - - } - - return false; -} - -void VideoSettingsWindow::UpdateControls() { -bool r = ManualRenderSize.Checked(); - Multiplier.Enable(!r); - FixAspectRatio.Enable(!r); - RenderWidth.Enable(r); - RenderHeight.Enable(r); - - r = (VideoProfile.GetSelection() == 1); - FullResWidth.Enable(r); - FullResHeight.Enable(r); - FullResHz.Enable(r); -} - -void VideoSettingsWindow::Show() { -//VideoProfile.SetSelection(config::video.profile); -//LoadSettings(config::video.profile); - Window::Show(); -} - -void VideoSettingsWindow::Setup() { - Header.Create(this, "visible", 0, 0, 475, 30, "Video Settings"); - Header.SetFont(global::font_header); - -int x = 15, y = 30; - VideoProfileLabel.Create(this, "visible", x, y + 3, 135, 15, "Video profile to configure:"); - VideoProfile.Create(this, "visible", x + 135, y, 90, 200, "Windowed|Fullscreen"); - y += 26; - - Separator1.Create(this, "visible|sunken", x, y, 460, 3); - y += 8; - - SoftwareFilterLabel.Create(this, "visible", x, y + 3, 85, 15, "Software filter:"); - SoftwareFilter.Create(this, "visible", x + 85, y, 140, 200, - "None|NTSC|HQ2x|Scale2x"); - - HardwareFilterLabel.Create(this, "visible", x + 235, y + 3, 85, 15, "Hardware filter:"); - HardwareFilter.Create(this, "visible", x + 320, y, 140, 200, - "None|Bilinear"); - y += 25; - - VideoStandardLabel.Create(this, "visible", x, y + 3, 85, 15, "Video standard:"); - VideoStandard.Create(this, "visible", x + 85, y, 140, 200, - "NTSC|PAL"); - - MultiplierLabel.Create(this, "visible", x + 235, y + 3, 85, 15, "Multiplier:"); - Multiplier.Create(this, "visible", x + 320, y, 140, 200, - "1x|2x|3x|4x|5x"); - y += 25; - - FixAspectRatio.Create(this, "visible|auto", x, y, 460, 16, "Correct aspect ratio"); - Scanlines.Create(this, "visible|auto", x, y + 15, 460, 15, "Enable hardware scanlines"); - ManualRenderSize.Create(this, "visible|auto", x, y + 30, 460, 15, "Manual render screen size"); - y += 47; - - RenderWidthLabel.Create(this, "visible", x, y + 3, 90, 15, "Render width:"); - RenderWidth.Create(this, "visible|edge", x + 90, y, 50, 20); - RenderHeightLabel.Create(this, "visible", x + 150, y + 3, 90, 15, "Render height:"); - RenderHeight.Create(this, "visible|edge", x + 240, y, 50, 20); - y += 25; - - Separator2.Create(this, "visible|sunken", x, y, 460, 3); - y += 8; - - TripleBuffering.Create(this, "visible|auto", x, y, 460, 15, "Triple buffering (buggy, causes sound desync)"); - y += 20; - - FullResWidthLabel.Create(this, "visible", x, y + 3, 90, 15, "Resolution width:"); - FullResWidth.Create(this, "visible|edge", x + 90, y, 50, 20); - FullResHeightLabel.Create(this, "visible", x + 150, y + 3, 90, 15, "Resolution height:"); - FullResHeight.Create(this, "visible|edge", x + 240, y, 50, 20); - FullResHzLabel.Create(this, "visible", x + 300, y + 3, 70, 15, "Refresh rate:"); - FullResHz.Create(this, "visible|edge", x + 370, y, 50, 20); - y += 27; - - ApplySettings.Create(this, "visible", x, y, 120, 25, "Apply settings"); - SelectProfile.Create(this, "visible", x + 125, y, 120, 25, "Set as active profile"); - y += 25; -} diff --git a/src/ui/win/settings/ui_videosettings.h b/src/ui/win/settings/ui_videosettings.h deleted file mode 100644 index 1ce5e4ee..00000000 --- a/src/ui/win/settings/ui_videosettings.h +++ /dev/null @@ -1,38 +0,0 @@ -class VideoSettingsWindow : public Window { -public: -Label Header; -Label VideoProfileLabel; -Combobox VideoProfile; -Label Separator1; -Label SoftwareFilterLabel; -Combobox SoftwareFilter; -Label HardwareFilterLabel; -Combobox HardwareFilter; -Label VideoStandardLabel; -Combobox VideoStandard; -Label MultiplierLabel; -Combobox Multiplier; -Checkbox FixAspectRatio; -Checkbox Scanlines; -Checkbox ManualRenderSize; -Label RenderWidthLabel; -Editbox RenderWidth; -Label RenderHeightLabel; -Editbox RenderHeight; -Label Separator2; -Checkbox TripleBuffering; -Label FullResWidthLabel; -Editbox FullResWidth; -Label FullResHeightLabel; -Editbox FullResHeight; -Label FullResHzLabel; -Editbox FullResHz; -Button ApplySettings; -Button SelectProfile; - - bool Event(EventInfo &info); - void UpdateControls(); - - void Show(); - void Setup(); -} wVideoSettings; diff --git a/src/ui/win/ui.cpp b/src/ui/win/ui.cpp deleted file mode 100644 index cc804117..00000000 --- a/src/ui/win/ui.cpp +++ /dev/null @@ -1,66 +0,0 @@ -#include "ui_input.cpp" -#include "ui_main.cpp" -#include "ui_about.cpp" -#include "settings/settings.cpp" -#include "debugger/debugger.cpp" - -void init_ui() { -HDC hdc = GetDC(0); -long height; - height = -MulDiv(8, GetDeviceCaps(hdc, LOGPIXELSY), 72); - global::vwf = CreateFont(height, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "Tahoma"); - height = -MulDiv(8, GetDeviceCaps(hdc, LOGPIXELSY), 72); - global::fwf = CreateFont(height, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "Courier New"); - height = -MulDiv(9, GetDeviceCaps(hdc, LOGPIXELSY), 72); - global::font_about = CreateFont(height, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "Verdana"); - height = -MulDiv(14, GetDeviceCaps(hdc, LOGPIXELSY), 72); - global::font_header = CreateFont(height, 0, 0, 0, FW_BOLD, 0, 0, 0, 0, 0, 0, 0, 0, "Verdana"); - height = -MulDiv(10, GetDeviceCaps(hdc, LOGPIXELSY), 72); - global::font_list = CreateFont(height, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "Comic Sans MS"); - ReleaseDC(0, hdc); - - wMain.SetBackgroundColor(0, 0, 0); - wMain.SetIcon(100); - wMain.Create(0, "bsnes", config::misc.window_style, 0, 0, 256, 224, BSNES_TITLE); - wMain.Center(); - - wAbout.SetIcon(100); - wAbout.Create(0, "bsnes_about", "topmost|title", 0, 0, 325, 155, "About bsnes..."); - wAbout.Center(); - - init_settings(); - init_debugger(); - - uiVideo = - config::system.video == "none" ? (Video*)new Video() : - config::system.video == "dd" ? (Video*)new VideoDD(wMain.hwnd) : - (Video*)new VideoD3D(wMain.hwnd); - uiAudio = - config::system.audio == "none" ? (Audio*)new Audio() : - (Audio*)new AudioDS(wMain.hwnd); - uiInput = - config::system.input == "none" ? (Input*)new Input() : - (Input*)new InputDI(wMain.hwnd); - - uiVideo->init(); - uiAudio->init(); - uiInput->init(); - - wMain.Setup(); - wMain.Show(); - wAbout.Setup(); - setup_settings(); - setup_debugger(); -} - -void term_ui() { - wMain.Hide(); - - uiVideo->term(); - uiAudio->term(); - uiInput->term(); - - SafeDelete(uiVideo); - SafeDelete(uiAudio); - SafeDelete(uiInput); -} diff --git a/src/ui/win/ui.h b/src/ui/win/ui.h deleted file mode 100644 index 99a035dc..00000000 --- a/src/ui/win/ui.h +++ /dev/null @@ -1,91 +0,0 @@ -#define KeyDown(__key) ((GetAsyncKeyState(__key) & 0x8000) ? 1 : 0) - -enum { - EVENT_INPUTKEYDOWN = EVENT_USER + 0, - EVENT_INPUTKEYUP = EVENT_USER + 1, -}; - -namespace global { -Font vwf, fwf, font_about, font_header, font_list; -}; - -enum { -MENU_FILE = 100, - MENU_FILE_LOAD, - MENU_FILE_LOAD_SPECIAL, - //--- - MENU_FILE_LOAD_ST, - MENU_FILE_LOAD_STDUAL, - MENU_FILE_UNLOAD, - MENU_FILE_RESET, - MENU_FILE_POWER, - MENU_FILE_EXIT, - -MENU_SETTINGS, - MENU_SETTINGS_FRAMESKIP, - MENU_SETTINGS_FRAMESKIP_0, - //--- - MENU_SETTINGS_FRAMESKIP_1, - MENU_SETTINGS_FRAMESKIP_2, - MENU_SETTINGS_FRAMESKIP_3, - MENU_SETTINGS_FRAMESKIP_4, - MENU_SETTINGS_FRAMESKIP_5, - MENU_SETTINGS_FRAMESKIP_6, - MENU_SETTINGS_FRAMESKIP_7, - MENU_SETTINGS_FRAMESKIP_8, - MENU_SETTINGS_FRAMESKIP_9, - MENU_SETTINGS_SHOWFPS, -//--- - MENU_SETTINGS_MUTE, -//--- - MENU_SETTINGS_SPEED_REGULATION, - MENU_SETTINGS_SPEED_REGULATION_ENABLE, - //--- - MENU_SETTINGS_SPEED_REGULATION_SLOWEST, - MENU_SETTINGS_SPEED_REGULATION_SLOW, - MENU_SETTINGS_SPEED_REGULATION_NORMAL, - MENU_SETTINGS_SPEED_REGULATION_FAST, - MENU_SETTINGS_SPEED_REGULATION_FASTEST, - MENU_SETTINGS_CONFIGURATION, - MENU_SETTINGS_DEBUGGER, - -MENU_MISC, - MENU_MISC_SCREENSHOT, - MENU_MISC_LOGAUDIO, - MENU_MISC_CHEATEDITOR, -//--- - MENU_MISC_ABOUT, -}; - -class MainWindow : public Window { -public: -uint8 frameskip, frameskip_pos; -uint8 regulation_speed; - -struct { - bool fullscreen; - uint32 x, y, refresh_rate; - uint32 width, height; -} vi; - void SetFrameskip(uint fs); - void SetRegulationSpeed(uint speed); - - bool Event(EventInfo &info); - - void Setup(); - - MainWindow() { frameskip = frameskip_pos = 0; } -} wMain; - -class AboutWindow : public Window { -public: -Button Ok; - -static const char about_text[4096]; - bool Event(EventInfo &info); - - void Setup(); -} wAbout; - -#include "settings/settings.h" -#include "debugger/debugger.h" diff --git a/src/ui/win/ui_about.cpp b/src/ui/win/ui_about.cpp deleted file mode 100644 index 91d5afab..00000000 --- a/src/ui/win/ui_about.cpp +++ /dev/null @@ -1,50 +0,0 @@ -const char AboutWindow::about_text[4096] = "" - " bsnes -- version " BSNES_VERSION "\r\n" - " Author: byuu\r\n" - " Project began: October 14th, 2004\r\n" - "\r\n\r\n" - "Contributors:\r\n" - " anomie, blargg, DMV27, GIGO, kode54, Nach,\r\n" - " Overload, Richard Bannister, TRAC, zones"; - -bool AboutWindow::Event(EventInfo &info) { - switch(info.event_id) { - - case EVENT_CLOSE: { - Hide(); - return true; - } break; - - case EVENT_DRAW: { - PAINTSTRUCT ps; - HDC hdc = BeginPaint(hwnd, &ps); - - HDC hdcsrc = CreateCompatibleDC(hdc); - HICON hicon = LoadIcon(GetModuleHandle(0), MAKEINTRESOURCE(100)); - DrawIcon(hdc, 5, 10, hicon); - DeleteObject(hicon); - - SelectObject(hdc, (HGDIOBJ)global::font_about); - SetBkMode(hdc, TRANSPARENT); - RECT rc; - SetTextColor(hdc, RGB(0, 0, 0)); - SetRect(&rc, 5, 5, 315, 145); - DrawText(hdc, about_text, strlen(about_text), &rc, DT_TOP | DT_LEFT); - - EndPaint(hwnd, &ps); - } break; - - case EVENT_CLICKED: { - if(info.control == &Ok) { - Hide(); - } - } break; - - } - - return false; -} - -void AboutWindow::Setup() { - Ok.Create(this, "visible", 220, 125, 100, 25, "Ok"); -} diff --git a/src/ui/win/ui_input.cpp b/src/ui/win/ui_input.cpp deleted file mode 100644 index 05a39d64..00000000 --- a/src/ui/win/ui_input.cpp +++ /dev/null @@ -1,29 +0,0 @@ -bool8 old_keystate[4096]; - -void ui_poll_input(Window *focus, bool require_window_focus = true) { - if(require_window_focus == true) { - if(GetFocus() != focus->hwnd)return; - } - - uiInput->poll_hw(); - -bool8 *keystate = uiInput->keystate; -EventInfo info; - info.window = focus; - info.window_id = focus->id; - info.control = 0; - - for(int i = 0; i < 4096; i++) { - if(!old_keystate[i] && keystate[i]) { - info.event_id = EVENT_INPUTKEYDOWN; - info.control_id = i; - focus->Event(info); - } else if(old_keystate[i] && !keystate[i]) { - info.event_id = EVENT_INPUTKEYUP; - info.control_id = i; - focus->Event(info); - } - } - - memcpy(old_keystate, keystate, sizeof(keystate)); -} diff --git a/src/ui/win/ui_main.cpp b/src/ui/win/ui_main.cpp deleted file mode 100644 index cb74bea3..00000000 --- a/src/ui/win/ui_main.cpp +++ /dev/null @@ -1,284 +0,0 @@ -void CALLBACK wMainInputTimerProc(HWND hwnd, UINT msg, UINT event, DWORD time) { - if(uiInput) { ui_poll_input(&wMain); } -} - -void MainWindow::SetFrameskip(uint fs) { - frameskip = fs % 10; - frameskip_pos = 0; - - CheckMenuItem(MENU_SETTINGS_FRAMESKIP_0, fs == 0); - CheckMenuItem(MENU_SETTINGS_FRAMESKIP_1, fs == 1); - CheckMenuItem(MENU_SETTINGS_FRAMESKIP_2, fs == 2); - CheckMenuItem(MENU_SETTINGS_FRAMESKIP_3, fs == 3); - CheckMenuItem(MENU_SETTINGS_FRAMESKIP_4, fs == 4); - CheckMenuItem(MENU_SETTINGS_FRAMESKIP_5, fs == 5); - CheckMenuItem(MENU_SETTINGS_FRAMESKIP_6, fs == 6); - CheckMenuItem(MENU_SETTINGS_FRAMESKIP_7, fs == 7); - CheckMenuItem(MENU_SETTINGS_FRAMESKIP_8, fs == 8); - CheckMenuItem(MENU_SETTINGS_FRAMESKIP_9, fs == 9); -} - -void MainWindow::SetRegulationSpeed(uint speed) { - speed %= 5; - regulation_speed = speed; - - switch(speed) { - case 0: uiAudio->set_frequency(config::system.speed_slowest); break; - case 1: uiAudio->set_frequency(config::system.speed_slow); break; - case 2: uiAudio->set_frequency(config::system.speed_normal); break; - case 3: uiAudio->set_frequency(config::system.speed_fast); break; - case 4: uiAudio->set_frequency(config::system.speed_fastest); break; - } - - CheckMenuItem(MENU_SETTINGS_SPEED_REGULATION_SLOWEST, speed == 0); - CheckMenuItem(MENU_SETTINGS_SPEED_REGULATION_SLOW, speed == 1); - CheckMenuItem(MENU_SETTINGS_SPEED_REGULATION_NORMAL, speed == 2); - CheckMenuItem(MENU_SETTINGS_SPEED_REGULATION_FAST, speed == 3); - CheckMenuItem(MENU_SETTINGS_SPEED_REGULATION_FASTEST, speed == 4); -} - -bool MainWindow::Event(EventInfo &info) { - switch(info.event_id) { - - case EVENT_INPUTKEYDOWN: { - keymap *key = &uiInput->key; - uint id = info.control_id; - bool ctrl = uiInput->keydown(key->lctrl) || uiInput->keydown(key->rctrl); - if(id == key->esc) { - ShowMenu(!MenuVisible()); - Center(); - } else if(id == key->f12) { - if(bsnes.get_state() == bSNES::RUN) { - bsnes.set_state(bSNES::STOP); - } else if(bsnes.get_state() == bSNES::STOP) { - bsnes.set_state(bSNES::RUN); - } - //no idea why this is needed, keydown event should only occur once; - //however it is being called repeatedly when F11 is held down ... - Sleep(200); - } else if((id == key->minus && !ctrl) || id == key->numpad_minus) { - if(frameskip > 0)SetFrameskip(frameskip - 1); - } else if((id == key->plus && !ctrl) || id == key->numpad_plus) { - if(frameskip < 9)SetFrameskip(frameskip + 1); - } else if(id == key->minus && ctrl) { - if(regulation_speed > 0)SetRegulationSpeed(regulation_speed - 1); - } else if(id == key->plus && ctrl) { - if(regulation_speed < 4)SetRegulationSpeed(regulation_speed + 1); - } - } break; - - case EVENT_DRAW: { - if(r_mem->cart_loaded() == true) { - uiVideo->refresh(); - } - } break; - - case EVENT_MENUENTER: { - //program is paused while menu is active, which - //causes audio to hang. clear audio buffer so no - //sound is output during this time. - uiAudio->clear_audio(); - } break; - - case EVENT_MENUEXIT: { - time_t timeout = time(0); - //wait for enter key to be released... - while(difftime(time(0), timeout) < 3) { - if(!KeyDown(VK_RETURN))break; - } - //...and then clear input, so that emulation does - //not see that enter was pressed during menu event - uiInput->clear_input(); - } break; - - case EVENT_MENUCLICKED: { - switch(info.control_id) { - - case MENU_FILE_LOAD: { - event::load_rom_normal(); - } break; - - case MENU_FILE_LOAD_ST: { - event::load_rom_st(); - } break; - - case MENU_FILE_LOAD_STDUAL: { - event::load_rom_stdual(); - } break; - - case MENU_FILE_UNLOAD: { - event::unload_rom(); - } break; - - case MENU_FILE_RESET: { - if(cartridge.loaded() == true) { - snes.reset(); - dprintf("* Reset"); - } - } break; - - case MENU_FILE_POWER: { - if(cartridge.loaded() == true) { - snes.power(); - dprintf("* Power"); - } - } break; - - case MENU_FILE_EXIT: { - PostQuitMessage(0); - } break; - - case MENU_SETTINGS_FRAMESKIP_0: - case MENU_SETTINGS_FRAMESKIP_1: - case MENU_SETTINGS_FRAMESKIP_2: - case MENU_SETTINGS_FRAMESKIP_3: - case MENU_SETTINGS_FRAMESKIP_4: - case MENU_SETTINGS_FRAMESKIP_5: - case MENU_SETTINGS_FRAMESKIP_6: - case MENU_SETTINGS_FRAMESKIP_7: - case MENU_SETTINGS_FRAMESKIP_8: - case MENU_SETTINGS_FRAMESKIP_9: { - SetFrameskip(info.control_id - MENU_SETTINGS_FRAMESKIP_0); - } break; - - case MENU_SETTINGS_SHOWFPS: { - config::misc.show_fps.toggle(); - SetWindowText(hwnd, BSNES_TITLE); - CheckMenuItem(MENU_SETTINGS_SHOWFPS, config::misc.show_fps); - } break; - - case MENU_SETTINGS_MUTE: { - config::snes.mute.toggle(); - CheckMenuItem(MENU_SETTINGS_MUTE, config::snes.mute); - } break; - - case MENU_SETTINGS_SPEED_REGULATION_ENABLE: { - config::system.regulate_speed.toggle(); - CheckMenuItem(MENU_SETTINGS_SPEED_REGULATION_ENABLE, config::system.regulate_speed); - } break; - - case MENU_SETTINGS_SPEED_REGULATION_SLOWEST: - case MENU_SETTINGS_SPEED_REGULATION_SLOW: - case MENU_SETTINGS_SPEED_REGULATION_NORMAL: - case MENU_SETTINGS_SPEED_REGULATION_FAST: - case MENU_SETTINGS_SPEED_REGULATION_FASTEST: { - SetRegulationSpeed(info.control_id - MENU_SETTINGS_SPEED_REGULATION_SLOWEST); - } break; - - case MENU_SETTINGS_CONFIGURATION: { - wSettings.Show(); - } break; - - case MENU_SETTINGS_DEBUGGER: { - (debugger.active() == false) ? debugger.activate() : debugger.deactivate(); - } break; - - case MENU_MISC_LOGAUDIO: { - if(MenuItemChecked(MENU_MISC_LOGAUDIO) == false) { - CheckMenuItem(MENU_MISC_LOGAUDIO); - snes.log_audio_enable(); - } else { - UncheckMenuItem(MENU_MISC_LOGAUDIO); - snes.log_audio_disable(); - } - } break; - - case MENU_MISC_CHEATEDITOR: { - settings.set_active_panel(&wCheatEditor); - wSettings.Panel.SetSelection(PANEL_CHEATEDITOR); - wSettings.Show(); - } break; - - case MENU_MISC_ABOUT: { - wAbout.Show(); - } break; - - } - } break; - - case EVENT_DESTROY: { - PostQuitMessage(0); - } break; - - } - - return false; -} - -void MainWindow::Setup() { -char t[128]; - CreateMenu(); - - AddMenuGroup("&File"); - AddMenuItem(MENU_FILE_LOAD, "&Load Cartridge"); - AddMenuGroup("&Load Special"); - AddMenuItem(MENU_FILE_LOAD_ST, "&Load ST Cartridge"); - AddMenuItem(MENU_FILE_LOAD_STDUAL, "&Load ST Dual Cartridges"); - EndMenuGroup(); - AddMenuItem(MENU_FILE_UNLOAD, "&Unload Cartridge"); - AddMenuSeparator(); - AddMenuItem(MENU_FILE_RESET, "&Reset System"); - AddMenuItem(MENU_FILE_POWER, "&Power Cycle System"); - AddMenuSeparator(); - AddMenuItem(MENU_FILE_EXIT, "E&xit"); - EndMenuGroup(); - - AddMenuGroup("&Settings"); - AddMenuGroup("&Frameskip"); - AddMenuItem(MENU_SETTINGS_FRAMESKIP_0, "&0 (Off)"); - AddMenuSeparator(); - AddMenuItem(MENU_SETTINGS_FRAMESKIP_1, "&1"); - AddMenuItem(MENU_SETTINGS_FRAMESKIP_2, "&2"); - AddMenuItem(MENU_SETTINGS_FRAMESKIP_3, "&3"); - AddMenuItem(MENU_SETTINGS_FRAMESKIP_4, "&4"); - AddMenuItem(MENU_SETTINGS_FRAMESKIP_5, "&5"); - AddMenuItem(MENU_SETTINGS_FRAMESKIP_6, "&6"); - AddMenuItem(MENU_SETTINGS_FRAMESKIP_7, "&7"); - AddMenuItem(MENU_SETTINGS_FRAMESKIP_8, "&8"); - AddMenuItem(MENU_SETTINGS_FRAMESKIP_9, "&9"); - EndMenuGroup(); - - AddMenuItem(MENU_SETTINGS_SHOWFPS, "&Show FPS"); - - AddMenuSeparator(); - AddMenuItem(MENU_SETTINGS_MUTE, "&Mute Sound Output"); - AddMenuSeparator(); - - AddMenuGroup("Speed &Regulation"); - AddMenuItem(MENU_SETTINGS_SPEED_REGULATION_ENABLE, "&Enable"); - AddMenuSeparator(); - sprintf(t, "Slowest (%d%%)", uint(100.0 * (double(config::system.speed_slowest) / 32000.0))); - AddMenuItem(MENU_SETTINGS_SPEED_REGULATION_SLOWEST, t); - sprintf(t, "&Slow (%d%%)", uint(100.0 * (double(config::system.speed_slow) / 32000.0))); - AddMenuItem(MENU_SETTINGS_SPEED_REGULATION_SLOW, t); - sprintf(t, "&Normal (%d%%)", uint(100.0 * (double(config::system.speed_normal) / 32000.0))); - AddMenuItem(MENU_SETTINGS_SPEED_REGULATION_NORMAL, t); - sprintf(t, "&Fast (%d%%)", uint(100.0 * (double(config::system.speed_fast) / 32000.0))); - AddMenuItem(MENU_SETTINGS_SPEED_REGULATION_FAST, t); - sprintf(t, "Fastest (%d%%)", uint(100.0 * (double(config::system.speed_fastest) / 32000.0))); - AddMenuItem(MENU_SETTINGS_SPEED_REGULATION_FASTEST, t); - EndMenuGroup(); - - AddMenuItem(MENU_SETTINGS_CONFIGURATION, "&Configuration"); - AddMenuItem(MENU_SETTINGS_DEBUGGER, "&Debugger"); - EndMenuGroup(); - - AddMenuGroup("&Misc"); - AddMenuItem(MENU_MISC_LOGAUDIO, "&Log Audio Data"); - AddMenuItem(MENU_MISC_CHEATEDITOR, "&Cheat Code Editor"); - AddMenuSeparator(); - AddMenuItem(MENU_MISC_ABOUT, "&About"); - EndMenuGroup(); - - ShowMenu(); - - CheckMenuItem(MENU_SETTINGS_SHOWFPS, config::misc.show_fps); - CheckMenuItem(MENU_SETTINGS_MUTE, config::snes.mute); - CheckMenuItem(MENU_SETTINGS_SPEED_REGULATION_ENABLE, config::system.regulate_speed); - - event::update_video_settings(); - SetFrameskip(0); - SetRegulationSpeed(2); - - SetTimer(hwnd, 0, 50, wMainInputTimerProc); -}