I was talking to Deep earlier about masked sprites. I learned that to create a masked sprite, you need to:

(1) create a white-background-ed sprite
(2) create a black background
(3) xor the sprite with the background to create the mask
(4) AND the mask to the screen
(5) OR or XOR the sprite to the screen.

So now, if I wanted to do 4-layer greyscale, would I essentially need to have 4 images layers, two for each buffer, and do this process once on each?
Do you mean 4-level grayscale? If so, you just need 3 layers of sprite data (eg. an 8x8 sprite would be 3*8=24 bytes of data)

The first 2 layers are just normal grayscale data, and the 3rd layer is the mask.

In this example, the red is transparency.


Code:
; dark level
.db %00000000
.db %01111110
.db %01000010
.db %01000010
.db %01000010
.db %01000010
.db %01111110
.db %00000000
; light level
.db %00000000
.db %01100110
.db %01111110
.db %00100100
.db %00100100
.db %01111110
.db %01100110
.db %00000000
; mask
.db %00000000
.db %01111110
.db %01111110
.db %01111110
.db %01111110
.db %01111110
.db %01111110
.db %00000000
And if I understand correctly, I AND the mask to both buffers, then write the sprite itself to each buffer?
ACagliano wrote:
And if I understand correctly, I AND the mask to both buffers, then write the sprite itself to each buffer?
I haven't written my own masked sprite routine for ages, but if I remember correctly you would CPL and then AND the mask byte with each buffer, and OR the "dark level" byte to the dark buffer and the "light level" byte to the light buffer Smile
What's CPL? Sorry, I'm awful with graphics stuff.

Secondly, I used Badja's sprite scaling routine (which I posted in below for reference), and the ability to scale sprites is important. First off, the scaled sprite routine uses XOR or OR logic, not AND, so it would need to be changed to do the mask. Secondly, is there a way to do both buffers at the same time, and only call the routine, say, twice?


Code:
; -------------------- putScaledSprite --------------------
; Draws a scaled sprite to the graph buffer.
;
; Version: 1.1
; Author: Badja <http://move.to/badja> <badja@alphalink.com.au>
; Date: 21 December 1999
;
; Modified by Eric Piel : LD and smaller and quicker < Eric.Piel@etu.utc.fr >
; Date: 19 May 2000
; Size: 156 bytes (161 bytes if XORing the sprite, 151 bytes if just Loading it)
;
; Input:
;   HL -> sprite
;    D = x-coordinate
;    E = y-coordinate
;    B = height of unscaled sprite
;    C = width of unscaled sprite (in bytes, so divide by 8)
;    A = scale factor ($01 to $00 <=> 0.4% to 100%)
;        eg: $80 is 50%
;
; Output:
;   The sprite is ORed to the graph buffer. To XOR the sprite
;   instead, add the following line near the top of your program:
;   #define _SS_XOR
;   To just load it insert:
;   #define _SS_LD
;
; Destroys:
;   AF, BC, DE, HL


putScaledSprite:
   ld   (_SS_SetScale1),a
   ld   (_SS_SetScale2),a
   ld   a,d

   push   hl
   ld   d,0
   ld   h,d
   ld   l,e
   add   hl,de
   add   hl,de
   add   hl,hl
   add   hl,hl
   ld   de,(iy)      ;preset buffer
   add   hl,de
   ld   d,0
   ld   e,a
   srl   e
   srl   e
   srl   e
   add   hl,de
   and   %00000111
   ld   (_SS_SetPreShift),a
   neg
   add   a,8

   ld   (_SS_SetBitsLeft),a
   ex   de,hl

   ld   a,c
   ld   (_SS_SetByteWidth),a
   sla   a
   sla   a
   sla   a
   ld   (_SS_SetPixelWidth),a

   pop   hl
   ld   c,0
   push   bc
   jr   _SS_DoRow

_SS_SpriteLoop:
_SS_SetScale1 = $ + 1
   ld   a,0      ; scale factor (self-modified)
   add   a,c
   ld   c,a
   push   bc
   jr   z,_SS_DoRow
   jr   c,_SS_DoRow
_SS_SetByteWidth = $ + 1
   ld   bc,$0000   ; C = byte width of sprite data (self-modified)
   add   hl,bc
   jr   _SS_SkipRow
_SS_DoRow:
   push   de

_SS_SetPreShift = $ + 2
   ld   bc,$0000   ; B = # bits before start of row (self-modified)
   ld   a,b
   or   a
   jr   z,_SS_PutBitsLeft
   ld   a,(de)
_SS_PreShift:
   rlca
   djnz   _SS_PreShift
   ld   (de),a
_SS_PutBitsLeft:
_SS_SetBitsLeft = $ + 1
   ld   b,$00      ; # bits to copy into first byte (self-modified)

_SS_SetPixelWidth = $ + 1
   ld   a,$00      ; pixel width of sprite data (self-modified)
   push   af
   jr   _SS_DoPixel
_SS_RowLoop:
   and   %00000111
   jr   nz,_SS_SameByte
   inc   hl
_SS_SameByte:
_SS_SetScale2 = $ + 1
   ld   a,0      ; scale factor (self-modified)
   add   a,c
   ld   c,a
   jr   z,_SS_DoPixel
   jr   nc,_SS_SkipPixel
_SS_DoPixel:
   ld   a,(de)
   rlc   (hl)
#ifndef _SS_LD
   jr   nc,_SS_LeaveBit
#ifdef _SS_XOR
   bit   7,a
   jr   z,_SS_LeaveCarry
   ccf
_SS_LeaveCarry:
#endif
#endif
   rla
#ifndef _SS_LD
   jr   _SS_DoneBit
_SS_LeaveBit:
   rlca
_SS_DoneBit:
#endif
   ld   (de),a
   djnz   _SS_DoneByte
   ld   b,8
   inc   de
   jr   _SS_DoneByte
_SS_SkipPixel:
   rlc   (hl)
_SS_DoneByte:
   pop   af
   dec   a
   push   af
   jr   nz,_SS_RowLoop
_SS_DoneRow:
   inc   hl
   bit   3,b
   jr   nz,_SS_RowComplete
   ld   a,(de)
_SS_PostShift:
   rlca
   djnz   _SS_PostShift
   ld   (de),a
   inc   de
_SS_RowComplete:
   pop   af
   ex   (sp),hl
   ld   de,12
   add   hl,de
   ex   de,hl
   pop   hl

_SS_SkipRow:
   pop   bc
   djnz   _SS_SpriteLoop
   ret
CPL is complementary, so like xor $FF, the asm command to cpl the register a is simply cpl
Response to trip1ea:

I actually call that routine 4 times in my original code, but if it can be modified to call twice or even once, that would be great. Or even if I can call it once pointing to the mask, and once to load in the greyscale layers, that would be perfect. I'll be back tonight to play around with it some... but it would be a big help if someone could just fill me in as to what part of that routine scales and what part actually renders.
bump!
Well, I'm officially stuck here...
_SS_RowLoop is where the rendering begins. Also, the edits I made and linked to you earlier only does one layer of the sprite. (mask the first time, draw the second time).
Btw, rather than cpl the mask, just store it already cpl'd. Instead of
Code:
; mask
.db %00000000
.db %01111110
.db %01111110
.db %01111110
.db %01111110
.db %01111110
.db %01111110
.db %00000000
use:
Code:
; mask
.db %11111111
.db %10000001
.db %10000001
.db %10000001
.db %10000001
.db %10000001
.db %10000001
.db %11111111
I'm not sure how scaling a mask would work, though.
chickendude, Zeda was kind enough to help with that, so its done. The only coding remaining in this project is:

1. Map generator.
2. Making the rendering engine render objects with farther objects behind closer ones (rather than in the order they occur as it is currently). For this, i was thinking some sort of shunting yard sorting.
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
Page 1 of 1
» All times are UTC - 5 Hours
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

 

Advertisement