Heaven/TQA Posted September 22, 2007 Author Share Posted September 22, 2007 thanks miker...will have a look... ah...just looked into the code...its antic e... but i can not use antic e for Beyond Evil as i need anyway a charbased screen to handle the drop/picking/door routine. so thats why i went down the road for soft sprites in antic 4...but maybe we can found games which use that mode instead of antic e.... and for all who think that you can have antic 4 softsprites for free can have a look into the source code....that is the overhead you need for 1 8x16 sprite... (ok...the code is not optimised yet like unroll code, lookup tables but...) Quote Link to comment Share on other sites More sharing options...
Heaven/TQA Posted September 22, 2007 Author Share Posted September 22, 2007 f.e. download Dropzone from Fandal's website. Enter Monitor by Hitting F8 and enter "A 380C". now we are altering the DLI code and switching back the playfield area into system font.... so enter the codes "LDA #$E0", "NOP" and press RETURN to go back to the monitor...now restart the game by entering CONT. start a game and you will see the "mess"... Quote Link to comment Share on other sites More sharing options...
Heaven/TQA Posted September 22, 2007 Author Share Posted September 22, 2007 mr robot and his robot factory looks promissing. Quote Link to comment Share on other sites More sharing options...
Shawn Jefferson Posted September 23, 2007 Share Posted September 23, 2007 f.e. download Dropzone from Fandal's website. Enter Monitor by Hitting F8 and enter "A 380C". now we are altering the DLI code and switching back the playfield area into system font.... so enter the codes "LDA #$E0", "NOP" and press RETURN to go back to the monitor...now restart the game by entering CONT. start a game and you will see the "mess"... You need to type "A 380D" actually. That's interesting, especially interesting when the guy blows up. All those single pixels are actually characters... wierd. I also always liked the display list effects in the title screen/attract mode. So easy to do on the Atari, but effective. Quote Link to comment Share on other sites More sharing options...
Heaven/TQA Posted September 24, 2007 Author Share Posted September 24, 2007 small update of the soft sprite test.... it's now with masking the background...so now we have "real sprites". now let us check how we can optimise the code and/or the data (f.e. store gfx/mask upside down). when the stuff works i will through the engine into Beyond Evil and see what happens. sprite3.zip Quote Link to comment Share on other sites More sharing options...
Heaven/TQA Posted October 3, 2007 Author Share Posted October 3, 2007 i guess i find a solution for Beyond... i will have 4 different monster types per floor level. so i can write 4 different sub routines for handling the soft sprites. the routine can look like this: set_sprite_monster0: ;set pointer to desired sprite #0 - #3 (no*9 = charoffset) ... ldy #0 ldx #15 loop_stripe0: lda (charpointer),y and monster0_mask,x ora monster0_data,x sta (charpointer),y iny dex bpl loop_stripe0 ldx #15 ldy #24 loop_stripe1: lda (charpointer),y and monster0_mask+16,x ora monster0_data+16,x sta (charpointer),y iny dex bpl loop_stripe1 ldx #15 ldy #48 loop_stripe2: lda (charpointer),y and monster0_mask+32,x ora monster0_data+32,x sta (charpointer),y iny dex bpl loop_stripe2 ... i am thinking about a faster way without preshifting sprite data in y direction as well... but havent found any yet. Menace does only move in y-direction in 8 pixel (1 char) steps so the copy routine is more compact but i haven't found any solution for Beyond Evil yet. what do you think? looks good imho. so when player is entering new tower level the monster sprite data + mask data is copied into the 4 different monster buffers. so when using 4 different sprite routines this could simplify things. the sprite pointer is set to correct sprite chars depending on the sprite no. and the y-offset for the data is stored directly into the pointer. Quote Link to comment Share on other sites More sharing options...
Heaven/TQA Posted October 4, 2007 Author Share Posted October 4, 2007 actually there will be 8 different subroutines. 4 for each facing (4 left, 4 right). Quote Link to comment Share on other sites More sharing options...
gauntman Posted October 4, 2007 Share Posted October 4, 2007 I suspect that some of the techniques discussed back in May with bitmapped soft-sprites can also be applied here. I don't know how necessary they would be if you only have 4 softsprites on screen though. The basic idea boiled down to: lda (chardata_stripe1),y and #160 ; spritemask byte 0 ora #160 ; sprite data byte 0 sta (chardata_stripe1),y lda (chardata_stripe2),y and #3 ; spritemask byte 16 ora #2 ; sprite data byte 16 sta (chardata_stripe2),y lda (chardata_stripe3),y and #160 ; spritemask byte 32 ora #160 ; sprite data byte 32 sta (chardata_stripe3),y iny lda (chardata_stripe1),y and #168 ; spritemask byte 1 ora #168 ; sprite data byte 1 sta (chardata_stripe1),y . . . Of course, you can optimize each of the shifted sprites when they fall on even character borders (when any horiz pos x&4=0, it will only be 2 strips wide, not 3); Depending on the how you are using the code, you may even be able to use x indexing instead of zero,y. Certainly, this will work for the player character that will always be the same shape in the same character range: lda playersprite_stripe1,x and #160 ora #160 sta playersprite_stripe1,x . . . inx . . . which could save a number of cycles. This might be able to work with the monsters, as long as there are no more than 3 on screen: ldx #0 ; base offset for enemy 0 jsr drawsprite ldx #72; base offset for enemy 1 jsr drawsprite drawsprite: lda enemy0_stripe1,x and #160 ora #160 sta enemy0_stripe1,x . . . Of course, unrolling a sprite will take something like 4-5k per unique shape (I think I was calculating for 12 bytes tall, not 16) which may be too much memory. Also, filling in the playerdata from the background is expensive, and not accounted for here. I suppose you could unroll the player only, since it will always be displayed, and use the slower, but significantly more memory efficient method for the monsters. I was hoping to use this method for driving ~10 character sprites during an NTSC VBI, but I don't think it will fit in the time slice (I wasn't planning on masking, only on ora'ing in the data). I may need to try writing up a routine for timing. Quote Link to comment Share on other sites More sharing options...
Heaven/TQA Posted October 4, 2007 Author Share Posted October 4, 2007 there is one issue in my code which i havent covered...and makes the thing again more complicated... of course i need sprite masks for the shifted sprite data and the shifted sprite data as well... and with my absolute ANDs and ORAs without pointers... i can't move pixelwise in x-direction... grrr... Quote Link to comment Share on other sites More sharing options...
Heaven/TQA Posted October 5, 2007 Author Share Posted October 5, 2007 (edited) ok. more thoughts yesterday... as i need flexible pointers (for animation, positioning the preshifted data) i thought that using a pointer for the LDA/STA (sprite),y is not the best way to go as the AND/ORA (DATA),y will change more often but the sprite-adresses (the char-adresses for each sprite) are fixed. so it does make more sense to use self modified code for these 2 instructions than for the masks and data. so the loop might be like this ... ;set sprite start adresses for each stripe ldx sprite_nr lda sprite_stripe0_lo,x sta set0+1 lda sprite_stripe0_hi,x sta set00+2 lda sprite_stripe1_lo,x sta set1+1 lda sprite_stripe1_hi,x sta set11+2 lda sprite_stripe2_lo,x sta set2+1 lda sprite_stripe2_hi,x sta set22+2 lda sprite_y and #7 tax stx temp ldy #15 loop: set0: lda spritead,x and (mask),y ora (data),y set00: sta spritead,x inx dey bpl loop ldx temp ldy #15 loop: set1: lda spritead,x and (mask),y ora (data),y set11: sta spritead,x inx dey bpl loop ldx temp ldy #15 loop: set2: lda spritead,x and (mask),y ora (data),y set22: sta spritead,x inx dey bpl loop ... so the pointers mask/data can be adjusted each frame and for pixel positioning. they are changing more frequently than the fixed chars used for the softsprites... looks better than the old one. tss... thanks for lookup tables which i haven't used for ages... seems i am too long in game mode and not demo mode where most of the time you are using precalculated stuff... Edited October 5, 2007 by Heaven/TQA Quote Link to comment Share on other sites More sharing options...
Heaven/TQA Posted October 6, 2007 Author Share Posted October 6, 2007 ehm...nobody spotted the error in the code...as the pointers mask/data needs to be adjusted for each stripe as well...aaarg... Quote Link to comment Share on other sites More sharing options...
Heaven/TQA Posted October 6, 2007 Author Share Posted October 6, 2007 and some more errors... aarg.... i hate it... some philosophy question...can code have some errors as i am writing the code...so how can the code have some? hmmm...seems like the same like in the WoW south park episode... "how can you kill someone who has no life"? Quote Link to comment Share on other sites More sharing options...
Heaven/TQA Posted October 6, 2007 Author Share Posted October 6, 2007 and who ever told us...that atari can easily simulate the c64 sprites by software...i can tell you some secret...he does not know how much cpu time is needed at the end of the day.... Quote Link to comment Share on other sites More sharing options...
Heaven/TQA Posted October 6, 2007 Author Share Posted October 6, 2007 ok...here is the correct code: et_sprite_monster0: lda x;div 4 lsr lsr sta xp lda y;div 8 lsr lsr lsr tax lda linetabl,x clc adc xp sta pointer lda linetabh,x adc #0 sta pointer+1 jsr copy_background;copy background chars into sprite chars ;now set sprite on screen lda char tax ldy #0 sta (pointer),y inx txa ldy #40 sta (pointer),y inx txa ldy #80 sta (pointer),y inx txa ldy #1 sta (pointer),y inx txa ldy #41 sta (pointer),y inx txa ldy #81 sta (pointer),y inx txa ldy #2 sta (pointer),y inx txa ldy #42 sta (pointer),y inx txa ldy #82 sta (pointer),y lda x and #3 tay lda #<sprmaskr clc adc x_offsettab,y sta pointer2 lda #>sprmaskr sta pointer2+1 lda #<sprdatar clc adc x_offsettab,y sta pointer3 lda #>sprdatar sta pointer3+1 ;set sprite start adresses for each stripe ldx sprite_nr ldx #0 lda sprite_stripe0_lo,x sta set_stripe0+1 sta set_stripe00+1 lda sprite_stripe0_hi,x sta set_stripe0+2 sta set_stripe00+2 lda sprite_stripe1_lo,x sta set_stripe1+1 sta set_stripe11+1 lda sprite_stripe1_hi,x sta set_stripe1+2 sta set_stripe11+2 lda sprite_stripe2_lo,x sta set_stripe2+1 sta set_stripe22+1 lda sprite_stripe2_hi,x sta set_stripe2+2 sta set_stripe22+2 lda y and #7 tax sta temp ldy #15 ; ldx temp set_stripe0: lda sprite,x and (pointer2),y ora (pointer3),y set_stripe00: sta sprite,x inx dey bpl set_stripe0 ldy #31 ldx temp lda #15 sta temp2 set_stripe1: lda sprite,x and (pointer2),y ora (pointer3),y set_stripe11: sta sprite,x inx dey dec temp2 bpl set_stripe1 ldy #47 lda #15 sta temp2 ldx temp set_stripe2: lda sprite,x and (pointer2),y ora (pointer3),y set_stripe22: sta sprite,x inx dey dec temp2 bpl set_stripe2 rts copy_background: lda #<sprite sta temp3 lda #>sprite sta temp3+1 ldy #0 lda (pointer),y jsr copy_char ldy #40 lda (pointer),y jsr copy_char ldy #80 lda (pointer),y jsr copy_char ldy #1 lda (pointer),y jsr copy_char ldy #41 lda (pointer),y jsr copy_char ldy #81 lda (pointer),y jsr copy_char ldy #2 lda (pointer),y jsr copy_char ldy #42 lda (pointer),y jsr copy_char ldy #82 lda (pointer),y jmp copy_char copy_char: ;char*8 tax lda fonttabl,x sta temp lda fonttabh,x sta temp+1 ldy #7 copy_char1 lda (temp),y sta (temp3),y dey bpl copy_char1 lda temp3 clc adc #8 sta temp3 bcc copy_char2 inc temp3+1 copy_char2 rts org $5000 x_offsettab dta 0,48,96,144;sprite offset 48 bytes per sprite(3 stripes a 16 bytes) sprite_stripe0_lo: dta <sprite sprite_stripe0_hi: dta >sprite sprite_stripe1_lo: dta <(sprite+24) sprite_stripe1_hi: dta >(sprite+24) sprite_stripe2_lo: dta <(sprite+48) sprite_stripe2_hi: dta >(sprite+48) not optimised...but hopefully some can imagine that the guys with hardware sprite all are doing this in hardware... leaving cpu free for many things more.... ps. first optimising stept is to change the draw order f.e. stripe 3, 2, 1 so i can leave the reloading of the index... Quote Link to comment Share on other sites More sharing options...
Heaven/TQA Posted October 6, 2007 Author Share Posted October 6, 2007 and...this is code for 1 8x16 sprite.... C64 has 8x 24x21...moveable with some STAs.... man...why did atari used the damned 2600 like player/missles... Quote Link to comment Share on other sites More sharing options...
JamesD Posted October 7, 2007 Share Posted October 7, 2007 (edited) and...this is code for 1 8x16 sprite.... C64 has 8x 24x21...moveable with some STAs.... man...why did atari used the damned 2600 like player/missles... Atari did that because it was the mid 1970s when it was designed and that type of circuit was already available to the engineers. The C64 was an 80's design and CBM had their own chip manufacturing plants. Also remember, to animate the sprite you don't need a complete new routine for each frame of the animation (if you hard code each sprite)... you just point the sprite hardware to the new data location. That saves a LOT of memory and clock cycles. That and the SID is why I gave the C64 the edge as a game machine over the Atari in another thread. But then... it depends on the game now doesn't it. The Speccy had a lot of 3D and Isometric games for it because it's 1 bit/pixel display was fast to update and it was clocked pretty fast for a Z80 machine of that time. Just for the record... the Plus/4 has had a lot of C64 games hacked to run on it just by doing this sort of thing so it is definitely possible. True sprites do save a lot of CPU time and memory though. Hmmmm... do you suppose it might be faster to move a sprite from 1 location to another on the C64 in BASIC than it is for the Atari to do this? Edited October 7, 2007 by JamesD Quote Link to comment Share on other sites More sharing options...
Heaven/TQA Posted October 7, 2007 Author Share Posted October 7, 2007 ok. here is the first "multiple" soft sprite test engine... its so "fast" that it can not handle 2 sprites per VBL... thats why the 2nd sprite is not moving in y-direction (as it would disappear at the top screen area). but that's ok as in Beyond Evil the sprite will not move fast anyway so the max. 4 enemy monsters will be handled in separate VBL cycles anyway. next will be to the background sprite buffer which needs to be implemented as at the moment the vram is filled each frame. but for Beyond Evil i need a proper sprite buffer for scanning the items covered by the sprite. when this is done i will make a first test with the Beyond Evil engine and hope it does not get screwed up. sprite4.zip Quote Link to comment Share on other sites More sharing options...
gauntman Posted October 8, 2007 Share Posted October 8, 2007 ok. here is the first "multiple" soft sprite test engine... its so "fast" that it can not handle 2 sprites per VBL... thats why the 2nd sprite is not moving in y-direction (as it would disappear at the top screen area). but that's ok as in Beyond Evil the sprite will not move fast anyway so the max. 4 enemy monsters will be handled in separate VBL cycles anyway. next will be to the background sprite buffer which needs to be implemented as at the moment the vram is filled each frame. but for Beyond Evil i need a proper sprite buffer for scanning the items covered by the sprite. when this is done i will make a first test with the Beyond Evil engine and hope it does not get screwed up. I was thinking about this a bit over the weekend. There are a few shortcuts I can make in the project I am working on, and perhaps you can make some of the same assumptions: The important bit is the following: Overlap is only between sprites, no background/sprite overlap. I was surprised by this, but after tweaking my character set a bit, I realized that picking up objects, running into walls, etc. could be modified to always be character boundaries. The entire map could be reduced to impassible (filled chars) or passable (blank) This basic assumption leads to a few interesting optimizations: If the player is updated every frame (and always drawn first), you do not need to perform any masking or eor'ing of data, the player data can be copied straight across - if this does not completely hold, the first sprite drawn each frame can be handled this way. It might be worth making the player character always first, since then you can hardcode the destination address. Sprite/Sprite interaction - if sprites cannot visually overlap, then you can remove the masking of each frame. The only needed operation is the eor (or ora); Finally: Mostly sprites will be drawn over blank characters. When this happens, no eor/mask or background character copy is required. It is probably worth checking this case, assuming overhead of the test is low enough. Even if you are planning on allowing background or visual sprite overlap, the common case will tend to be no overlap (well as long as you have a consistent single character background - preferably blank) . This makes it more important to figure out a good way to perform the check cheaply. Quote Link to comment Share on other sites More sharing options...
Heaven/TQA Posted October 8, 2007 Author Share Posted October 8, 2007 i was thinking in a similar way. but before leaving out the masking and do other things i will try to implement it straight away and see what happens. the "draw player first" is a valid point to consider. but what about following steps to think about: - avoid overlapping of the sprites (have to think about a quick check with the xp,yp of one sprite agains the 4 others (incl. 3 monster, 1 player) - the design of the sprites are done in a way where players would notice "black background" when moving over the loot f.e. imagine the bird sprite or the snake or even the player. and i do not want to give too many restriction to the artists. - do not draw the "buffer chars" when on even x mod 4 and y mod 8 lines as they are not needed. or as alternative...only copy background into those chars... so it's correct that they are still many ways to optimise the whole bunch of code. see Menace where the sprites do not move by pixel for faster code. Quote Link to comment Share on other sites More sharing options...
Heaven/TQA Posted October 8, 2007 Author Share Posted October 8, 2007 hmmm... just had 4 sprites running...now the background handling comes in place... and the restore of the background to be more precise. otherwise the sprites disappear except for the active one... Quote Link to comment Share on other sites More sharing options...
Heaven/TQA Posted October 9, 2007 Author Share Posted October 9, 2007 i guess i do not let the monsters overlap. but i am not sure if this is not already done? can not remember, if not...anybody has a quick solution for checking overlapping? this must be some kind of common issue for ages in computer science? anyway... i am sure some of you know the VIC20 game Amok!... what do you think of that engine? and as my pro eyeunderstands the game itselft only moves the shots, 1 robot and the player per frame? the game itself is here...use vice! emulator for vic... http://www.zimmers.net/anonftp/pub/cbm/vic...nded/index.html Quote Link to comment Share on other sites More sharing options...
gauntman Posted October 9, 2007 Share Posted October 9, 2007 i guess i do not let the monsters overlap. but i am not sure if this is not already done? can not remember, if not...anybody has a quick solution for checking overlapping? this must be some kind of common issue for ages in computer science? I would use bounding boxes. Particularly with a small number of sprites, this should be fast enough. I think there have been a number of discussions here about this. One good on is here: http://www.atariage.com/forums/index.php?showtopic=64287 I think there was on in the 6502 killer hacks thread. Hmmmm.... here: http://www.atariage.com/forums/index.php?s...st&p=873438 It is not pixel perfect collision, but more than enough for avoiding overlap. Quote Link to comment Share on other sites More sharing options...
Heaven/TQA Posted October 13, 2007 Author Share Posted October 13, 2007 here is another small update of the sprite routines...now different speed per sprite and clearing of the background of each sprite (not restore yet)... i am moving 4 monsters so actually this will be the speed in the game. you notice a flicker when sprites are overlapping each others (same like in dropzone btw...) but as i am avoiding overlapping should be no major issue... i am still not 100% sure if i will copy the background gfx into the sprites... more checks later... sprite4.zip Quote Link to comment Share on other sites More sharing options...
Heaven/TQA Posted October 15, 2007 Author Share Posted October 15, 2007 small update...now with background restore... the background gets messed up simply because i am not avoiding overlapping... well... as more i am into it...i have to say... sprite hardware rules... look how many cpu cycle are needed, look how much code (not even optimised f.e. like with unrolled loops etc... which cause more code), many lookup tables and i am not able to move more than 1 sprite per frame...and the sprite is a 8x16 one... vertical movement of player/missles is simple compared to own soft sprite routines... now i know why a lot of people went for antic e games instead of using chars... it's far simpler and faster (but not for beyond evil... ) sprite4.zip Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.