Register | Login | |||||
Main
| Memberlist
| Active users
| Calendar
| Chat
| Online users Ranks | FAQ | ACS | Stats | Color Chart | Search | Photo album |
| |
0 users currently in SMW Hacking. |
User | Post |
mikeyk Posts: 19/89 |
i'm not sure how the block loading routine works. is the whole level loaded once at the begining or does the game just load the parts that are about to come onscreen? either way
dealing with blocks that spawn sprites seems to complicate things greatly. once the sprite was spawned, what would become of the block? i would think that it would need to stay in place. if the sprite wasn't killed and we went back to the original screen, we'd expect it to be respawned. but after the sprite has been killed, then it shouldn't be. there seems to be unnecessary bookkeeping. there's also a couple more issues that i can think of, but it's quite possible i'm thinking about this whole thing wrong on the other hand, i am familiar with how sprites are initialized and loaded into ram when they're about to come onscreen. i know for a fact that it would be very easy to write the snes code to split on the extra bit. that part would be short and sweet. so very easily 00 could indicate a green koopa if the extra bit was clear, and a custom sprite if it were set. i could create the system in my previous post easily in a day. the only semi-difficult or time-consuming thing would be making a program to automatically insert the code. the whole process of finding free space, inserting the .bin, modifying the reloc offsets, erasing the stuff that was inserted in the previous use of the program, etc. i'm without a computer for the next 2-3 days, so i'll catch you guys later. maybe i can get something started when i come back. |
HyperHacker Posts: 2274/5072 |
It sounds like it might be easier to just change the ASM pointer of some unused sprite, say #12 as you mentioned, to grab the real code location from some other table. Just as object #0 can actually be one of several objects from a second list; you'd be doing the same with sprites. You could perhaps use the sprite # itself (0 for the first instance of #12, 1 for the second, etc) as the table index, or the sprite position (leaving the sprite's code to set up the actual position in-game).
I still think Smallhacker's idea is best, though. Put a specific block and use the size or one of the block # bytes as the sprite #, and hack it to spawn a sprite at that position instead of drawing a block. |
mikeyk Posts: 16/89 |
i'm not promising that i'll make a program, but i am seriously considering it. here's what i had in mind.
my plan is to add support for ~255 custom sprites by using the second extra bit. i know i could use the first extra bit as well and support ~765 sprites, but i wanted to leave this one free to use in sprite code. i think 255 custom sprites should be plenty. i would hijack the code that calls sprite routines. my code would first check if the second extra bit was set. if not, i would return and let the game deal with that sprite like normal. (i would also return if the sprite uses the second extra bit itself). at this point i would know that we're dealing with a custom sprite and i would convert it. the game does many checks with the sprite number, so i would try and avoid this. i would store the sprite number to a ram location (for fun, lets just say $9962,x) and set the original sprite number ($9E,x) to 12 indicating a custom sprite. from then on the custom code could use $9962,x to index a big table. the table would be of fixed length and have 9 bytes per sprite. 6 bytes for sprite properties (basically: tweaker code - asm information) and 3 for the code location. I would set the sprite properties, jump to the code, and be done with the custom routine. there is a little problem using extra bits. they are actually stored in bits 2 and 3 (if the least significant bit is numbered 0) of 14D4,x by the level loading routine (see SNES $02A965). it’s only the sprite code for the goal tape that puts the bits in 187B,x and ANDs them out of 14D4,x. $14D4,x is usually only used for the high byte of the sprite position, and this leads to some interesting consequences. The first is that goal tapes don't work very well on vertical levels. place a regular one on screen 05 and you'll notice it won't show up. this is because 14D4,x = 05 is interpreted as a secret exit (bit 2) on screen 01 (bit 0). using $14D4,x to hold the extra bits also explains all other sprites don't appear if they use them. the extra bits just mess up the high byte of their y position, and they are placed way off sceen. when i planned to use an extra bit i was going to handle them as the goal tape did, but this would make them breakdown on vertical levels. perhaps i could fix this with a hack to the level loading routine. so that's my plan. i'd appreciate some feedback. |
Alastor Posts: 5692/8204 |
gih... guh...
Okay, that's on the list. |
Mozeki Posts: 96/160 |
Originally posted by Smallhacker This seems like this could work if some planning was put out for it. BTW if this was to be done I really hope it doesn't use Decimals like blocktool |
HyperHacker Posts: 2223/5072 |
Heh, I thought of what Sukasa mentioned, but it being 5 AM or so, I thought it wouldn't work. Really, it does sound like a good idea. |
Smallhacker Posts: 575/832 |
Originally posted by SnifflySquirrel Well. My idea would only use one Map16 block per sprite. Instead, it would use a table that contains Map16 numbers and the custom sprite ID to turn the block into. Using entire pages was somebody else's idea. |
SnifflySquirrel Posts: 54/80 |
Sukasa makes a very valid point. It's up to an individual object's rendering code to write any block data that defines it. If that code decides to interpret the object data differently, without writing to the level layout, then it won't matter what it overlaps, because it will still be there. A few things in SMW already work this way, like screen exits (which are Extended Object 0) and some of LM's enhancements.
That being said, I would opt for the "unused sprite index + extra data + level-specific sprite table" method, myself. It sounds like it would be far less difficult to implement. Furthermore, it wouldn't involve sacrificing Map16 pages. |
Sukasa Posts: 889/2068 |
AND, if the routine doesn't place anything for the sprite blocks, you could have those on top of everything else, without having any problems. Shows up on top of everything else in LM, doesn't show up in SMW. |
Smallhacker Posts: 574/832 |
Originally posted by Glyph Phoenix Actually, the 21 bits haven't got anything to do with the idea. I just wanted to prove you wrong by showing that blocks are more dynamic than sprites. |
Glyphodon Posts: 274/536 |
I didn't realize you were applying the 21 bits to your block-sprite idea. Having a sprite use LM's block data would indeed give you extra bits to work with, but blocks themselves are quite static--that's all I meant.
I still wouldn't go for the idea unless there were no more viable solutions, though. Hacking level loading routines, like I said, can't be much fun. |
Smallhacker Posts: 573/832 |
Originally posted by Glyph Phoenix Appearently, you misunderstood my idea. The hacked level loading routine would translate the sprite blocks into real sprites before the level fades in and any other sprites have had a chance to execute anything. They're not blocks. They're sprites stored as blocks. As for the "what to turn the 'sprite blocks' into" question: Let's set it to 25. The level data is stored in Z order (from back to front). If we place a "sprite block" in the level and put a normal block on top of it, the "sprite block" would be loaded first of the two, right? Therefore, the loading code would load the "sprite block", translate it into a sprite and turn the block into thin air. Then, it would load the block placed on top of it, overwriting the thin air. The only problem I see with this method is that the "sprite block" can't be seen in LM unless you move the block on top of it. |
Glyphodon Posts: 271/536 |
Originally posted by Bio.exe Good job, Bio. Those should come in handy. Isn't the location of the sprite in the tables stored in the X or Y register or something? If so, all we'd need is an LDA absolute indexed with X/Y and we'd be good to go. Originally posted by Smallhacker Again, totally missing the point. Blocks can't act differently until they're touched. Sprites, which can read just about any byte in RAM or ROM to change their appearence, behavior, etc. straight from the start, trump your 21 bits. Originally posted by Smallhacker Let this be a lesson to you all. Nobody beats Glyph Phoenix in a battle of theoretical game mechanics. Viva la Extra Info! ...and they don't need to be unused. Extra Info + used sprites can work too. |
HyperHacker Posts: 2214/5072 |
There's plenty of space. The problem is with modifying the code so that it allows more sprites than there already are, without breaking LM compatibility.
Now if we had LM's source we could just modify the routine it uses for ExGFX, timer/music override, etc, since they already work by adding things into the level data. Another project made unneccessarily difficult due to having to keep compatibility with closed-source software. I like the Map16 idea though. AFAIK, the Direct Map16 Access feature can insert blocks up to #FFFF (though I don't think LM would let you do this ), and only up to #FFF are valid. If LM doesn't complain about it, you could break this down into bits like so: fsss ssss bbbb bbbb f=custom sprite flag, s=sprite #, b=block #. If the custom sprite flag is set, the next 7 bits specify the custom sprite # (0-127), and the remaining 8 specify the block #. This way you could create one of 128 custom sprites overtop of one of 256 blocks. A table elsewhere in the ROM could specify which Map16 page these blocks come from in each level, and if necessary, divide the custom sprites into groups of 128 and use a similar table to specify which group to use in each level. I realize I should probably do some things like see if LM does care about invalid block numbers, and if the block numbers are in fact 16-bit, but I really, really need to go to sleep right now. |
Billiards Koopa Posts: 74/174 |
I have no clue about ASM, but couldn't you use that program that expands ROMs to create extra space. |
Alastor Posts: 5661/8204 |
Originally posted by SkreenameRead the ****ing thread. |
Skreename Posts: 967/1427 |
Wouldn't there be a problem with trying to overlap the new block-sprites with normal blocks? Not much of an issue for solid blocks, I know, but I'm sure there are cases in which it could be significant.
(I haven't done too much with it so I don't know all the nuances, so I may not be completely accurate with it...) Otherwise, it sounds decently good. Glyph Phoenix's idea sounds a bit better, but.. that's okay. |
Sukasa Posts: 885/2068 |
I like that Idea. No holes, no sprite overlapping, etc. GP: You can so- makew the block a copy of a normal one, then have to routine read it as a sprite generation block.
Also, this routine only needs to run once. Then, if you use code $FE (I think $FF means, "No Sprite") for a custom sprite, just have the normal sprite routine ignore that sprite number, and have only your custom routine run it or whatever. Also, you'd only need one RAM table for the extra sprites - use a ROM table for their addresses. |
C:/xkas bio.asm Posts: 1045/1209 |
, I've finally found where the extra bit is stored in RAM, they are stored at 7E187B(Sprite Stomp Immunity Flag Table) as bit 3 and 4 |
Smallhacker Posts: 570/832 |
Originally posted by Glyph Phoenix It was supposed to be a "solution" that wouldn't work. Originally posted by Glyph Phoenix Well... From a level designer's point of view, is there really any difference between a sprite and a block? Both can be placed anywhere in the level, both must be placed in a 16x16 grid (as in, you can't place a sprite nor a block 1 pixel away from another one). In fact, when working with Lunar Magic, the only difference is that sprites can't be resized. (Okay. Some blocks can't be resized, but that's not the point.) The sprite properties that Lunar Magic can change are Command (0-FF), Screen Number (0-1F), X/Y Position (0-FF) and Extra Info (0-3). The MAP16 block properties that LM can change are Block (0-FFF), Screen Number (0-1F), X/Y Position (0-FF) and Size (0-FF). If you ignore the Command and Block parts, sprites have got 15 bits of data while MAP16 blocks have got 21 bits of data, which, technically, means that MAP16 blocks are MORE dynamic than sprites. Anyway. Enough about that idea, since I belive that the other idea, the one that uses extra bits and unused sprites, would be better. |
This is a long thread. Click here to view it. |