bsnes v0.031 released
If it doesn't its kinda pointless
Manually is a pain in the ass to do for headerd roms(assuming UPS works the same as ninja):
1) Add header to rom
2) Apply ips patch to headerd rom
3) Remove header from rom
4) Tell UPS to create a UPS file from the diff between clean rom and patched headerless rom
5) Add all the copyright information from the text files into the copyright field
6) Save UPS file to disk with the correct name (No-Intro naming)
Manually is a pain in the ass to do for headerd roms(assuming UPS works the same as ninja):
1) Add header to rom
2) Apply ips patch to headerd rom
3) Remove header from rom
4) Tell UPS to create a UPS file from the diff between clean rom and patched headerless rom
5) Add all the copyright information from the text files into the copyright field
6) Save UPS file to disk with the correct name (No-Intro naming)
-
- Trooper
- Posts: 394
- Joined: Mon Feb 20, 2006 3:11 am
- Location: Space
Well, what patches are actually worth creating? Converting every IPS patch to UPS would be redundant and pointless. I believe this discussion will just be a back and forth discussion with no final decision when nothing really will get done.
[url=http://www.eidolons-inn.net/tiki-index.php?page=Kega]Kega Fusion Supporter[/url] | [url=http://byuu.cinnamonpirate.com/]bsnes Supporter[/url] | [url=http://aamirm.hacking-cult.org/]Regen Supporter[/url]
Just to clarify my earlier point: I was strictly referring to the naming convention and not any potential additional emulator functions.
All valid points but one way or the other would be pretty equal to me afaic.FitzRoy wrote:The fundamental problem is that no one loads a game without intending to run it, but on old consoles, games did not auto-run. You loaded the game, then you powered on the system. Today, it's the opposite. So it makes sense to additionally and automatically perform power on and off when loading and unloading a file to save people time and prevent them from confusing themselves. If this were bwii, just opening the program would be equivalent to powering on the system. I think pSXEmulator operates this way.
With power functions automatically performed as they are now in bsnes, "Power (Cycle)" serves practically no purpose other than to be a fast version of unloading / loading the current game. It's only there as an alternative reset mechanism, since Reset itself has different effects on the RAM than cutting the power entirely.
Problem is, if you want things to be utterly logical and descriptive, then you have to separate power from load. Because technically, it's possible to power on a system without a game in it. Technically, it's possible to insert a game into a system with the power on. But to me, that's no more worth allowing than "unhook video cable."
I know, I was being facetious in the quote above.A virtual cartridge can consist of several files that are loaded all at once: ROM, SRM, IPS/UPS, possibly even graphic packs and other files.Snark wrote:But it's not a cart! Its a file!
Not if they actually played the original system.byuu wrote:Well, I like the auto power-on from cart load.
Unload is pretty silly, true. The one big thing it does is save SRAM and cheat codes to disk, and clear out the UI stuff like the cheat code editor entries.
I also like how fast power cycle works. One option to do both. I can't imagine why anyone would want to stare at a powered off emulator window. Makes even less sense than an unloaded cart window (at that point, it's in the same state as when you first start the emu.)
But I don't like having both reset and power, either. It's confusing to everyone but developers. An end user isn't going to know about RAM persistence.
Damn, never thought I'd trigger a franpa alert... Glad to know I was wrong, though.etabeta wrote:sorry for the OT, but some clarification was needed... then we can go back and enjoy the wonderful work byuu's doing
DANGER!!!!! DISINFORMATION!!!I.S.T. wrote:*Did some googling*
Oh, Jesus Christ. He's behind MESS?
Well, there's another program I will never touch...
you should google better next time. Cowering contributes to MESS hashes files (i.e. huge xml-like files containing crcs to identify images) and detection routines (similar to the above, detecting e.g. megadrive chinese pirate games from their headers, to install the appropriate handlers for protections)
Cowering does nothing more for MESS [1], so please do not spread lies as facts
main contributors to MESS are Nathan P. Woods (which does core changes to keep MESS up-to-date with MAME), Wilbert Pol (aka judge), R.Belmont and a bunch of other brilliant developers working on the emulation of specific computers/consoles...
[1] in fact, he also provides the server which hosts the svn repository, but I guess you were referring to his coding contributions
New WIP. Please be sure to test a few games with this one to look for regressions.
I got tired of using bit packing for CPU / SMP register flags, because they do not mask the upper bits properly.
In other words, (assume big endian) if you have struct { uint8_t n:1, v:1, m:1, x:1, d:1, i:1, z:1, c:1; } p; and you set p.m = 7; it will set p.v and p.n as well. It doesn't cast the type to bool.
So I rewrote the old template struct trick, but bound it with a reference rather than relying upon union alignment. Looks something like this:
Surprisingly, benchmarks show this method is ~2x faster, but flags were never a bottleneck so it won't affect bsnes' speed.
Anyway, with this, I decided to get rid of the confusing and stupid !!() stuff all throughout the CMP and SMP opfn.cpp files. It's no longer needed since the template assignment takes only a boolean argument. Anything not zero becomes one with that.
So code such as this:
Now looks like this:
I also took the time to figure out how the hell the overflow stuff worked. Pretty neat stuff.
Essentially, overflow is set when you add/subtract two positive or two negative numbers, and the result ends up with a different sign. Hence, the sign overflowed, so your negative number is now positive, or vice versa.
A simple way to simulate it is:
int result = (int8_t)x + (int8_t)y;
bool overflow = (result < -128 || result > 127);
But there's no reason to perform signed math, since the result can't be used for anything else, not even any other flags, as the opcode math is always unsigned.
So to implement it with this:
int result = (uint8_t)x + (uint8_t)y;
We just verify that both signs in x and y are the same, and that their sign is different from the result to set overflow, eg:
bool overflow = (x & 0x80) == (y & 0x80) && (x & 0x80) != (result & 0x80);
But that's kind of slow. We can test a single bit for equality and merge the &0x80's by using a XOR table:
0^0=0, 0^1=1, 1^0=1, 1^1=0
The trick here is that if the two bits are equal, we get 0, if they are not equal, we get one.
So if we want to see if x&0x80 == y&0x80, we can do:
!((x ^ y) & 0x80);
... or we can simply invert the XOR result so that 1 = equal, 0 = different, eg ~(x ^ y) & 0x80;
The latter is nice because it keeps the bit positions in-tact. Whereas the former reduces to 1 or 0, the latter remains 0x80 or 0x00. This is good for chaining, as I'll demonstrate below.
Do the same for the second test and we get:
bool overflow = ~(x ^ y) & 0x80 && (x ^ result) & 0x80;
We complement the former because we want to verify they are the same, we don't for the latter because we want to verify that they have changed.
Now we can basically use one more trick to combine the two bit masks here. We want to return 1 when overflow is set, so we can look for a pattern that will only return one when both the first and second tests pass.
An AND table works great here. 0&0=0, 0&1=0, 1&0=0, 1&1=1. Only if both are true do we end up with 1.
So this means we can AND the two results, and then mask the only bit we care about once to get the result, eg:
bool overflow = ~(x ^ y) & (x ^ result) & 0x80;
And there we go, that's where that bizarre math trick comes from. I realized while doing this something that bugged me in the past.
I used to think that for some reason, the S-SMP add overflow test required x^y & y^r, whereas S-CPU add overflow used x^y & x^r. Probably because I read the algorithm from Snes9x's sources or something.
But that was flawed -- since addition is commutative, it doesn't matter whether the latter is x^result or y^result. Only in subtraction does the order matter, where you must always use x^result to test the initial value every time.
Subtraction switches up things a little. It sets overflow only when the signs of x and y are different, and when x and the result are also different, eg:
bool overflow = (x ^ y) & (x ^ result) & 0x80;
Fun stuff, huh?
So I was wanting this tested thoroughly, just in case there was a typo or something when updating the opfn.cpp files.
---
That said, I also polished up the UI a bit. Moved disabled to the bottom of the speed regulation list, and added key / joypad bindings for "exit emulator", "speed regulation increase / decrease" and "frameskip increase / decrease".
I know these key bindings do not update the menubar radiobox positions yet. I'll get that taken care of shortly.
I got tired of using bit packing for CPU / SMP register flags, because they do not mask the upper bits properly.
In other words, (assume big endian) if you have struct { uint8_t n:1, v:1, m:1, x:1, d:1, i:1, z:1, c:1; } p; and you set p.m = 7; it will set p.v and p.n as well. It doesn't cast the type to bool.
So I rewrote the old template struct trick, but bound it with a reference rather than relying upon union alignment. Looks something like this:
Code: Select all
template<int mask>
struct CPUFlag {
uint8 &data;
inline operator bool() const { return data & mask; }
inline CPUFlag& operator=(bool i) { data = (data & ~mask) | (-i & mask); return *this; }
CPUFlag(uint8 &data_) : data(data_) {}
};
class CPURegFlags {
public:
uint8 data;
CPUFlag<0x80> n;
CPUFlag<0x40> v;
...
CPURegFlags() : data(0), n(data), v(data), m(data), x(data), d(data), i(data), z(data), c(data) {}
};
Anyway, with this, I decided to get rid of the confusing and stupid !!() stuff all throughout the CMP and SMP opfn.cpp files. It's no longer needed since the template assignment takes only a boolean argument. Anything not zero becomes one with that.
So code such as this:
Code: Select all
uint8 sSMP::op_adc(uint8 x, uint8 y) {
int16 r = x + y + regs.p.c;
regs.p.n = !!(r & 0x80);
regs.p.v = !!(~(x ^ y) & (y ^ (uint8)r) & 0x80);
regs.p.h = !!((x ^ y ^ (uint8)r) & 0x10);
regs.p.z = ((uint8)r == 0);
regs.p.c = (r > 0xff);
return r;
}
Code: Select all
uint8 sSMP::op_adc(uint8 x, uint8 y) {
int r = x + y + regs.p.c;
regs.p.n = r & 0x80;
regs.p.v = ~(x ^ y) & (x ^ r) & 0x80;
regs.p.h = (x ^ y ^ r) & 0x10;
regs.p.z = (uint8)r == 0;
regs.p.c = r > 0xff;
return r;
}
Essentially, overflow is set when you add/subtract two positive or two negative numbers, and the result ends up with a different sign. Hence, the sign overflowed, so your negative number is now positive, or vice versa.
A simple way to simulate it is:
int result = (int8_t)x + (int8_t)y;
bool overflow = (result < -128 || result > 127);
But there's no reason to perform signed math, since the result can't be used for anything else, not even any other flags, as the opcode math is always unsigned.
So to implement it with this:
int result = (uint8_t)x + (uint8_t)y;
We just verify that both signs in x and y are the same, and that their sign is different from the result to set overflow, eg:
bool overflow = (x & 0x80) == (y & 0x80) && (x & 0x80) != (result & 0x80);
But that's kind of slow. We can test a single bit for equality and merge the &0x80's by using a XOR table:
0^0=0, 0^1=1, 1^0=1, 1^1=0
The trick here is that if the two bits are equal, we get 0, if they are not equal, we get one.
So if we want to see if x&0x80 == y&0x80, we can do:
!((x ^ y) & 0x80);
... or we can simply invert the XOR result so that 1 = equal, 0 = different, eg ~(x ^ y) & 0x80;
The latter is nice because it keeps the bit positions in-tact. Whereas the former reduces to 1 or 0, the latter remains 0x80 or 0x00. This is good for chaining, as I'll demonstrate below.
Do the same for the second test and we get:
bool overflow = ~(x ^ y) & 0x80 && (x ^ result) & 0x80;
We complement the former because we want to verify they are the same, we don't for the latter because we want to verify that they have changed.
Now we can basically use one more trick to combine the two bit masks here. We want to return 1 when overflow is set, so we can look for a pattern that will only return one when both the first and second tests pass.
An AND table works great here. 0&0=0, 0&1=0, 1&0=0, 1&1=1. Only if both are true do we end up with 1.
So this means we can AND the two results, and then mask the only bit we care about once to get the result, eg:
bool overflow = ~(x ^ y) & (x ^ result) & 0x80;
And there we go, that's where that bizarre math trick comes from. I realized while doing this something that bugged me in the past.
I used to think that for some reason, the S-SMP add overflow test required x^y & y^r, whereas S-CPU add overflow used x^y & x^r. Probably because I read the algorithm from Snes9x's sources or something.
But that was flawed -- since addition is commutative, it doesn't matter whether the latter is x^result or y^result. Only in subtraction does the order matter, where you must always use x^result to test the initial value every time.
Subtraction switches up things a little. It sets overflow only when the signs of x and y are different, and when x and the result are also different, eg:
bool overflow = (x ^ y) & (x ^ result) & 0x80;
Fun stuff, huh?
So I was wanting this tested thoroughly, just in case there was a typo or something when updating the opfn.cpp files.
---
That said, I also polished up the UI a bit. Moved disabled to the bottom of the speed regulation list, and added key / joypad bindings for "exit emulator", "speed regulation increase / decrease" and "frameskip increase / decrease".
I know these key bindings do not update the menubar radiobox positions yet. I'll get that taken care of shortly.
Alright, sorry for being idle the past two weeks. I finally perfected my new Hackintosh, which took a lot longer than expected. To answer previous questions, no, I have no intentions of porting bsnes to Mac myself. Richard's port is fantastic and adheres to Apple's strict usability guidelines. Plus I don't know the first thing about Mac development yet anyway.
Anyway, new beta posted.
I've added the HQ2x 64-bit OS fix, a crash bug when loading a non-existent file (via command-line), and perhaps most interestingly, ALSA output for Linux. It doesn't seem to work too well on Ubuntu 8.04 -- perhaps due to PulseAudio, or maybe due to the driver, not sure. Specifically, there's no speed regulation at all. So even if you use a video driver that syncs to vblank, you'll still get crackly audio.
On a more positive note, OpenAL sounds great on Ubuntu 8.04 ... does anyone disapprove of making OpenAL the default output target for the next official release? It has much lower latency than libao, and it allows you to turn off speed regulation.
Anyway, new beta posted.
I've added the HQ2x 64-bit OS fix, a crash bug when loading a non-existent file (via command-line), and perhaps most interestingly, ALSA output for Linux. It doesn't seem to work too well on Ubuntu 8.04 -- perhaps due to PulseAudio, or maybe due to the driver, not sure. Specifically, there's no speed regulation at all. So even if you use a video driver that syncs to vblank, you'll still get crackly audio.
On a more positive note, OpenAL sounds great on Ubuntu 8.04 ... does anyone disapprove of making OpenAL the default output target for the next official release? It has much lower latency than libao, and it allows you to turn off speed regulation.
-
- -Burninated-
- Posts: 871
- Joined: Mon Sep 10, 2007 11:33 pm
- Location: Unspecified
This whole implementing OpenAL thing...it isn't directly related to the Windows port, right...?byuu wrote:Alright, sorry for being idle the past two weeks. I finally perfected my new Hackintosh, which took a lot longer than expected. To answer previous questions, no, I have no intentions of porting bsnes to Mac myself. Richard's port is fantastic and adheres to Apple's strict usability guidelines. Plus I don't know the first thing about Mac development yet anyway.
Anyway, new beta posted.
I've added the HQ2x 64-bit OS fix, a crash bug when loading a non-existent file (via command-line), and perhaps most interestingly, ALSA output for Linux. It doesn't seem to work too well on Ubuntu 8.04 -- perhaps due to PulseAudio, or maybe due to the driver, not sure. Specifically, there's no speed regulation at all. So even if you use a video driver that syncs to vblank, you'll still get crackly audio.
On a more positive note, OpenAL sounds great on Ubuntu 8.04 ... does anyone disapprove of making OpenAL the default output target for the next official release? It has much lower latency than libao, and it allows you to turn off speed regulation.
俺はテメエの倒す男だ! 宜しく! お前はもう死んでいる...
-
- ZSNES Developer
- Posts: 3904
- Joined: Tue Jul 27, 2004 10:54 pm
- Location: Solar powered park bench
- Contact:
That's weird.byuu wrote: Specifically, there's no speed regulation at all. So even if you use a video driver that syncs to vblank, you'll still get crackly audio.
I'm using Xv+ALSA, and even with no speed regulation, I'm getting 60 FPS.
The OpenAL driver on this machine on the other hand is a bit crackly (not more crackly than ALSA), and turning off speed regulation mutes the sound output.
AO is the most crackly, but strangely enough, not too bad...
And OSS sounds perfect, whether speed regulation is on or off.
I'll install OSS 4 on this machine, and see how that changes the sound output for each driver.
BTW, we'll need to change the makefile a bit. Instead of specifying platform=x, we might want to change that to linux,bsd/solaris,osx...
Only Linux has ALSA/libasound, OSX doesn't have (well not normally) Xv, or other X stuff or OSS. We currently don't seem to have any differences between BSD and Solaris.
May 9 2007 - NSRT 3.4, now with lots of hashing and even more accurate information! Go download it.
_____________
Insane Coding
_____________
Insane Coding
Another WIP. This one changes the GUI toolkit to not invoke callbacks when the API is used to set the state of widgets. With that it was really easy to get the speedreg / frameskip checks to update when using the keyboard controls.
What I really need for this WIP is testing to see if any UI elements are now broken as a result of the change. For example, try and get a checkbox to not represent the actual state of something. Eg a frameskip of 2 but the checkbox is on 0. Also check startup states and that sort of thing.
The UI code really needs to be cleaned up at this point ...
What I really need for this WIP is testing to see if any UI elements are now broken as a result of the change. For example, try and get a checkbox to not represent the actual state of something. Eg a frameskip of 2 but the checkbox is on 0. Also check startup states and that sort of thing.
The UI code really needs to be cleaned up at this point ...
New WIP.
This one adds DPI-independent font sizing for both Windows and Linux. With that, I've reduced the font size back down to "Tahoma 8" on Windows, and "Sans 8" on Linux.
Because of that, I was able to reduce textbox and button height from 30 to 25, and label, checkbox and radiobox height from 20 to 18. In other words, the UI looks like it did back with v019.
There's only one tiny flaw with the Linux port, I'm unable to change the font face for the listbox column header. It's not actually a widget, so it ignores my gtk_container_foreach -> gtk_widget_modify_font() calls. Any help would be greatly appreciated.
I've also added FitzRoy's new icon. It seems to only have 32-bit icons, and no 256-color icons ... I guess we'll see how that looks on Win2k soon enough.
Lastly, statusbar toggle was broken in the last WIP, that's fixed now.
This one adds DPI-independent font sizing for both Windows and Linux. With that, I've reduced the font size back down to "Tahoma 8" on Windows, and "Sans 8" on Linux.
Because of that, I was able to reduce textbox and button height from 30 to 25, and label, checkbox and radiobox height from 20 to 18. In other words, the UI looks like it did back with v019.
There's only one tiny flaw with the Linux port, I'm unable to change the font face for the listbox column header. It's not actually a widget, so it ignores my gtk_container_foreach -> gtk_widget_modify_font() calls. Any help would be greatly appreciated.
I've also added FitzRoy's new icon. It seems to only have 32-bit icons, and no 256-color icons ... I guess we'll see how that looks on Win2k soon enough.
Lastly, statusbar toggle was broken in the last WIP, that's fixed now.
Well, this is what I'm working on now:

Unfortunately, I don't remember how to set codepage 65001 on Windows. Anyone remember the API command for that? Not having much luck with Google at the moment.

Unfortunately, I don't remember how to set codepage 65001 on Windows. Anyone remember the API command for that? Not having much luck with Google at the moment.
Ah, thanks. I resized that panel first, and used the 'y' to make sure the new height was long enough to avoid clipping.Looking great. I found a typo in pathsettings.cpp, it should read Default instead of Defaulty.
Awesome. Language support is a great idea and probably a good way to gain more (non native English speaking) user base.byuu wrote:Well, this is what I'm working on now:
edit: Even if, really, using an emulator in a foreign language isn't particularly hard, you'd be surprised the number of emulators I've seen (unofficially) "translated" from English to French or other languages.
-
- Regular
- Posts: 347
- Joined: Tue Mar 07, 2006 10:32 am
- Location: The Netherlands
-
- -Burninated-
- Posts: 871
- Joined: Mon Sep 10, 2007 11:33 pm
- Location: Unspecified
Translating the UI will probably be easy anyway -- google has it's own translation tool -- use that to get each language.
The screenshot byuu showed was bsnes running on linux.I've always wondered how to get XP to display Japanese unicode (or whatever it is) on programs such as emulators. The method for doing so has long left my memory...
Neat, thanks! Let me get all of the strings into the database lookup table first, and then I'll post it here for some translations :DI can translate it to Dutch if you like - but you didn't need Unicode support for that
How good thought, Franki? As for me Google' It is possible to use; In order the translation equipment where s is automated, to make margin and bsnes concentrate which are rubbed from the actual people! I can' t predicts the problem of this thought at all!Translating the UI will probably be easy anyway -- google has it's own translation tool -- use that to get each language.
byuu wrote:How good thought, Franki? As for me Google' It is possible to use; In order the translation equipment where s is automated, to make margin and bsnes concentrate which are rubbed from the actual people! I can' t predicts the problem of this thought at all!Translating the UI will probably be easy anyway -- google has it's own translation tool -- use that to get each language.







Umm, byuu, could you say that in English?
I just meant that say you wanted to translate a peice of text in the UI (like "file", "misc", "speed regulation", or whatever), just use google's translator.
so if you wanted to translate the ui to spanish, get everything in the ui that's in english, and put it through google's translator to get the spanish word.
http://www.google.co.uk/language_tools?hl=en
I just meant that say you wanted to translate a peice of text in the UI (like "file", "misc", "speed regulation", or whatever), just use google's translator.
so if you wanted to translate the ui to spanish, get everything in the ui that's in english, and put it through google's translator to get the spanish word.
http://www.google.co.uk/language_tools?hl=en
Last edited by ZH/Franky on Wed May 14, 2008 6:57 pm, edited 1 time in total.
-
- Veteran
- Posts: 637
- Joined: Sat Apr 21, 2007 8:05 pm