Compare commits

...
15 Commits
Author SHA1 Message Date
byuu 926ffd9695 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
2008-02-04 16:16:34 +00:00
byuu a1389a2ba3 Update to bsnes v027r14? release.
> Anything is better than re-using an already well-established name
> (even a short acronym like "vai"), but that's just me.




               I was asking about eliminating the extra layer of
abstraction in the UI.

 But since you brought it up ... I'm sure vai has been taken before.
Quark certainly has been. Hell, BSNES was taken by some people trying
to port ZSNES to BeOS (they gave up). Given, none of those have
anywhere near the popularity of the programming language. But eh, I
_really_ don't care. I like the name, and nobody else in the world is
ever going to use any of my software libraries anyway, so I'll use it.

               Speaking of which, I hate the name miu for the GUI
library, it sounds stupid. So in the spirit of selecting **totally
random names** that are _certainly not associated with any licensed /
trademarked / copyrighted proper nouns_, **especially** not from any
_video games_ or somesuch; I've renamed miu to the **completely
arbitrary** name of hiro. Boy, I'm so creative and original with
naming.

               ---

               That said, new WIP up, with Windows binary.

 Windows users, be sure to set system.video to "direct3d",
system.audio to "directsound", system.input to "directinput".

               Linux users, "opengl", "openal" and "sdl" are
preferred. "xv", "ao" and "x" are safer fallbacks.

               Changes:

               - Finally found a problem with dots in folder names, it
screws with GNU make. So foo.bar has been renamed foo_bar.
 - Decided to drop the pointless duplications of folder names into
file names, such as miu.gtk/miu.gtk.button.cpp -> hiro_gtk/button.cpp.
Same for libco.
 - ruby is completed, all 13 drivers are in the ruby namespace, and
bound to the base ruby.cpp file. The UI just calls
ruby::video.driver("name"); to select a driver. Before v028's release,
omitting the name will select the default best-case driver. ruby is no
longer dependent on anything besides nall (the template library, for
those losing track in the sea of _arbitrary_ names.)
 - miu became hiro, as mentioned above. Like ruby, I wanted to remove
the need for platform-specific tests inside the UI for it. There's now
a base hiro.cpp file that will auto-select the best implementation and
compile it. Just build hiro.cpp on whatever platform you want and it
does the rest.
 - UI platform abstraction removed. src/ui/miu was moved to src/ui.
The two main.cpp files were merged into one. With the GUI wrapper and
hardware drivers moved out of this folder, it's quite orderly there
now.
 - More improvements to the Makefile system. New folder obj/
accumulates all of the object files now. Added streq(al) and
strn(ot)e(qual) to Makefile.string library. Improved the delete
command to support deleting from either obj/*.$(obj) with rm, or
obj\*.$(obj) with del. bsnes executable is moved up one folder above
src/ for both Windows and Linux now. The batch file doesn't perform
this copy anymore.
               - Killed the doc/ folder. Just a pointless, out of date
.dia file there anyway.

               Future plans:
 - I want to make ruby take advantage of nall/config.hpp, and output
to ~/.bsnes/ruby.cfg. This file will contain driver-specific
configuration settings. I may or may not add editing support for them
to the advanced window. Or maybe I'll be lazy and just throw
everything into bsnes.cfg.
               - Really need to add automatic driver selection to
ruby. Can't release it with "" defaulting to no driver.
 - I'd like to replace the god-awful GTK+ video driver (that spawns a
new window) with SDL video. Yeah, I know. At least with SDL_WINDOWID
environment variable hack, it will go into the main window. I'll
probably make this the default driver on Linux, since ATI can't even
seem to get X-Video right with their drivers.

[No archive available]
2008-02-03 10:12:00 +00:00
byuu 5263ffb7aa Update to bsnes v027r13? release.
Yeah, I'll probably worry about the axis stuff later. I didn't intend
to spend a ton of time on adding SDL input support like this, to be
honest. Though I guess I should have known better with SDL and Linux.

 Okay, new WIP with no Windows binary. There's really no reason to get
the WIP. The only change is renaming vai to ruby. That's right matz,
ruby. Deal.

 Moved the folder to lib/ruby from ui/vai. The main point is trying to
make it easier to use for other applications. Instead of having each
app include all sorts of platform-specific header files and manually
create the objects at runtime, it's all done for you now. Just
#include <ruby/ruby.h>, call ruby::input.init(const char *driver = "")
and use it. So far, only the input driver has been ported in this way.

 Note: if you use this WIP, you'll want to make sure system.input is
set to either "sdl"/Linux or "directinput"/Windows. It defaults to no
driver with "", for the time being.

 Once I finish the video and audio drivers in the same manner, I'm
strongly considering eliminating the "multiple UI" bindings, as my
Win32/GTK+ wrapper is pretty much meant to wrap all possible
interfaces into one. This means it would be harder to create a
standalone, GUI-less SDL or VESA2/DOS only port in the future, for
example. But I really don't have any plans to do that anyway. So it's
just needless separation of components, really.

 That extra separation layer was being blurred a lot recently anyway.
The config.cpp file was adding miu-specific GUI commands, where they
had to be to bind to interface.cpp, which binds to the core. Meh.

             So basically, I'm wanting to change the structure from:
             core <> abstracted UI <> miu, SDL, VESA2
             to:
             core <> miu

 Even with this, porting to pure SDL would still be doable in the
future, you'd just have more code to write to do it.

             Any objections?

[No archive available]
2008-02-02 11:58:00 +00:00
byuu 1744bcb99c Update to bsnes v027r12? release.
New WIP.

 I removed property.hpp, as I really didn't like it. Reverted Audio
wrappers to use cap/get/set method that Video and Input wrappers use.
Yay, consistency.

 Capped input.sdl to only poll up to six axes. I suppose if someone
really only has 2 or 4, and has phantom 5,6 axes, they'll run into
Glenn's problem. Meh. We'll wait for a way to configure vai settings
on a per-driver basis to work on that problem more. I was thinking of
just giving it the handle to either unique configuration class
objects, or to the bsnes.cfg one. Just dump all settings for all
(compiled-in) drivers in there, in case the user wants to keep
swapping between drivers.

 Added Nightcrawler's screensaver and monitorpower disable code. Happy
now? Note, I don't use screensavers, nor do I feel like playing for
ten minutes to verify. If anyone else could verify whether or not it's
working, I'd appreciate it. Note again, this won't work on X11, only
Windows.

 Improved the makefile a bit more for Visual C++. Disabled the warning
about passing "this" in a constructor. It's valid and safe C++, and
the only way to implement a bidirectional private implementation by
reference. The last warning is comparison between unsigned long long
and bool, which I can't see a problem with (it gives no warnings about
unsigned long and bool, either). Should I just disable that warning,
as well?







> It ended up being axis 6, but yes, that pinpointed it exactly.




 Oops, sorry. When there are two of something, I always have a really
hard time telling them apart (x/y, hidori/migi, edge/level
(sensitive), etc etc). Not sure why that is. Three or more choices and
it's never a problem.







> Would need porting for BSD gamepads however.




 If it doesn't support BSD, then I'm not really interested. I kind of
have to special case Windows (~95+% userbase), but I don't personally
want to waste my time writing Linux only code.

[No archive available]
2008-02-01 11:46:00 +00:00
byuu 6362044c05 Update to bsnes v027r11? release.
Alright, new WIP posted, Windows binary included.

 I've added the auto-pause setting. I removed the formerly useless
joypad selection comboboxes, as I want to stick those in the main menu
when they are ready anyway. It defaults to auto-pause, so that
discussion is moot now.

 Don't complain that three combo boxes are not natural compared to two
checkboxes -- I don't care. There are only three possible states, and
I like it the way it is. Thanks in advance.

 Nach, you have my humble thanks for your input today. This was
definitely a lot easier than I thought it would be with your help.

               For those curious, here's how things look at the
moment:

               [image]

 I also fixed up the CPU usage when paused. I tried to stress test as
many things as possible (manual pause <> auto pause conflicts,
statusbar update failures, toggling settings in real time, etc etc),
but I may have overlooked something. Rigorous testing would be
appreciated :)

               ---

 In other news, I completely rewrote the Makefile. It is now far more
advanced, and will allow you to easily remove vai modules. Once
removed, the dependencies on those modules will automatically be
removed. The source still needs to be updated to auto-detect non-
existent modules, but this is a step in the right direction.

               Take a look at some of my GNU make-fu:







    ifneq ($(findstring gcc,$(compiler)),) # GCC family
                       flags = -O3 -fomit-frame-pointer -Ilib
                       c = $(compiler) $(flags)
                       cpp = $(subst cc,++,$(compiler)) $(flags)










    ifeq ($(platform),x) # X11
                       miu = miu.gtk
                       vai = video.glx video.xv video.gtk audio.openal
    audio.oss audio.ao input.sdl input.x










    link += $(if $(findstring audio.directsound,$(vai)),$(call
    mklib,dsound))
                       link += $(if $(findstring
    audio.openal,$(vai)),$(call mklib,openal) $(call mklib,alut))
                       link += $(if $(findstring
    input.directinput,$(vai)),$(call mklib,dinput8) $(call
    mklib,dxguid))
                       link += $(if $(findstring
    input.sdl,$(vai)),`sdl-config --libs`)










    arch := $(patsubst %,$(call mkdef,%),$(arch))
                       objects := $(patsubst %,%.$(obj),$(objects))










    compile = $(strip \
                       $(if $(filter %.c,$<), \
                       $(c) $(1) $(rule), \
                       $(if $(filter %.cpp,$<), \
                       $(cpp) $(1) $(rule) \
                       ) \
                       ) \
                       )

                       %.$(obj): $<; $(call compile)










    video.glx.$(obj) : ui/vai/video/video.glx.cpp ui/vai/video/*
                       video.gtk.$(obj) : ui/vai/video/video.gtk.cpp
    ui/vai/video/*
                       $(call compile,`pkg-config --cflags gtk+-2.0`)




               Hahahahahah :)

[No archive available]
2008-01-29 07:42:00 +00:00
byuu 319b244af4 Update to bsnes v027r10? release.
New WIP posted.

 I downloaded a 64-bit Linux OS to verify that libco.x86-64.c worked
this time. Turns out the problem was that I declared "register stack =
*(long long*)to;" -- forgot the size qualifier, so it was being
truncated to 32-bits. Anyway, it works now.

 I also added two more GUI keys, one to pop open the load ROM window,
and one to pause emulation. Yes, took me eight versions, but I finally
re-added pause mode. It probably still consumes CPU time, not sure. I
don't really care, I'll fix it before release. The whole thing is
silly anyway, task scheduler is so easy to cheat. Add sleep(1) inside
the main loop and it states bsnes uses ~1-2% CPU time. As if.

               Windows binary updated, too.







> Unfortunately, it will be 64-bit and using Vista 64 Ultimate, so I'm
> not sure what all will be compatible in terms of software and
> emulators.




 32-bit software runs fine for the most part on Vista. bsnes works
there for sure. But if you want it 64-bit native, you'll have to
compile it yourself, as I have no idea how to make a 64-bit Windows
binary. Nor do I really feel like maintaining another build :/

[No archive available]
2008-01-28 06:27:00 +00:00
byuu a3f1802845 Update to bsnes v027r09? release.
New WIP. No Windows binary. This one fixes the GTK+
fullscreen issue on Openbox completely. How do I know? Because I'm
running Openbox now to verify :P
               It's pretty spiffy, whole thing is only consuming ~5mb
of memory. Total mem usage sans the 'fox is ~40mb.

 The cool part with these changes is that video no longer flickers for
one frame when you toggle the menubar in fullscreen mode anymore. Not
even on XFCE.

 Just in case, verification always helps. Hopefully it'll work on all
the esoteric window managers out there, so long as they honor the
undecorate window request. You may have some small issues if not.

 I didn't need keepabove to get on top of my XFCE panel, even when I
run the panel in Openbox. I'd like to keep it off if possible.







    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());
                       }

                       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));
                       }




 I also fixed the "esc" -> "escape" keysym for menu toggle, and
updated the x86-64 target with OpenGL + SDL input stuff. Thanks
everyone for the awesome feedback!







> EDIT3: How come you haven't added the icon to the window? Need to
> write another class for handling it (for MIU)? Adding the following
> to the end of pWindow::create() in
> 'src/lib/miu.gtk/miu.gtk.window.cpp':




 Yes, I need a way to do the same in Windows. Ideally, I need a way to
embed the icon inside the EXE, and have an API that allows me to set
the icon both on Windows and Linux from it. I'd prefer to not require
another external file for bsnes binary releases.

               Thanks for the GTK+ code, though. It's a step in the
right direction.







> I tested the linux version of bsnes with my Radeon Mobility x1400,
> and I don't get any video inside the bsnes window. I'm running
> Ubuntu, and I've set up all the ATI driver stuff, AFAIK (Compiz, at
> least, works).




 Aw ... well, thanks for trying. I kind of figured it wouldn't work.
Perhaps ATI doesn't support GLX ... I honestly have no idea. I'll look
into it.







> What other package(s) do I need to install to correct these
> warnings/errors?




               libsdl1.2-dev







> My first problem when running this WIP is that my statusbar is
> black. All black. No one else has complained, so this must just be
> happening over here... any ideas why? Also, fullscreen won't work
> for me... gameplay freezes for a moment when I toggle it and then
> continues windowed, as normal.




 Sigh. I fixed this a while back. Certain GTK+ themes weren't painting
the background of statusbars, so I embedded the statusbar inside an
event box. I don't know why it still isn't working for you. It seems
to work for everyone else now ...







> Secondly, when attempting to map my gamepad, every single key logged
> correctly... except my right directional. What? Weird.




 Good question. The SDL docs say axis 0 = x, axis 1 = y. but the two
thumbs are axes 2, 3 left and 4,5 right. The left thumb uses 2 for X
and 3 for Y, but the right uses 4 for Y and 5 for X. Since the API has
no way to tell you what direction an axis is in, I decided to play it
safe and do axis&1 over all axes. I guess I'll just hardcode for D-pad
+ two thumbs in the next version by swapping 4 and 5 ... no idea how
other apps do it.







> Finally, turning on Scale2x with or without opengl as video does
> this to the Donkey Kong Country intro (note the statusbar)...




 Longstanding issue. Never modified the hq2x and scale2x filters to
support hires modes. Only direct and NTSC do. Hoping to bypass the
issue with pixel shaders in the future. That, or wait until I cleanup
the video filter code and get it out of the core.







> Does GtkSocket not do what you're looking for?
>                    http://www.gtk.org/api/2.6/gtk/GtkSocket.html




 Nah, that's for other processes. I just need to convert an X11 handle
back to a gtk_drawing_area GtkWidget. Sounds weird, but miu only has
one handle() function for cross-platform reasons. So I make that
export an X11 handle (that Xv and OGL take) rather than a GtkWidget
handle (which requires gdkx.h header to extract the X11 handle from in
a safe manner.)

[No archive available]
2008-01-22 07:37:00 +00:00
byuu 4370acae2e Update to bsnes v027r08? release.
Okay, new WIP. This time there's a Windows binary.

 I improved input.hpp a lot, and now InputManager will scan the
joypads as well. DirectInput is fixed, so the Windows port works
again. Now that the InputCaptureWindow stuff is cleaned up, I made it
only capture joypad assignment keypresses when that window has focus.

 I'm also planning to make a "fast assign all keys" button or
something, like I used to have. Not sure how I want to do that just
yet.

               I also tested triggering UI events through the joypad,
it works great :)
 Now I just need to add entries to Input Configuration window for each
UI action. Hmm, should I list the UI entries above or below the SNES
joypad entries? (eg ui.fullscreen, joypad1.up, ... or ...
joypad2.start, ui.fullscreen?)

 The rest of my time tonight I spent working on my cross assembler,
xkas. Added sublabels to it, and some more parsing improvements. It's
getting messy already, though. Trying to write complex grammar parsers
in C++ usually does. But it has to be pure C++. No yacc, flex, etc.
So, I'll have to go back through and find redundant code to factor
out. Why would you care about xkas? Well, the sooner I get that done,
the sooner I can help out the Mother 3 translation project a bit more.
GBA cross assemblers suck for ROM hacking.







> You have a big disclaimer about how it's perfectly legal to use "_0"
> as an identifier inside a namespace... and then never actually do
> it.




 I was using it for joypad button IDs, but I just decided to go with
button_0n. I removed the comment in the latest WIP. Also added a way
to index joypad IDs at runtime, and packed the enums into a linear
list.







> Apps that process input according to 'the characters printed on the
> key' are my pet hate because I the Dvorak layout, so Z and X or WASD
> are not nearly as convenient as you might otherwise expect.




 Would require supporting every keyboard in existence, and needing
some sort of lower-level stuff to translate keycodes to raw keyboard
IDs. The only issue you'll have to reassign your keys one time on
first startup :(

 I envy you though for managing to switch to dvorak. I tried for a
really long time, I could never get above ~40wpm, whereas I get
~110wpm with qwerty now. I think programming is the worst part, all of
my brackets moved? Well, that or the fact that all apps use
Ctrl+C/X/V/Z. That hack to make Ctrl+ use qwerty on dvorak doesn't
solve the underlying issue, either.







> If there is any other areas in the bsnes ppu rendering code that you
> want me to verify in a similar fashion, please tell me, so that I
> can try and code something to prove if it is right.




               Hahah, there sure are :)

 I think the biggest one is that I've yet to test setting BG3 tilesize
to 16x16 when using Mode2/4/6's offset-per-tile mode. Does it affect
indexing? I don't think that it does. May want to also toggle BG1/2
tilesize, just for fun, but I'm almost certain I have that right
already.

 Don't worry about it if you're busy. It's obviously not a big deal
since no game in the world uses the effect (that, or I already emulate
it correctly), and I'll no doubt get around to it if I ever rewrite
the PPU emulation.

               Either way, many thanks for helping me with this :D

[No archive available]
2008-01-17 06:48:00 +00:00
byuu 5a804eac58 Update to bsnes v027r07? release.
Okay, new WIP.
 But before you download it ... there's no Windows binary, because I
haven't finished porting some changes over to DirectInput yet. So it
won't compile just yet.

             But, here's the changes anyway:
             - fixed up the recursive descent math parser, it should
reject 100% of invalid math now
 - added a new header, new.hpp, by Nach. This allows for uint8_t
*buffer = new(zeromemory) uint8_t[65536]; //zeromemory ==
memset(buffer, 0, 65536);
             - updated input.hpp more, and removed keymap.hpp
completely -- this is why DirectInput is broken right now
 - rewrote all of inputmgr.cpp, and InputCaptureWindow. The really
ugly, hackish code is now gone. InputCaptureWindow no longer needs to
hijack the main UI event loop to catch keycodes. Instead, a ~20ms
polling occurs that will alert event::key(up|down) of key changes. The
really, really good news about this, is that it also catches the UI
keypresses now, too. That means that I can now map GUI events to the
joypad, or alternate keys!! Expect that within the next release or
two.
 - ran krom's mode7 test -- holy hell, he has good eyes o.O -- took me
about 20 minutes to definitively tell which output looked correct on
my SNES. He was right of course, and I trusted him, but double
verification is always nice, right? Removed TRAC's theorem from the
mode7 code, and spruced up the formatting in that file a bit.
             - **a real emulation change!!** zones recently pointed
out that anomie figured out that $213e.d4 was PPU1 open bus. I'm
pretty sure I was really thorough when I initially added PPU1+PPU2
open bus (even verified CGRAM.d15 open bus (-much- harder than it
sounds)), but I guess I missed a bit ... odd. anomie also said that
$213e.d5 is basically tied to GND, so that should mean it always
returns 0. I read previously that it was some weird "no PPU activity
for ~40 frames" bit or something, but I don't even remember where I
saw that. I trust anomie anyway, so that means all PPU register status
bits should be accounted for. Thanks for the heads up, zones! :) Now,
of course, it's _extremely_ minor and it won't fix any games (there
aren't any known bugs anyway), but it's still nice to actually fix
something in the core for a change.

[No archive available]
2008-01-16 07:59:00 +00:00
byuu 3b65b50aea Update to bsnes v027r06? release.
Double post! Better to separate this, I think.

             Okay, new WIP lacks Windows binary, and only changes one
header.

 I figured it might be fun to show you guys what I've been doing as
far as code cleanup goes, something a little different, you know?

             Okay, here was the config.hpp file from the last WIP:
             http://byuu.cinnamonpirate.com/temp/config_old.txt

             And here is the new one:
             http://byuu.cinnamonpirate.com/temp/config_new.txt

             Or for those who do not know C++ ... :)
 Like a standard library should be, I've reverted UpperCase to
lower_case, I've converted everything to const-correctness, I've
hidden everything that should not be public, improved the code
formatting, added proper casting, removed the needless template
overloads all over the place, converted the variable names from
incomprehensible gibberish (idef, ifmt?) to clean, understandable
alternatives (default_value, type), removed needless copying of const
char* data, which means no more destructors needed, and added proper
int -> unsigned types when indexing arrays.

 The only thing left is to add better-named integer->string conversion
routines to string.hpp, to get rid of the ugly sprintf code.

[No archive available]
2008-01-09 06:53:00 +00:00
byuu a85ff8c437 Update to bsnes v027r05? release.
Another WIP, this one's really just for myself to look
over at work tomorrow.

 Changed any.hpp again to not auto upcast fundamental types, as it
causes problems such as downcasting references to long doubles and
such. Sucks how limited the any type is by forced casting 100% of the
time, but whatever ... no endian issues possible now, at least.

 I added property.hpp and bound that to the Audio class (not to Video
or Input yet). It's a lot more complicated than the old integral
identifier cap/get/set functions, but I need the char*-named list
functionality to allow changing driver-specific settings from the GUI
one day. Not too much done there yet. Need to work on it more, I'd
like to make bconfig use property.hpp rather than the IntegerSetting +
StringSetting classes. Tried to make property.hpp read in a config
file without bstring, talk about pain ... ugh.

 Tried to move bstring into nall, failed miserably. When strcpy(char*,
const char*) is in the global namespace and strcpy(string&, const
char*) is not, the compiler gets angry. Not going to work. Really
should go object-oriented entirely and ditch libc functions, but ...
that's a _lot_ of code rewriting on my part. Need to think about it
more first.

 Removed bbase.h dependency from bstring, miu and xkas. Now I just
need to do something about bkeymap.h, and things will be looking a lot
better for code sanity.

               Nach wrote the _seventh(!!)_ libco driver tonight, an
implementation using setjmp / longjmp. Pretty neat, overhead is ~20x,
which puts it only slightly worse off than Windows Fibers on my
machine. Using it in bsnes slows the emulator down by <1%, but it
should be portable across all Unix-derivative systems now. This means
eg a PS3, Alpha, SPARC, etc port should be completely doable now, just
need someone to compile it.

               Planning to position libco as a competitor to GNU Pth,
so that leaves me with:

               SDL -> vai
               wxWidgets -> miu
               GNU Pth and pthreads -> libco
               boost and Loki -> nall
               std::string -> bstring

               Good times. Now I just need to register
inventedhere.org for all of these libraries.







> but it's pointless since the sound quality of the S-DSP isn't good
> enough to make a difference.




 The only thing we could possibly bypass would be the driver / API
resampling our audio (eg 32khz -> 44khz native). Running each SNES
channel through its own hardware channel is just silly. Either use an
API that bypasses the mixer, or don't.

 And yes, there's lots of ways to "enhance" the audio. Replacing
gaussian with a higher end interpolation, bypassing the clipping, etc.
But then you end up with "better" (in most cases), but less accurate
sound.







> is anyone currently working on an enhancement snes emu?




 ZSNES adds cubic spline audio interpolation, SNES9x adds "hi-res"
mode7, ZSNES/XBOX adds rumble pad support to most games.

               Other than smaller things like that, not really.

 I've talked about adding things like rumble, a new MMC to map more
than 64mbits, CD-audio and video playback capabilities. Nobody seemed
all that interested. Eh, maybe if someone finds and sends me one of
those SNES CD player addons used by that one English teaching game,
I'll add support for that to bsnes and then rig something like Der
Langrisser to use it :P

[No archive available]
2008-01-02 07:31:00 +00:00
byuu a15d15047c Update to bsnes v027r04? release.
Okay, I posted a new WIP. This one's source only again,
since the Windows port is still unchanged.

 I went through and used std::min + std::max, rather than my own
#define, for the sole benefit of getting Nach's JMA code to compile
again (JMA includes a C++ standard header that doesn't like you
#defining min/max, apparently). I was kind of cheap with it though,
max(0, min(10, value)) -> max(0U, min(10U, value)), etc.
 Geez, std::min/max can't even cast between uint16 and uint32. What a
joke, I'll have to write my own that takes advantage of type traits.

 I also started killing off the "bheader.h" files. Since 90% of them
are just template classes, I figure I may as well stick them all in a
namespace and make something akin to boost / Loki. I'm calling this
one nall (I love making up all these names, lately). I also use gcc -I
to point to it, so you get #include <nall/array.hpp> instead of
#include "../../../lib/barray.h", much nicer.

 Taking advantage of the new template library, I added any.hpp
(generic object container), traits.hpp (type traits) and static.hpp
(static assert, if), and with that, I made stdint.hpp, which is a C++
implementation of stdint.h. Since stdint.h is part of C99, it isn't
included with all compilers (eg Visual C++). By using sizeof() and
static_if, I was able to make my own compiler-independent version of
this file. Thus, the dependency on stdint.h was removed.

               I'd be very interested in feedback on anything in nall/
(it's located in src/lib).

 Specifically, could someone with a big-endian machine test any.hpp?
I'm worried that downcasting will reverse the order of data read back.

               Example test app:






    #include <stdio.h>
                       #include <nall/any.hpp>
                       int main() {
                       nall::any t = 0x01020304;
                       printf("0x%x\n",nall::any_cast<short>(t));
    //should print 0x0304
                       return 0;
                       }










> Please byuu, can you extend the API, would you be so kind?




 Of course, I want vai to be used for more than just SNES emulation.
Though I've yet to get anyone using any of my libraries before, so it
may be a fairly pointless endeavor.

               It'll take me some time, though. I'm working on a lot
of other stuff first.







> Anyways, byuu, here's what I wrote of the OpenGL renderer so far, to
> prove its very much being worked on.




 Really cool! My only concern is the use of Win32-specific code
(header, GetForegroundWindow(), HDC stuff, setting up the pixel format
stuff) ... no idea how this is going to compile on Linux :(
               I don't know the Linux equivalents to all of the
Win32-specific stuff being done.

 Nonetheless, please take your time. I'll check it out when you have
the Win version finished. Thanks a million for making this :D







> What about guys like me who just stick to Intel HDA.




               Hah, I do the same. I'm not going to spend more on my
sound card than on my mainboard that comes _with_ onboard sound. HDA
sounds just fine to me :/

[No archive available]
2008-01-01 19:24:00 +00:00
byuu f77aca7172 Update to bsnes v027r03? release.
I have a new WIP up. Again, this one has only source, as nothing has
changed on Windows since wip01.

 This time, I've just cleaned up the OSS and OpenAL drivers. Nach will
probably want to kill me, since by cleaned up, I mean "removed lots of
not-so-helpful comments and safety checks", but I intend to add them
back. Before v028, I'd like to have vai init() functions return a
boolean success value, and have bsnes continue to fall back on lesser
drivers until there are none left, in which case it won't use one. But
it will keep the program from crashing.

 Also, I tried some black magic on the OSS4 support. Because
soundcard.h is included in a different location than the OSS3 one, I
tried manually defining the new SNDCTL options and invoking ioctl
regardless of OSS version. This is supposed to be safe -- the ioctls
should just fail silently and it will behave just like OSS3. Let me
know if you have problems compiling or using the driver with OSS3,
especially on non-Linux boxen.

             > Will you update the readme with recommendations for
which sound driver to use on which system?

 I suppose I can do that. I was planning on writing up an article
about OSS4 and such, perhaps I can just link to that in the readme.

 > I changed it to set_background_color(0, 255, 0) and sure enough I
had a green statusbar. The main window background color was still
black though. Assuming that set_background_color() is meant to be used
for the main UI this is very odd.

 Okay, here's how this works. Inside the main window, there is a view
control, which is a gtk_drawing_area(). I draw the video to this. When
bsnes is in windowed mode, obviously this control fills the entire
window. And the view control draws a black background by default. But
when you go fullscreen, the view area centers itself on your screen
(or tries to, some issues in GTK+ size requests render it non-
perfect.) Now there's the problem that the window itself is exposed on
the sides. Therefore, I have to set the window background to black
here, otherwise it will show up gray, which is _very_ distracting in
fullscreen mode, to say the least.

 Now, I only tell GTK+ to set the window to black. The reason I do
this is because just setting the formcontainer to black has no effect,
since containers do not draw a background. As for why that is causing
your statusbar to render black ... good lord, I have no idea at all
o.O

 I don't know what to do to fix this, unfortunately ... but at least
we now know where the problem is so we can research it. Thank you very
much for tracking that down [vEX], I realize my request to have an
end-user look into that was unreasonable, but it's very much
appreciated.

 > EDIT2: After some testing it doesn't appear that bsnes was guilty.
I can't reproduce the memory consumption, but it could be all the
recompiling bsnes that somehow ate all my memory.

 bsnes does appear to have a tiny memory leak at the moment. It loses
about ~100k a minute on me. I'm not sure if it's specific to the Linux
port or not. This will certainly be a hard one to track down in such a
big program.

             > I believe OpenAL is pretty smart in frequency handling.

 Definitely. I don't really like complex APIs, but the buffering
system in OpenAL will actually come in handy. I failed with
DirectSound, but maybe with OpenAL I can manage to resample audio --
maybe even let OpenAL do the resampling for me by calculating the
frequency as a measure of "how many samples should have been created"
versus "how many actually were."

 That would be awesome. Combine that with OpenGL triple buffering, and
SDL/libjsw joypad support, and wow ... I'll have something really,
really usable :)

[No archive available]
2007-12-26 13:03:00 +00:00
byuu c32195cbd6 Update to bsnes v027r02? release.
Okay, here's the deal with sound.

 wertigon's initial OpenAL driver was incomplete and produced no
audio, and _willow_'s had some Windows-specific bindings.

 So, Nach took those, some OpenAL sample code, and some other
application's OpenAL code and produced a working driver for it. Then
Nach and I refined the driver -- I got rid of the crashing on exit and
frequency changing, and both of us wrote new sample() functions.
Nach's is vastly superior on CPU resources, so we'll probably go with
that one.

               That code can be found here:
http://byuu.cinnamonpirate.com/temp/audio.openal.cpp

               This code wouldn't be possible without the help from
wertigon, _willow_ _and_ Nach, so many thanks to everyone, and I'm
sorry I wasn't able to go directly with anyone's specific OpenAL
driver. Linux compatibility was a big concern here. You'll all be
getting full credit in the source and documentation for bsnes v0.028.

               ---

 Now, as for the driver itself. It should work on Windows now with the
sample() and init() corrections, but maybe not. I don't have the means
at the moment to build a Windows binary with it, but maybe I can in
the future.

 But anyway, I don't intend to compile in OpenAL/Win support by
default with bsnes, but rather leave it as an option for those who
compile it themselves. Why? Because Windows does not come with
alut.dll and OpenAL32.dll. I don't want to require another download to
use bsnes, and I don't want to package an extra 300kb of DLLs with it
either. Plus, it doesn't seem to be working too well for most people
anyway thus far.

 Windows does come with DX9, and basically nobody has problems with
DirectSound. It's great, it has very low latency, and it seems to work
on everyone's sound cards, unlike the OpenAL stuff. So it's really not
needed for Windows.

               ---

 However, on Linux, OpenAL has a lot of good points. Unlike with
Linux/OSS3, OpenAL backends to ALSA which supports software mixing.
Meaning audacious and bsnes can run at the same time. And OpenAL has
much lower latency than libao, as well as the ability to disable speed
throttling when necessary.

               But! The OSS4 driver, with SND_DSP_COOKEDMODE,
absolutely _destroys_ even the OpenAL driver. In fact, it's even twice
as good as the DirectSound driver on Windows! No joke!

               From http://wiki.freebsd.org/RyanBeasley/ioctlref :






> ... this ioctl is meant to give processes direct access to the
> hardware buffer, giving the application the most control possible
> (ex: minimizing latency by avoiding in-kernel processing).




 With this, I get roughly ~15-20ms latency, at the very most, with
bsnes. It skips kernel processing entirely! It's hard to even describe
such a low latency. I've never heard Link's sword sound effect start
so quickly. It's really quite impressive. Remember when kode54 was
talking about ASIO or kmixer or whatever? That super low latency
kernel-level audio setup that bypasses the kernel and goes directly to
the sound card? This is it, but for Linux. It's that good.

 But the problem, of course, is Linux' obsession with ALSA, even
though OSS4 is GPLv2 now (and not to mention portable). ALSA is, of
course, total garbage. Anyone who's programmed for it knows that.

 It's very easy to install OSS4, download a DEB package, double click
it, hit install and reboot. But the problem is, many Linux distros try
their best to kill OSS now. Lots of apps are compiled by Linux distro
vendors to only support ALSA, so it does cause some problems, and you
have to reconfigure many apps to use OSS afterwards, so it's not a
very good solution to make bsnes default to the OSS driver.

 Further, because ALSA is so terrible, it causes the OpenAL driver
(which is really just a wrapper to ALSA here) to suck, and it causes
lots of static in the sound. And ALSA's OSS emulation causes severe
video lag -- bizarre, but it has something to do with the blocking
mechanism in ALSA. Only installing OSS4 fixes this. For both drivers,
in fact.

 So, because of ALSA's pathetically poor emulation of both OSS and
OpenAL, I can't default bsnes to either of these drivers. Therefore, I
have to leave the libao driver as the default, but I really recommend
the installation of OSS4 (if you haven't gotten that hint already) if
you really want the best audio possible, and don't mind losing a
couple of your favorite ALSA-only apps. If installing OSS4 is too much
of a plunge, then I still recommend experimenting with the OpenAL and
OSS (in that order) drivers under ALSA. If they work good, great. If
not, sorry, it isn't a problem with the bsnes drivers. You'll have to
stick with libao and it's terrible latency and forced blocking. Unless
someone else wants to write an ALSA driver. I have no intentions of
programming for yet another single-platform API, myself.

               ---

 With all of that said, I have a new WIP up. I'll send the link to any
Linux users who want to test it, as well. Feel free to ask.

               This WIP is source code _only_ (nothing changed on
Windows), and has both the new OpenAL and OSS drivers. Testing would
be greatly appreciated.

[No archive available]
2007-12-25 17:54:00 +00:00
byuu 161366df9b Update to bsnes v027r01? release.
I posted a new private WIP that adds the new statusbar. But much more
importantly, thanks to Nach, the Linux port now has an OSS driver.

             It's current set as the default. You can get ao again by
setting system.audio to, yep, you guessed it, "ao".

 Would some Linux users mind giving it a spin? For me, it appears to
be blocking and causing serious video lag (xv [XV_SYNC_TO_VBLANK=0] or
GTK+ video, 60hz monitor, speed regulation = normal). Not happening
for Nach ... it's quite possible the problem is just on my system.

 The complete and utter lack of perceived latency lag though, makes
this sound a million times better than the ao driver.

[No archive available]
2007-12-23 15:25:00 +00:00
305 changed files with 8060 additions and 10130 deletions

No files matched your search

+1 -1
View File
@@ -1,5 +1,5 @@
bsnes (TM) Reference License
Copyright (C) 2004 - 2007 byuu
Copyright (C) 2004 - 2008 byuu
All rights reserved
1. Definitions
+1 -7
View File
@@ -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:
------------------
+204 -234
View File
@@ -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 ""
+16 -15
View File
@@ -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 <nall/algorithm.hpp>
#include <nall/array.hpp>
#include <nall/bit.hpp>
#include <nall/config.hpp>
#include <nall/function.hpp>
#include <nall/new.hpp>
#include <nall/sort.hpp>
#include <nall/string.hpp>
#include <nall/vector.hpp>
using namespace nall;
#include <libco.h>
#include <bbase.h>
//platform-specific global functions
void alert(const char*, ...);
BIN
View File
Binary file not shown.
+1 -1
View File
@@ -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);
+2 -2
View File
@@ -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);
}
}
+3 -6
View File
@@ -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
@make platform=win compiler=mingw32-gcc
::@make platform=win compiler=mingw32-gcc enable_gzip=true enable_jma=true
@pause
+2 -1
View File
@@ -1 +1,2 @@
make PLATFORM=x-gcc-x86
make platform=x compiler=gcc
#make platform=x compiler=gcc enable_gzip=true enable_jma=true
+2 -2
View File
@@ -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
+21 -18
View File
@@ -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;
-1
View File
@@ -1,5 +1,4 @@
#include "bsx/bsx.h"
#include "superfx/superfx.h"
#include "srtc/srtc.h"
#include "sdd1/sdd1.h"
#include "cx4/cx4.h"
-3
View File
@@ -1,3 +0,0 @@
void op_unknown() {}
void op_00();
-7
View File
@@ -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;
}
-66
View File
@@ -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;
}
-65
View File
@@ -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;
}
}
-174
View File
@@ -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<int bit> 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<int bit> 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;
-42
View File
@@ -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);
}
-17
View File
@@ -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;
+1 -2
View File
@@ -1,2 +1 @@
@make PLATFORM=win-mingw-x86 clean
::@make PLATFORM=win-visualc-x86 clean
@make platform=win compiler=mingw32-gcc clean
+1 -1
View File
@@ -1 +1 @@
make PLATFORM=x-gcc-x86 clean
make platform=x compiler=gcc clean
+60 -63
View File
@@ -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);
};
+22 -23
View File
@@ -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;
};
+1 -1
View File
@@ -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;
BIN
View File
Binary file not shown.
-1
View File
@@ -14,7 +14,6 @@
#include "smp/ssmp/ssmp.h"
#include "dsp/dsp.h"
//#include "dsp/adsp/adsp.h"
#include "dsp/bdsp/bdsp.h"
#include "ppu/ppu.h"
+54 -110
View File
@@ -4,11 +4,25 @@
*/
#ifndef BBASE_H
#define BBASE_H
#define BBASE_H
#include <nall/stdint.hpp>
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 <algorithm>
using std::min;
using std::max;
#include <assert.h>
#include <limits.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
@@ -16,8 +30,6 @@
#include <time.h>
#include <math.h>
#include <new>
#if defined(_MSC_VER) || defined(__MINGW32__)
#include <io.h>
#include <direct.h>
@@ -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<typename T>
struct base_from_member {
T value;
base_from_member(T value_) : value(value_) {}
};
/*****
* template functions
*****/
@@ -153,88 +129,57 @@ template<typename T> inline void safe_release(T &handle) {
}
}
template<typename T> 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<int min, int max, typename T> inline T minmax(const T x) {
return (x < (T)min) ? (T)min : (x > (T)max) ? (T)max : x;
}
template<int bits> inline unsigned uclamp(const unsigned x) {
enum { y = (1U << bits) - 1 };
return y + ((x - y) & -(x < y)); //min(x, y);
}
template<int bits> inline unsigned uclip(const unsigned x) {
enum { m = (1U << bits) - 1 };
return (x & m);
}
template<int bits> 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<int bits> 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] = {
-185
View File
@@ -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<Setting*> 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<typename T> IntegerSetting &operator=(T x) { data = uint(x); return *this; }
template<typename T> bool operator==(T x) { return (T(data) == x); }
template<typename T> bool operator!=(T x) { return (T(data) != x); }
template<typename T> bool operator>=(T x) { return (T(data) >= x); }
template<typename T> bool operator> (T x) { return (T(data) > x); }
template<typename T> bool operator<=(T x) { return (T(data) <= x); }
template<typename T> 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
-310
View File
@@ -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
-95
View File
@@ -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);
}
-99
View File
@@ -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<string> 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
-14
View File
@@ -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
-194
View File
@@ -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
-277
View File
@@ -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
-39
View File
@@ -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
-31
View File
@@ -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
-39
View File
@@ -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
+42 -26
View File
@@ -1,21 +1,28 @@
#include "miu.h"
#include <hiro.h>
using namespace nall;
namespace ns_miu {
#if defined(_WIN32)
#include <hiro_win/hiro.cpp>
#else
#include <hiro_gtk/hiro.cpp>
#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<pWindow&>(*new pWindow(*this)),
Widget(base_from_member<pWindow&>::value),
p(base_from_member<pWindow&>::value) { type = WindowType; }
Window::Window(pWindow &p_) :
base_from_member<pWindow&>(p_),
Widget(base_from_member<pWindow&>::value),
p(base_from_member<pWindow&>::value) { type = WindowType; }
p(base_from_member<pWindow&>::value),
menu(base_from_member<pWindow&>::value),
status(base_from_member<pWindow&>::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<pCanvas&>(*new pCanvas(*this)),
FormControl(base_from_member<pCanvas&>::value),
@@ -250,4 +266,4 @@ Slider::Slider() :
FormControl(base_from_member<pSlider&>::value),
p(base_from_member<pSlider&>::value) { type = SliderType; }
} //namespace ns_miu
} //namespace libhiro
+85 -65
View File
@@ -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 <nall/array.hpp>
#include <nall/function.hpp>
#include <nall/input.hpp>
#include <nall/stdint.hpp>
#include <nall/string.hpp>
#include <nall/utility.hpp>
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<MenuRadioItem*> MenuRadioItemGroup;
typedef array<Radiobox*> RadioboxGroup;
typedef nall::array<MenuRadioItem*> MenuRadioItemGroup;
typedef nall::array<Radiobox*> 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<pWindow&>, public Widget {
class Window : private nall::base_from_member<pWindow&>, 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<uintptr_t (Event)> on_close;
function<uintptr_t (Event)> on_block;
function<uintptr_t (Event)> on_keydown;
function<uintptr_t (Event)> 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<uintptr_t (Event)> on_close;
nall::function<uintptr_t (Event)> on_block;
nall::function<uintptr_t (Event)> on_keydown;
nall::function<uintptr_t (Event)> on_keyup;
Window();
protected:
Window(pWindow&);
private:
pFriends;
pWindow &p;
};
class MenuControl : public base_from_member<pMenuControl&>, public Widget {
class MenuControl : public nall::base_from_member<pMenuControl&>, public Widget {
public:
void enable(bool = true);
void disable();
@@ -225,7 +245,7 @@ private:
pMenuControl &p;
};
class MenuGroup : public base_from_member<pMenuGroup&>, public MenuControl {
class MenuGroup : public nall::base_from_member<pMenuGroup&>, 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<pMenuItem&>, public MenuControl {
class MenuItem : public nall::base_from_member<pMenuItem&>, public MenuControl {
public:
MenuItem& create(const char *text);
MenuItem();
function<uintptr_t (Event)> on_tick;
nall::function<uintptr_t (Event)> on_tick;
private:
pFriends;
pMenuItem &p;
};
class MenuCheckItem : public base_from_member<pMenuCheckItem&>, public MenuControl {
class MenuCheckItem : public nall::base_from_member<pMenuCheckItem&>, public MenuControl {
public:
MenuCheckItem& create(const char *text);
void check(bool = true);
@@ -256,28 +276,28 @@ public:
bool checked();
MenuCheckItem();
function<uintptr_t (Event)> on_tick;
nall::function<uintptr_t (Event)> on_tick;
private:
pFriends;
pMenuCheckItem &p;
};
class MenuRadioItem : public base_from_member<pMenuRadioItem&>, public MenuControl {
class MenuRadioItem : public nall::base_from_member<pMenuRadioItem&>, public MenuControl {
public:
MenuRadioItem& create(MenuRadioItemGroup &group, const char *text);
void check();
bool checked();
MenuRadioItem();
function<uintptr_t (Event)> on_tick;
nall::function<uintptr_t (Event)> on_tick;
private:
pFriends;
pMenuRadioItem &p;
};
class MenuSeparator : public base_from_member<pMenuSeparator&>, public MenuControl {
class MenuSeparator : public nall::base_from_member<pMenuSeparator&>, public MenuControl {
public:
MenuSeparator& create();
MenuSeparator();
@@ -287,7 +307,7 @@ private:
pMenuSeparator &p;
};
class FormControl : private base_from_member<pFormControl&>, public Widget {
class FormControl : private nall::base_from_member<pFormControl&>, public Widget {
public:
void resize(uint width, uint height);
void focus();
@@ -306,7 +326,7 @@ private:
pFormControl &p;
};
class Frame : private base_from_member<pFrame&>, public FormControl {
class Frame : private nall::base_from_member<pFrame&>, 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<pCanvas&>, public FormControl {
class Canvas : private nall::base_from_member<pCanvas&>, 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<pLabel&>, public FormControl {
class Label : private nall::base_from_member<pLabel&>, 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<pButton&>, public FormControl {
class Button : private nall::base_from_member<pButton&>, public FormControl {
public:
void create(uint style, uint width, uint height, const char *text = "");
void set_text(const char *text = "");
function<uintptr_t (Event)> on_tick;
nall::function<uintptr_t (Event)> on_tick;
Button();
@@ -357,7 +377,7 @@ private:
pButton &p;
};
class Checkbox : private base_from_member<pCheckbox&>, public FormControl {
class Checkbox : private nall::base_from_member<pCheckbox&>, 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<uintptr_t (Event)> on_tick;
nall::function<uintptr_t (Event)> on_tick;
Checkbox();
@@ -374,14 +394,14 @@ private:
pCheckbox &p;
};
class Radiobox : private base_from_member<pRadiobox&>, public FormControl {
class Radiobox : private nall::base_from_member<pRadiobox&>, 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<uintptr_t (Event)> on_tick;
nall::function<uintptr_t (Event)> on_tick;
Radiobox();
@@ -390,7 +410,7 @@ private:
pRadiobox &p;
};
class Editbox : private base_from_member<pEditbox&>, public FormControl {
class Editbox : private nall::base_from_member<pEditbox&>, public FormControl {
public:
enum Style {
Multiline = 1 << 1,
@@ -416,7 +436,7 @@ private:
pEditbox &p;
};
class Listbox : private base_from_member<pListbox&>, public FormControl {
class Listbox : private nall::base_from_member<pListbox&>, public FormControl {
public:
enum Style {
Header = 1 << 1,
@@ -439,8 +459,8 @@ public:
void set_selection(int index);
void reset();
function<uintptr_t (Event)> on_change;
function<uintptr_t (Event)> on_activate;
nall::function<uintptr_t (Event)> on_change;
nall::function<uintptr_t (Event)> on_activate;
Listbox();
@@ -449,7 +469,7 @@ private:
pListbox &p;
};
class Combobox : private base_from_member<pCombobox&>, public FormControl {
class Combobox : private nall::base_from_member<pCombobox&>, 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<uintptr_t (Event)> on_change;
nall::function<uintptr_t (Event)> on_change;
Combobox();
@@ -466,7 +486,7 @@ private:
pCombobox &p;
};
class Progressbar : private base_from_member<pProgressbar&>, public FormControl {
class Progressbar : private nall::base_from_member<pProgressbar&>, 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<pSlider&>, public FormControl {
class Slider : private nall::base_from_member<pSlider&>, public FormControl {
public:
enum Style {
Horizontal = 0,
@@ -490,7 +510,7 @@ public:
uint get_position();
void set_position(uint position);
function<uintptr_t (Event)> on_change;
nall::function<uintptr_t (Event)> on_change;
Slider();
@@ -501,6 +521,6 @@ private:
#undef pFriends
} //namespace ns_miu
} //namespace libhiro
#endif //ifndef MIU_H
#endif //ifndef HIRO_H
@@ -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) {
@@ -6,7 +6,7 @@ public:
pButton(Button&);
/* internal */
/* internal */
GtkWidget *button;
GtkWidget* gtk_handle();
};
@@ -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);
@@ -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();
@@ -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) {
@@ -9,7 +9,7 @@ public:
Checkbox &self;
pCheckbox(Checkbox&);
/* internal */
/* internal */
GtkWidget *checkbox;
GtkWidget* gtk_handle();
};
@@ -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) {
@@ -9,7 +9,7 @@ public:
Combobox &self;
pCombobox(Combobox&);
/* internal */
/* internal */
GtkWidget *combobox;
uint counter;
GtkWidget* gtk_handle();
File renamed without changes.
@@ -7,7 +7,7 @@ public:
pEditbox(Editbox&);
/* internal */
/* internal */
GtkWidget *scrollbox;
GtkWidget *editbox;
GtkTextBuffer *buffer;
File renamed without changes.
@@ -10,6 +10,6 @@ public:
FormControl &self;
pFormControl(FormControl&);
/* internal */
/* internal */
virtual GtkWidget* gtk_handle();
};
File renamed without changes.
@@ -6,7 +6,7 @@ public:
pFrame(Frame&);
/* internal */
/* internal */
GtkWidget *frame;
GtkWidget* gtk_handle();
};
+121
View File
@@ -0,0 +1,121 @@
#include "hiro.h"
#include <nall/algorithm.hpp>
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
+56
View File
@@ -0,0 +1,56 @@
#ifndef HIRO_GTK_H
#define HIRO_GTK_H
#include <gtk/gtk.h>
#include <gdk/gdkx.h>
#include <gdk/gdkkeysyms.h>
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
+188
View File
@@ -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;
}
File renamed without changes.
@@ -6,7 +6,7 @@ public:
pLabel(Label&);
/* internal */
/* internal */
GtkWidget *label;
GtkWidget* gtk_handle();
};
@@ -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() {
@@ -12,7 +12,7 @@ public:
Listbox &self;
pListbox(Listbox&);
/* internal */
/* internal */
GtkWidget *scrollbox;
GtkWidget *listbox;
GtkListStore *store;
@@ -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) {
@@ -8,7 +8,7 @@ public:
MenuCheckItem &self;
pMenuCheckItem(MenuCheckItem&);
/* internal */
/* internal */
GtkWidget *item;
GtkWidget* gtk_handle();
};
File renamed without changes.
@@ -7,6 +7,6 @@ public:
MenuControl &self;
pMenuControl(MenuControl&);
/* internal */
/* internal */
virtual GtkWidget* gtk_handle();
};
File renamed without changes.
@@ -6,7 +6,7 @@ public:
pMenuGroup(MenuGroup&);
/* internal */
/* internal */
GtkWidget *group;
GtkWidget *item;
GtkWidget* gtk_handle();
@@ -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);
}
@@ -5,7 +5,7 @@ public:
MenuItem &self;
pMenuItem(MenuItem&);
/* internal */
/* internal */
GtkWidget *item;
GtkWidget* gtk_handle();
};
@@ -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() {
@@ -7,7 +7,7 @@ public:
MenuRadioItem &self;
pMenuRadioItem(MenuRadioItem&);
/* internal */
/* internal */
GtkWidget *item;
GtkWidget* gtk_handle();
};
File renamed without changes.
@@ -5,7 +5,7 @@ public:
pMenuSeparator(MenuSeparator&);
/* internal */
/* internal */
GtkWidget *item;
GtkWidget* gtk_handle();
};
@@ -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);
}
@@ -7,7 +7,7 @@ public:
pProgressbar(Progressbar&);
/* internal */
/* internal */
GtkWidget *progressbar;
GtkWidget* gtk_handle();
};
@@ -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) {
@@ -8,7 +8,7 @@ public:
Radiobox &self;
pRadiobox(Radiobox&);
/* internal */
/* internal */
GtkWidget *radiobox;
GtkWidget* gtk_handle();
};
@@ -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() {
@@ -7,7 +7,7 @@ public:
Slider &self;
pSlider(Slider&);
/* internal */
/* internal */
GtkWidget *slider;
uint slider_position;
GtkWidget* gtk_handle();
@@ -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_) {
@@ -8,6 +8,6 @@ public:
Widget &self;
pWidget(Widget&);
/* internal */
/* internal */
virtual GtkWidget* gtk_handle();
};
+262
View File
@@ -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);
}
@@ -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();
};
@@ -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) {
File renamed without changes.
@@ -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;
@@ -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);
@@ -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) {
File renamed without changes.
@@ -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) {
@@ -9,6 +9,6 @@ public:
pCombobox(Combobox&);
/* internal */
/* internal */
int combobox_selection;
};
@@ -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);
File renamed without changes.
File renamed without changes.
@@ -11,6 +11,6 @@ public:
FormControl &self;
pFormControl(FormControl&);
/* internal */
/* internal */
HWND hwnd;
};
@@ -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) {
File renamed without changes.
@@ -1,33 +1,36 @@
#include "miu.win.h"
#include "../miu.cpp"
#include "hiro.h"
namespace ns_miu {
#include <nall/algorithm.hpp>
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
+73
View File
@@ -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 <windows.h>
#include <commctrl.h>
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*> 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
+67
View File
@@ -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;
}
@@ -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) {
Loaded 100 of 305 files, more files were not shown because too many files have changed in this diff. Show more