News: 11 March 2016 - Forum Rules, Mobile Version
Current Moderators - DarkSol, KingMike, MathOnNapkins, Azkadellia

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Messages - Disch

Pages: [1] 2 3 4 5 6 ... 57
Newcomer's Board / Re: fceux help
« on: March 16, 2018, 12:43:41 am »
I'm very late to the game, but I'm going to chime in to somewhat reiterate what Psyklax said.

So the item ID# is found with a9 and not c9.

^  This quote is kind of nonsense.  You seem to fundamentally have the wrong idea about how assembly works, and are looking for specific instructions opcodes in hopes that they'll be some kind of magic bullet that will lead you to the solution you're looking for.

That's not how it works.  Programming concepts cannot be understood by only looking at a single instruction.  It takes several instructions to really do anything.  It's no wonder you're staring at pages of hex and not getting anywhere.

You need to understand the code.  You're not looking for a single opcode, or a single instruction, you're looking for an ENTIRE ROUTINE.  10, 15, maybe 20 instructions... maybe even more.  A big block of code that does a bunch of stuff in sequence to perform an in-game effect.  That's what you need to find.... instead of just hoping the game uses a CMP immediate somewhere, and hoping you can change the immediate value to something else to get the desired effect.

Don't look at hex.  Looking at hex is very rarely useful, and usually only pays off when you already know what kind of pattern you're looking for.  You don't know what you're looking for (or at least, you don't know what it will look like) so looking at a page of hex is going to get you nowhere.

Get a disassembler.  Run DW2 through it.  Look at the code.  Read it.  Understand it.  Get a handle on what the code is actually doing.  Disassemblies are great because you can see the code structure AND you can jot down notes right in there.

FCEUX can help narrow down what part of the code you need to be looking at -- but once you're in the area, you have to read the code.

Gaming Discussion / Re: one handed games?
« on: February 14, 2018, 10:03:30 am »
Crypt of the Necrodancer.  It's a rogue-lite (which I normally hate) combined with a rhythm game, and is designed to be played entirely with just the arrow keys on your keyboard  (or a DDR dance pad)

EDIT:  Whoops.  I missed the "PS or SNES" restriction.  My mistake!

Gaming Discussion / Re: Playing SotN for the first time.
« on: February 08, 2018, 10:53:32 pm »
Lol, haven't figured out Soul Steal yet since I'm doing the first run blind,
how broken would you say it is?

Soul Steal deals a shitton of damage (basically killing) everything on screen and simultaneously filling up all your life.

It's completely broken.

Gaming Discussion / Re: Playing SotN for the first time.
« on: February 06, 2018, 10:08:07 pm »
Dark Metamorphosis

You mean "Dark Metamorphathith"?

Also Soul Steal is better.  In fact it's way too good and is totally game breaking.

Programming / Re: C++: array indexing issues
« on: February 06, 2018, 09:53:50 pm »
I can't have a long int as the index into an array of chars?

Of course you can.  :P

This sounds like stack corruption.  Switch back to using WriteIndex and change that line to this:

Code: [Select]
unsigned long int romoff, testtest[100], WriteIndex, testtesttest[100];

Does it work?  If yes, you have stack corruption.  Most likely you are stepping out of bounds of an array somewhere -- and that array is resting on the stack.

It *might* be DataBuffer ... like maybe you're using a negative index or something by mistake.

This, of course, is not a fix.  It's just diagnostic.  If you want further diagnostics, you can try replacing your arrays with some kind of container class so you have bounds checking. Or add your own bounds checking since you don't appear to be checking at all, which -- unless you know the exact size or a strict upper-bound of the size of the data you're working with, is an extremely bad idea.


Really... since this is C++ and not C, you should be using a container class like vector anyway for DataBuffer.  And instead of having a WriteIndex, you should just push_back the values into your vector.  Then you never have to worry about out of bounds writes -- and your buffer is not unnecessarily large.

And, if you compile with debug settings, you also get bound checking on read-accesses as well.

Maybe something like this:
 Assign each character a number: random(0...24) + [AGI/4]
 Then set the turn order based on the assigned numbers.
 In case of a tie, the character with the higher AGI score goes first.

Do a gauge.  Keep increasing by something like AGI+rand(0,Luck/2) or something like that, and once it reaches X they get a turn.  That'll nerf the extremely overpowered Fighter a bit because he won't get as many turns, and it'll give the player an actual reason to use a Thief --- maybe they don't hit as hard, but they get to hit way more often.

Enemies already have an agility stat, too, but it'll probably have to take some adjustment so that they match level-appropriate characters.  Actually, this whole plan would require some rebalancing, so maybe it's beyond the scope of what you want to do, but it would be my approach to this.

Programming / Re: Bsnes problem
« on: January 12, 2018, 01:37:25 am »
I just edited my post before you replied -- I would like to draw your attention to that edit

Programming / Re: Bsnes problem
« on: January 12, 2018, 01:34:02 am »
This is a symptom of a larger problem...  there is exactly a 0% chance that this is an issue with the way the emus are running your code.  All emus are going to have the core 65816 emulation pretty much nailed -- if they didn't, games just flat out wouldn't run.

The only way something like this is going to differ between emus is if you are doing screen rendering when it's not safe to do so, and the effect you're seeing is due to slight timing differences between emus.

The question to ask here is when are you actually transferring the data to VRAM?  And are you sure the system is still in VBlank when you're doing so?


From the code it looks like you are putting the VWF stuff inside the actual screen rendering, which is a terrible idea because VWF processing is going to take a lot of time.  You're probably running out of VBlank time.

Typically what you'd want to do is do this processing and put the stuff you're going to draw to RAM somewhere -- then when VBlank comes around just do a single quick DMA to get it all in VRAM at once.

Programming / Re: [65816]Store indirect problem
« on: January 10, 2018, 10:53:39 pm »
I find that STA ($54,x) works exactly the same as STA $54,x

Not at all.

Assume you have the below memory:
Code: [Select]
X   =02
Y   =02
DP  =0000

Code: [Select]
STA $54,X    ; writes to $0056
STA ($54),Y  ; writes to $BBAC
STA ($54,X)  ; writes to $DDCC

Programming / Re: [65816]Store indirect problem
« on: January 10, 2018, 10:43:16 pm »
Indirect,X is not what you want -- and I'd argue is only useful is VERY LIMITED circumstances.  It does the +X BEFORE the pointer is dereferenced, not after.

When X=2, The pointer being read is from $56.  It's not reading the pointer from $54 at all.

What you are looking for is Indirect,Y mode... which is the same, but the indirection happens first, and the indexing afterward:

Code: [Select]
STA ($54),Y

Things to note:
- The comma denotes indexing (addition)
- The parenthesis denote dereferencing (pointer lookup)
- Indirect, X has the comma inside the parenthesis "($54,X)" because the addition is first
- Indirect, Y has the comma outside the parenthesis "($54),Y" because the indirection is first

And since Disch mentioned a recent game that he liked, you guys really have to play Fez if you haven't already, it's a fantastic trip.

I second the Fez recommendation.

The platforming gets a little tedious with all the backtracking, but the atmosphere is great and the puzzles have a great balance of being both "wtf is this supposed to mean" cryptic while still being actually solvable (well -- most of the time -- a few of the puzzles are pretty far out there).

You feel like you EARN those cubes.

Star Wars Battlefront 2: I bought the game, but I need to pay money again (either a few dollars to even $100) to acquire items/characters that will allow me to actually play the game. And grinding for over 9000 hours to get past the pay wall isn't gameplay; it's a chore.

So... here's the thing with SWBF2.  Everyone knows it's a pile of shit.  Everyone should have known after SWBF1.  Or really after any Battlefront game.  Ordinarily this game would just flop and everyone would forget about it in a few months... kind of like No Man's Sky.

But here's the thing...

... I'm going to let you in on a secret...

... are you ready?

Star Wars fanboys are fucking stupid.  They're like the stupidest of the stupid consumers.  They'll buy anything with the Star Wars logo on it... it doesn't matter how shitty everyone knows it is.  It doesn't matter how overpriced it is -- how lacking in base content it is -- or how poorly reviewed it is.  They'll still shell out for it.

EA knows this.  And they exploited it. The game is overpriced because they know SW fanboys will buy it anyway.  They have in-game microtransactions because they know SW fanboys will pay for them.

... and they kind of are.  Considering how badly the game has been drowning in drama, bad press, and bad PR... it still sold a looooot of copies.

Sorry, but I can't blame EA for seizing the opportunity to capitalize on fanboy stupidity.  All they did was make a shitty overpriced game (which, btw, have existed forever).  Everybody knew exactly what it was going to be months before it came out.  All they had to do was show some restraint and not buy it.  But "ZOMG STAR WARS" so they bought it anyway and got all butt-hurt.

This game is not an example of how games have gotten worse.  It's an example of how game consumers have gotten stupider.  But when games are as cheap as they are now, I guess more carelessness is to be expected.

Need I remind you that, adjusted for inflation, a copy of Street Fighter 2 on the SNES would set you back over $100?!

This.  This is really key to remember.

It was not uncommon for NES games to be priced at $50 or even $60+ at the time of their release.  In 1987.  30 years later, and modern games cost about the same -- often much less ... despite inflation.  Games are cheaper and more easily available now than they've ever been -- and part of that is because of digital distribution.

Take a game like Ori & the Blind Forest, for instance.  I'm using it as an example even though it's 2 years old now because I just recently tried in and completely fell in love.  The game is a friggin masterpiece, and IMO stands alongside the Metroidvania greats of the past... and it's $20.  A third of the price of Super Metroid or SotN -- and every bit as worthy of being played.

This kind of release just didn't happen in the pre-digital era.

EDIT:  sorry but I can't help gushing over this game.  I mean LOOK AT IT

But will you be able to play those games you bought in say another 10 years when the services that sold you the game go down? If you don't care about that, then not a problem.

1)  It depends on the game and where you bought it from.  As mentioned, GOG does not have this problem.
2)  It's a pretty safe bet to say that Steam will still be around in 10 years.  At least, I would be willing to bet.
3)  On a 10+ year timeline, I think Windows compatibility problems would be a much bigger issue anyway.  Who knows if a game designed for 2005 PCs will run on 2025 PCs?

I'm glad I decided to stop playing new games after rediscovering the PS1.

You just haven't been playing the right new games.  Either that or you're blinding yourself with stubbornness.

Good games are still being made.  But it's like games of any other area -- the vast majority of what gets released is trash.  The main difference is that for some unknown reason more people are willing to buy the trash now than they were before.

I have no problem with this.  I haven't bought a physical copy of a game in... 4 years?  5?  It seems like an antiquated concept to me.

UxROM are Nintendo boards and definitely have no SRAM. iNES mapper #2 is however a super-set of UxROM which is implementation-agnostic, and allows swapping far more banks (8 bits instead of 3 or 4), and allows for SRAM.

FCEUX at the very least seems to be putting open bus at $6000-7FFF for mapper 2.  Though maybe it wouldn't if the battery bit in the header was set?

Either way -- you're playing with fire at this point and are making your hack have questionable emu compatibility.

But yeah, so this one is going to actually take me a while. As I'll need to first convert the game into a different mapper(which would take a while if at all, not sure if I am capable of this), then adding the SRAM saving function...which would be the easy part as I've done enough of that already.

You're building a mental wall.  Doing a mapper hack isn't as hard as you think.  In fact, I'd argue that doing an SRAM hack is harder, as it actually takes understanding of what information the game is handling.

The only thing you really need to do for a mapper hack is find all the code that swaps banks and change it to a 'JSR' that does the MMC1 version of a swap.  It's little more than find/replace.  Time consuming, but very easy.

Don't let it scare you.  You definitely should be able to do it.

I'm 2 years late to the party, but I recently just discovered Ori and the Blind Forest.  I'm completely blown away -- it quickly became one of my favorite games.  Stunningly beautiful, amazingly thematic soundtrack, adorable character, and really fun platforming.

I threw this together to help explain bankswapping:

To do a mapper hack you need to know 3 things:

1)  6502 assembly  (which I assume you are reasonably proficient in if you are adding SRAM to a game)
2)  How the original mapper works (In this case, UxROM)
3)  How the new mapper works (In this case, MMC1, I assume, unless you decide on something different).

Most mappers do more or less the same thing.  So doing a mapper hack involves figuring out what the game is doing in one mapper, and doing the equivalent thing in another mapper.

In this case, UxROM only has 1 thing to do:  Swap PRG.  It does that with code similar to the following:

Code: [Select]
; Swap to bank 'some_bank_number'
LDA #some_bank_number
STA $C000,X    ; address may vary -- must be between $8000-FFFF

The equivalent code on MMC1 (to swap PRG) would be the below:
Code: [Select]
LDA #some_bank_number
STA $F000   ; address may vary -- must be between $E000-FFFF
STA $F000
STA $F000
STA $F000
STA $F000

Both of these bits of code might seem strange at first, but what they're doing is very simple.

To Swap PRG on UxROM, you just have to write the desired page number to any address in the $8000-FFFF range.  The thing that makes it complicated is that most boards have bus conflicts, so the value you write must match EXACTLY to the value that is read from that address.  IE, if you want to swap to page $05... you'd need to write $05 to an address in the $8000-FFFF range that already contains a $05.

Games often do this with a lookup table that just looks like this:
Code: [Select]
At address C000:
  00 01 02 03 04 05 06 07

The game then uses the page number as the index to the lookup table to write:

Code: [Select]
LDA #5        ; want to swap to bank 5
TAX           ; A and X are now both 5
STA $C000, X  ; Since X=5, we will write to $C005, and we know $C005 contains 5 because
              ;   that's the point of the lookup table.

Note that this is just an example, and not a definitive rule.  A game might do something like this:
Code: [Select]
LDA #$02
STA $8016
... if it just happens to know that $8016 contains a 2.  There isn'te specific routine to do this -- a game can do it any number of ways. It's up to you to look at the code and figure out what it's doing.

But you can know for sure that every single write the original game does to the $8000-FFFF range is the game attempting to swap PRG to a specific page.


MMC1 is weirder.  To Swap PRG here, you just have to write the desired page number to any address in the $E000-FFFF range.  The plus side is there's no bus conflicts, so you don't have to worry about writing to an address that contains a certain value.  The down side is MMC1 registers can only be written 1 bit at a time.

MMC1 regs are also 5 bits wide, which means each register write actually takes 5 writes (one for each bit)

Hence the LSR's between each STA.  The low bit is written first, then you shift right to move the next bit into position 0, so it will be written on the next STA.

MMC1 also has additional functionality besides just PRG swapping.  You don't have to use it, since the game you're hacking doesn't need it... however you still have to initialize everything.  Common best practice is to write to all registers once at powerup to put everything in a known state.  So take a look at MMC1's register list:

There are 4 registers:

1)  Control ($8000-9FFF).  This sets the mirroring mode, as well as the swap modes.  To match UxROM, you want 8K CHR and 16K PRG swappable at $8000... and either horizontal or vertical mirroring depending on what the game is (I'm too lazy to check).  So you'll want to write either $0E (vertical) or $0F (horizontal).  But again, gotta write 1 bit at a time, so when I say "write" I mean "perform 5 STA's"

2)  CHR bank 0 ($A000-BFFF).  Since you'll be using CHR-RAM, the CHR swapped in doesn't really matter.  You can probably get away with not writing to this reg at all, but if you want to be strict you can write $00.

3)  CHR bank 1 ($C000-DFFF).  Ditto.  Although since you'll be using 8K CHR swapping this reg will actually be ignored, so you REALLY don't need to write to it at all.

4)  PRG bank ($E000-FFFF).  This is what controls the PRG swapping.  Basically just write to this reg whatever the original game does when it bankswaps.

Pages: [1] 2 3 4 5 6 ... 57