Views: 853,103,753
12 users online: Hitsu2k, Isikoro,  JamesD28, Kignak, Koop the Koopa, Miscalc, MrDeePay, Para_0,  patcdr, Romano338, Schneider912, snailsenpai - Guests: 44 - Bots: 63 Users: 47,051 (2,518 active)
Latest: Natedogg62
Tip: Try not to use the exact same background more than once or twice in a row.Not logged in.
Posts by undefinied3
undefinied3's Profile - Posts by undefinied3
Pages: « 1 243 44 45 46 »
I quote leod. That's why you have graphics and tilemap, because you can't draw directly on screen and just having the graphics isn't enough, you have to put them in some way on the screen.

I had this curiosity about playing around with pixels and stuff so I tried to recode the vwf effect myself. It ended up being a pain because it's purely manipulating bits in a way you can get something decent. 2bpp for instance is stored 2 bytes. Each bit represents one pixel, and for each pixel you have 2 bits to have up to 4 colors (00, 01, 10, 11). One byte represents one 8x1 line, but these two bytes aren't stored one after another, the first byte for a line is stored at 0x00 and the next one at 0x10, the next line reads 0x01 and 0x11 and so on.

For instance, here's how I coded the vwf effect (just a part of it, of course):
LDA LetterGFX,x				;first 8x8
STA $09	
LDA LetterGFX+$10,x			;second 8x8 (letters 16x8)
LDA LetterGFX+$01,x
STA $0B						;Second byte
LDA LetterGFX+$11,x
STA $0C						;of information (2bpp)

LDA LetterGFX+$0100,x				;first 8x8
STA $3100	
LDA LetterGFX+$0110,x			;second 8x8 (letters 16x8)
STA $3101
LDA LetterGFX+$0101,x
STA $3102						;Second byte
LDA LetterGFX+$0111,x
STA $3103						;of information (2bpp)

REP #$20
LDA !ShiftValue
AND #$00FF
BEQ .noInitialShifting
LDA $03
AND #$00FF
LDA $09 : XBA : LSR A : XBA : STA $09
LDA $0B : XBA : LSR A : XBA : STA $0B
LDA $3100 : XBA : LSR A : XBA : STA $3100
LDA $3102 : XBA : LSR A : XBA : STA $3102
BRA ++
LDA $09 : XBA : ASL A : XBA : STA $09
LDA $0B : XBA : ASL A : XBA : STA $0B
LDA $3100 : XBA : ASL A : XBA : STA $3100
LDA $3102 : XBA : ASL A : XBA : STA $3102
CPY #$0000

LDA $310E
CLC :  ADC $00
SEP #$20
LDA !GFXBuffer,x : ORA $09 : STA !GFXBuffer,x
LDA !GFXBuffer+$01,x : ORA $0B : STA !GFXBuffer+$01,x
LDA !GFXBuffer+$10,x : ORA $0A : STA !GFXBuffer+$10,x
LDA !GFXBuffer+$11,x : ORA $0C : STA !GFXBuffer+$11,x
LDA !GFXBuffer+$100,x : ORA $3100 : STA !GFXBuffer+$100,x
LDA !GFXBuffer+$101,x : ORA $3102 : STA !GFXBuffer+$101,x
LDA !GFXBuffer+$110,x : ORA $3101 : STA !GFXBuffer+$110,x
LDA !GFXBuffer+$111,x : ORA $3103 : STA !GFXBuffer+$111,x

LeterGFX is just a pointer for the .bin with each letter's graphics in 2bpp. You see how I loaded $00, $10, $01 and $11? That's basically the 8x1 line I said, as you might guess, I had to loop through that 8 times to build a whole 8x8 tile. You can also see $0100, $0110, $0101 and $0111, but that's just because I was working with a 8x16 font, so I had to build 2 8x8 tiles.
After storing this data in a buffer, I had to work with the real stuff that would be uploaded to vram, that's !GFXBuffer. That was done by checking this RAM !ShiftValue that I would use to keep track of where I would have to start drawing the next letter inside a 8x8 tile (for example, iirc an "i" occupied 3 pixels, already counting the extra space you need between letters, so after drawing an "i", I would add 3 to that RAM and check whenever it would be #$08 to readjust everything and go to another 8x8 tile without cutting information, that's why it can be a pain in the butt to work only with bits. You don't have any specific opcodes other than ASL LSR AND ORA and so on). As you can see, I loaded this !ShiftValue RAM and did a bunch of ASL/LSR/XBA with the letter GFX so I could set the bits to the right place (in YYCHR, that would be moving everything one pixel to the right or to the left) and then I would take the vram buffer and do an ORA, because we don't want to substitute what we had, but we want to add that extra letter.

I also had that addPattern code, that would let me add a 8x8 filler to the back of the 8x8 (of course, only where there's are letter pixels)
macro patternCode(value)
LDA LetterGFX+<value>,y
ORA LetterGFX+<value>+$1,y
LDA !GFXBuffer+<value>,x
ORA !GFXBuffer+<value>+$1,x
LDA LetterGFX+<value>,y
ORA !GFXBuffer+<value>,x
STA !GFXBuffer+<value>,x
LDA LetterGFX+<value>+$1,y
ORA !GFXBuffer+<value>+$1,x
STA !GFXBuffer+<value>+$1,x

Basically the same idea, load the part of .bin that has the 8x8 background pattern and merge it with the buffer. This is a bit trickier than just building up the text because I had to make sure I wasn't overwriting anything, so I had to load the $00 byte, merge it with $01 byte (because one bit is enough to say that there's already some pixel there), do the same with the vram buffer, subtract of one of another to remove everything that would be overwritten and finally merge with the vram buffer.

I know it's kinda hard to get the idea just from these random pieces of code, but the point is that you have to figure out which bitshifting operations will get the result you want. AND works as a mask filter, ORA is to merge stuff, LSR and ASL is to shift everything to the left or to the right.

One last example would be the pixel effect I posted in the ASM show-off thread. Unfortunately, 4bpp is a bit different but I don't quite remember how it works, I think it's $00-$01 + $10-$11 for one 8x1 line (0000, 0001, .... 1111). The following code is working in 16-bits:

LDA !GFXBuffer,x							;Load byte (4 bytes per line)
AND InvPixelMask,y							;Keep all pixels which shouldn't be affected now
STA $00										;Save that value for now
LDA !GFXBuffer2,x							;Load source and get
AND PixelMask,y								;ONLY the necessary pixels
ORA $00										;Add result on top of initial gfx
STA !GFXBuffer,x							;Save to result buffer

LDA !GFXBuffer+$10,x						;Same deal. This finishes one line
AND InvPixelMask,y							
STA $00																
LDA !GFXBuffer2+$10,x							
AND PixelMask,y								
ORA $00										
STA !GFXBuffer+$10,x

Again, it's just a bunch of math that does what I need. I load the vram buffer (it has the current pixelated image) and filter only the pixels I want to change that frame (that y index is basically a frame index), then I do the same with the buffer which has the whole correct final result and merge with the vram buffer. That way, every frame I change just some pixels of the current on-screen image, while I always hold the final result in a buffer.

Of course, after all that stuff, you have to upload to VRAM and then build the tilemap. I'd say that what's most important is that you know how the x-bpp you want to work with works. If you don't know what each bit represents and how the bytes are organized, you'll end up uploading garbage to VRAM.
It's just a term I used to describe how AND can be used to select only specific pixels. As I said, each byte holds part of the information of a 8x1 line, and each bit is a pixel. If you load the whole byte, it's unlikely you'll want to work with it as a whole all the time. If you want to work only with the first pixel (so everthing else needs to be ignored) you do LDA $xx AND #$80, because the leftmost pixel is the leftmost bit of 00000000. Thats how I chose which pixels I wanted to upload each frame.
Yes, that's how it works. These aren't consecutive bytes, but that's how it works. 2bpp = 2 bits per pixel, and with 2 bits you have 2^2=4 possibilities, therefore 4 colors.
Yes. I have a levelasm library with a bunch of those effects, but they're all coded for SA-1.

Here it is if you want to give it a try

It's not the simplest thing to use though.
Yep, that's totally free to use/tweak. I coded it to use with an RPG battle system I was creating but I don't have enough time to continue that.
It would be really nice if you can convert them to non-SA-1. It shouldn't be too hard I think, the only issue is the signed/unsigned division of SNES, there are some effects which I had to code in a specific way to use the signed SA-1 maths, so you might get confused while trying to understand what each piece of code does. I might be able to help you if you have any questions during the conversion.
Oh and yes haha, sen would be sin. It's written "sen" because in my language sine is "seno", so we abbreviate as sen.
The windowing X/Y scaling is to scale any window by a specific factor in X and Y axis. If you have a.. idk, any shape that you have the static windowing table for it, a star shape figure for example (although you would need both windows for that, but you can still use the code with some RAM tweaks), and you want to make it bigger/smaller, or just stretch in some direction, you can use that code.

You can check all the effects on my channel, except the cylinder:

There're 2 ultima-effect videos, the most recent one uses the specific ultima code you can see in the ASM file, and the later uses the Windowing X/Y, because I hadn't figured the ellipse algorithm that time. Also, the ellipse video is outdated. The lag you'll see doesn't exist anymore because I found a way to use only 16-bit division; the video is an old code which used 32-bit division.

One last thing I forgot to mention, I don't know how just snes would be able to handle without major lag some of those effects, since let's say I'm not the best person when it comes to efficient coding, let alone finding better algorithms to fit ASM's limitations, so some of them I just recreated exactly what computers would use to rasterize some stuff since SA-1 can handle that stuff pretty ok.
Pages: « 1 243 44 45 46 »
undefinied3's Profile - Posts by undefinied3

The purpose of this site is not to distribute copyrighted material, but to honor one of our favourite games.

Copyright © 2005 - 2020 - SMW Central
Legal Information - Privacy Policy - Link To Us


Follow Us On

  • YouTube
  • Twitch
  • Twitter


  • Super Mario Bros. X Community
  • Mario Fan Games Galaxy