News:

Printed Amstrad Addict magazine announced, check it out here!

Main Menu
avatar_AMSDOS

Moving Graphical Images Down the Screen.

Started by AMSDOS, 11:52, 29 August 12

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

ervin

Looking good!
Just got back from a few days on holiday (touring caves and stuff) - it's great to see how this has progressed in that time.

If you change line 310, does it give the effect you are after?


310 FOR y%=3 TO 18 step 2



AMSDOS

Quote from: ervin on 13:49, 07 October 13
Looking good!
Just got back from a few days on holiday (touring caves and stuff) - it's great to see how this has progressed in that time.

If you change line 310, does it give the effect you are after?


310 FOR y%=3 TO 18 step 2


Hmm, funny cause I'm on Hols too and just came back from camping out over the last wkend.

I thought the way I had it was correct, but I'll try that out. ESD works a bit differently from the other Sprite routine I made, but I made it so it uses SCR CHAR POS (&BC1A) which is the same as ESD, though ESD uses XOR Sprites so a sprite is only deleted when it's drawn over itself, so it's a bit different from simply deleting it
* Using the old Amstrad Languages :D   * with the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

ervin

#52
 :)
Where'd you go camping? We went down to the south-east of south australia with the kids.
Had a great time.

Alrighty, since ESD uses XOR to draw the sprites, you can gain a tiny speed-up by simplifying line 350.


350 |SPRITE,1,x%,y%


Also, you won't be able to compile your program, as CPC Basic 3 doesn't allow loading BIN files using the LOAD command, and the MEMORY command doesn't do anything either.  :(

AMSDOS

Quote from: ervin on 02:17, 08 October 13
Alrighty, since ESD uses XOR to draw the sprites, you can gain a tiny speed-up by simplifying line 350.


350 |SPRITE,1,x%,y%

Ok, I actually found a problem in my original program, it appears that when I used ESD to GRAB the sprite, I'd only GRAB half of it (might of been due to me saving half the sprite in Bytes rather than Hexadecimal Bytes), so when I was using the Y-Loop to STEP 2, there was a gap. This updated version corrects that, so the Y-LOOP steps twice and I've altered 350 to read that, so now it's working a bit faster again.  :D

QuoteAlso, you won't be able to compile your program, as CPC Basic 3 doesn't allow loading BIN files using the LOAD command, and the MEMORY command doesn't do anything either.  :(

So it would be easier to load all those things from a BASIC Loader, followed by the CPC BASIC 3 program? To be honest I haven't looked to see how CPC BASIC 3 deals with RSXes, so I'll need to see how that works.
* Using the old Amstrad Languages :D   * with the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

ervin

#54
Nice job - it's working well now.
ESD would have been very useful in the dark old days of magazine type-ins!

Yeah, that might be worth a shot (loading the compiled BIN from loco BASIC)!
(I hadn't thought of that).


AMSDOS

Quote from: ervin on 04:24, 08 October 13
Nice job - it's working well now.
ESD would have been very useful in the dark old days of magazine type-ins!

Yeah, that might be worth a shot (loading the compiled BIN from loco BASIC)!
(I hadn't thought of that).

Yeah check this out. All I had to do to make this work was delete lines 20 & 30 which load ESD & the Brick Sprite. I used CPCBASIC 3 to output the code to a Disk Image, but I guess you can just as easily make it assembly source, ccz80, etc and just added the ESD program and Brick Sprite to that disc along with a BASIC Loader. At compile time it wasn't worried about the ESD or the Sprite data not being there, though obviously Running the code in the Emulator wouldn't work and as long as the RSXes are there before the main program is executed, it'll work in nicely with it.

ESD is pretty old, on Sean's "The Sprite Idea" website, Sean stated that The Sprite Definer & Driver Software appeared on the June 1992 Covertape, which is true, though the Driver component which is ESD, was first a Type-in Issue 55 (April 1990), which came with a demonstration of Batman. This nifty driver came about because Pat McDonald wrote a Sprite Editor which was a Type-In in AA43 and then some corrections were made to it in AA46, which isn't a bad little program if you don't exit the program. In between that period AA were hinting at having a Sprite Driver and they had an interesting little Assembly Guide to which some Sprite Drivers were published, though I think people were quite happy when ESD come out, because it simply meant they could type it in and use it without much fuss.
The Sprite Definer Sean made after ESD is a bit fiddly to use I thought, though the sprites you make with it will obviously be usable with ESD immediately, though the beauty of ESD is it was designed so you can grab your Sprites from screenshots, the Grab Routine is a little bit tricky to use because the Width is in Bytes & Height is in Pixels, though with all that sorted out it's pretty straightforward to use.
It wasn't written to be an 1-Pixel Perfect Program, with that Sean wrote "ESD Advanced", and it's using Text Based Coordinates from 0,0 to 79,24 to draw the Sprites, though benefits in it's speed. I guess given the size of ESD, I never saw any Type-ins afterwards which used it, though it wouldn't surprise me if Sean had it in some of his later Type-ins like Gribbet (AA66) or Alien Intenvention (AA91), the Public Domain game Sean wrote "The Further Adventures Of Fred", is perhaps an example of what you can do with ESD cause everything in that game is Character Based and it moves around very well.
* Using the old Amstrad Languages :D   * with the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

ervin

WOW! That's an amazing speed difference!
Well done on your excellent work-around to get it working in CPC BASIC 3.
That's really useful info for the future.

AMSDOS

I've just made some slight adjustments to the last program, in this example instead of relying on ESD, I've taken the BASIC Source Code (OUTPUT.ASC) and am using one of my own routines to plot the image which I've included in the Disk Image as DISP.ASM. Originally I had my plotting routine occupying the same space to which CBASIC 3 Assembles the code, though had no problems relocating it. I've also taken the OUTPUT.ASC BASIC code and made OUTPUT.CC which is the CCZ80. I had to modify my BASIC code cause it appears the SCR FLOOD BOX doesn't support XOR mode which explains for the slow down from the previous ESD version.

I only came up with this version to see if the SCR FLOOD BOX routine was perhaps shifting the Bricks Diagonally across the screen, however this code seems to be working in the appropriate manner, which suggests there's a flaw in my earlier Assembly code which is shifting the Bricks Diagonally.
* Using the old Amstrad Languages :D   * with the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

AMSDOS

I've done some modifications which has addressed the problem of the Bricks Moving Up the Screen Diagonally, the problem seemed related to how I was using the Loop to Double Count. What I've done to change this is to have it as a Single Count and use "sla" to space things out. It's worked out well with the Bricks moving straight up the screen, though there's some odd things happening with Bricks Appearing/Disappearing along the 8th Row & the Bottom Row is doing a bit of the same, so I'm not quite sure why that's happening.

org &4000

xor a
call &bc0e

xor a
ld b,a
ld c,a
call &bc32 ;; Set up Inks
ld a,1
ld bc,&0d0d
call &bc32
ld a,2
ld bc,&0a0a
call &bc32
ld a,3
ld bc,&0202
call &bc32

ld a,(x)
sla a
ld (pos_x),a

ld a,(y)
sla a
ld (pos_y),a

.setbase
xor a ;; ld a,(isone)
ld (base),a ;; base = 1

.return xor a ;; ld a,(isone)
ld (s),a ;; s = 1 (for position of Scr Array)
ld a,(base)
ld (m),a ;; m = base ( for position of map array)

.mainloop

ld hl,scr ;; setup scr array
ld a,(s) ;; s determines position
ld c,a ;; has to be incremented
ld b,0 ;; using bc
add hl,bc ;; hl holds position of scr
push hl ;; needs to be preserved
ld hl,map ;; setup map array
ld a,(m) ;; with m as position of it
ld c,a ;; again using
ld b,0 ;; bc to incrment with
add hl,bc ;; hl holds position of map
ld a,(hl) ;; store this into accumulator
pop hl ;; restore position of scr array
cp (hl) ;; compare contents scr with map position
jr z,skip ;; if it's the same then jump to skip

ld hl,map ;; }
ld a,(m) ;; }
ld c,a ;; }
ld b,0 ;; }
add hl,bc ;; }
ex hl,de ;; }
ld hl,scr ;; } Otherwise scr position
ld a,(s) ;; } equals map position
ld c,a ;; }
ld b,0 ;; }
add hl,bc ;; }
ld (hl),e ;; }
;; inc hl ;; }
;; ld (hl),d ;; }

;; ld hl,blank
;; ld (addrimg),hl
;; ld hl,(y)

ld hl,map ;;
ld a,(m) ;;
ld c,a ;;
ld b,0 ;; if position of map
add hl,bc ;; is not equal 1 then
ld a,(hl) ;; jump to skip2
cp 1 ;;
jr nz,skip2 ;;


ld hl,bricks
ld (addrimg),hl

;; push af
ld hl,(pos_y)
call begin
;; pop af

cp 0
jr z,skip


.skip2 ld hl,blank
ld (addrimg),hl
ld hl,(pos_y)
call begin

.skip ld a,(s)
inc a ;; increment s to next position
ld (s),a

ld a,(m)
inc a ;; increment m to next position
ld (m),a

ld a,(x) ;; if x has not reached
ld b,a
ld a,(xcount) ;; value determine by xcount
cp b
jr z,chk_m ;; jump back to x_loop for another pass

ld a,(x)
inc a
ld (x),a
sla a
ld (pos_x),a

jp mainloop

.chk_m ld a,(m) ;; }
ld b,a ;; } if m has not reached a value 
ld a,161 ;; } of 161 or more then jump to chk_y
cp b ;; }
jr nc,chk_y ;; }

xor a ;; ld a,(isone)
ld (m),a ;; otherwise m = 1

.chk_y  xor a ;;ld a,(isone)
ld (x),a

ld a,(y) ;; if y has not reached
ld b,a
ld a,(ycount) ;; value determine by ycount
cp b
jr z,resval ;; jump back to y_loop for another pass

ld a,(y)
inc a
ld (y),a ;; increment y
sla a
ld (pos_y),a

jp mainloop

.resval
xor a ;; ld a,(isone)
ld (x),a

;; xor a ;; ld a,(isone)
ld (y),a

ld a,(base) ;; }
add a,8 ;; } increment base by 8
ld (base),a ;; }
ld b,a
ld a,161 ;; if base > 161
cp b
jp c,setbase ;; jump to setbase if value has been reached

jp return ;; otherwise jump to return position
ret

.begin call &bc1a ;; SCR CHAR POSITION coverts this into a Screen Address

ld (scraddr),hl ;; Screen Address of Location
ld (storscraddr),hl ;; This is used because Scradr has to be Incremented

.sprloop ld d,1 ;; Width of the Image
ld e,d ;; Height of the Image

ld hl,(addrimg) ;; This points to the Bit Mask Data (the patten which
ld c,(hl) ;; gets drawn), and gets stored into the C register.

ld hl,(scraddr) ;; Address of the screen address.

call &bc47 ;; SCR FLOOD BOX.
;; Entry: C = Encoded INK
;; D = Width of the Image
;; E = Height of the Image
;; HL = Address to draw the Image.

ld hl,(scraddr) ;; I then have to increment the value of screen
inc hl ;; address to the next position to draw the next spot
ld (scraddr),hl ;; along. It gets stored so I can reuse my registers.

ld hl,(addrimg) ;; The address for the Bit Mask Pattern is also
inc hl ;; increment to point to the next value and is also
ld (addrimg),hl ;; stored as well.

ld a,(count1) ;; This is my loop sequence and again I needed to store
inc a ;; values into memory. I wanted to use my old friend
ld (count1),a ;; DJNZ, though was proving to be a nightmare.
ld b,a ;; This one checks if count1 equals loop1 and if it

ld a,(loop1) ;; doesn't it will jump back to loop to do another pass.

cp b
jr nz,sprloop ;; The Jump is applied here back to the loop label.

ld a,(count1) ;; If it has reacted this point then count1 equals loop1
xor a ;; it must be set back to zero so it can work when it
ld (count1),a ;; returns back to the main loop.

ld hl,(storscraddr) ;; This is used to calculate the previous line.
call &bc26 ;; SCR NEXT LINE
ld (scraddr),hl ;; I store the value into scraddr for the main loop
ld (storscraddr),hl ;; and I also store the screen address for this routine.

ld a,(count2) ;; Once all that is done I have to do the same thing
inc a ;; here and check to see if count2 equals loop2. And
ld (count2),a ;; again the values need to be stored in memory and
ld b,a ;; recalled again for when I need to check.

ld a,(loop2) ;; As long as count2 is not equal to loop 2, it will

cp b ;; return back to the main loop, otherwise it will
jr nz,sprloop ;; proceed to exit, back to BASIC if called from there.


ld a,(count2) ;; though upon exit count2 needs to return to 0
xor a ;; Just so this routine can be recalled again.
ld (count2),a ;; values are returned into it's rightful place.

ret


.loop1 defb 8 ;; Width of the Image
.loop2 defb 16 ;; Height of the Image
.count1 defb 0 ;; Checks for when the Width of the Image is Reached
.count2 defb 0 ;; Checks for when the Height of the Image is Reached
.scraddr defw 0 ;; Holds the screen address in relation to the Width.
.storscraddr defw 0 ;; Retains original screen address to calculate next line.
.addofimage defw 0 ;; Points to the address of the image to Display
.bricks defb 0,0,0,0,0,0,0,0
defb 192,12,12,12,12,12,12,0
defb 192,12,12,12,12,12,12,0
defb 204,12,12,12,12,12,12,0
defb 0,0,0,0,0,0,0,0
defb 12,12,12,0,192,12,12,12
defb 12,12,12,0,192,12,12,12
defb 192,192,192,0,204,192,192,192
defb 0,0,0,0,0,0,0,0
defb 192,12,12,12,12,12,12,0
defb 192,12,12,12,12,12,12,0
defb 204,12,12,12,12,12,12,0
defb 0,0,0,0,0,0,0,0
defb 12,12,12,0,192,12,12,12
defb 12,12,12,0,192,12,12,12
defb 192,192,192,0,204,192,192,192

.blank defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
.isone defb 1 ;; Constant value of 1
.base defb 0
.m defb 0
.s defb 0
.y defb 0
.x defb 0
.pos_y defb 0
.pos_x defb 0
.addrimg
defw 0
.xcount defb 7
.ycount defb 7
.scr ;; defb 0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0

.map defb 0
defb 0,0,0,0,0,0,0,1
defb 1,0,0,0,0,0,0,0
defb 0,0,1,0,0,1,0,0
defb 0,0,0,0,0,0,0,0
defb 0,1,0,0,0,0,0,0
defb 1,0,1,0,0,0,0,0
defb 0,0,0,1,1,0,0,0
defb 0,0,0,0,0,0,0,1
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 1,0,0,0,0,1,1,1
defb 1,1,1,0,0,0,0,1
defb 1,1,1,0,0,0,0,1
defb 1,0,0,1,1,0,0,1
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 1,0,0,1,0,0,1,1
defb 1,0,0,1,1,0,0,1
defb 1,0,0,0,0,0,0,1
defb 1,0,0,0,0,0,0,1
defb 1,1,0,0,1,1,1,1
* Using the old Amstrad Languages :D   * with the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

redbox

Quote from: AMSDOS on 07:14, 27 January 14
I've done some modifications which has addressed the problem of the Bricks Moving Up the Screen Diagonally, the problem seemed related to how I was using the Loop to Double Count. What I've done to change this is to have it as a Single Count and use "sla" to space things out. It's worked out well with the Bricks moving straight up the screen, though there's some odd things happening with Bricks Appearing/Disappearing along the 8th Row & the Bottom Row is doing a bit of the same, so I'm not quite sure why that's happening.

What are you trying to do here?

When I assembled and run the program I got the bricks appearing and disappearing randomly on the screen.

Axelay

Quote from: AMSDOS on 07:14, 27 January 14
I've done some modifications which has addressed the problem of the Bricks Moving Up the Screen Diagonally, the problem seemed related to how I was using the Loop to Double Count. What I've done to change this is to have it as a Single Count and use "sla" to space things out. It's worked out well with the Bricks moving straight up the screen, though there's some odd things happening with Bricks Appearing/Disappearing along the 8th Row & the Bottom Row is doing a bit of the same, so I'm not quite sure why that's happening.



The main problem I can see is that on a couple of occasions (after the chk_y and resval labels) you have not kept pos_x or pos_y in sync with the x or y values.  I'm attaching the fixed source, with two other changes.  One is that the update of the screen buffer didnt appear to be handled correctly in mainloop, so every block would be updated whether it needed to or not, and the other is that with SCR FLOOD BOX being used to write a single byte to the screen, I just couldnt resist replacing that with a simple load!  ;)  I've preceded the changes I made with a row of semi colons so you can spot them easily.


   
org &4000

xor a
call &bc0e

xor a
ld b,a
ld c,a
call &bc32 ;; Set up Inks
ld a,1
ld bc,&0d0d
call &bc32
ld a,2
ld bc,&0a0a
call &bc32
ld a,3
ld bc,&0202
call &bc32

ld a,(x)
sla a
ld (pos_x),a

ld a,(y)
sla a
ld (pos_y),a

.setbase
xor a ;; ld a,(isone)
ld (base),a ;; base = 1

.return xor a ;; ld a,(isone)
ld (s),a ;; s = 1 (for position of Scr Array)
ld a,(base)
ld (m),a ;; m = base ( for position of map array)

.mainloop

ld hl,scr ;; setup scr array
ld a,(s) ;; s determines position
ld c,a ;; has to be incremented
ld b,0 ;; using bc
add hl,bc ;; hl holds position of scr
push hl ;; needs to be preserved
ld hl,map ;; setup map array
ld a,(m) ;; with m as position of it
ld c,a ;; again using
ld b,0 ;; bc to incrment with
add hl,bc ;; hl holds position of map
ld a,(hl) ;; store this into accumulator
pop hl ;; restore position of scr array
cp (hl) ;; compare contents scr with map position
jr z,skip ;; if it's the same then jump to skip

ld hl,map ;; }
ld a,(m) ;; }
ld c,a ;; }
ld b,0 ;; }
add hl,bc ;; }
ex hl,de ;; }
ld hl,scr ;; } Otherwise scr position
ld a,(s) ;; } equals map position
ld c,a ;; }
ld b,0 ;; }
add hl,bc ;; }
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ld (hl),e ;; }
        ld a,(de) ;; get new value from map
ld (hl),a ;; and write it to screen
;; inc hl ;; }
;; ld (hl),d ;; }

;; ld hl,blank
;; ld (addrimg),hl
;; ld hl,(y)

ld hl,map ;;
ld a,(m) ;;
ld c,a ;;
ld b,0 ;; if position of map
add hl,bc ;; is not equal 1 then
ld a,(hl) ;; jump to skip2
cp 1 ;;
jr nz,skip2 ;;


ld hl,bricks
ld (addrimg),hl

;; push af
ld hl,(pos_y)
call begin
;; pop af

cp 0
jr z,skip


.skip2 ld hl,blank
ld (addrimg),hl
ld hl,(pos_y)
call begin

.skip ld a,(s)
inc a ;; increment s to next position
ld (s),a

ld a,(m)
inc a ;; increment m to next position
ld (m),a

ld a,(x) ;; if x has not reached
ld b,a
ld a,(xcount) ;; value determine by xcount
cp b
jr z,chk_m ;; jump back to x_loop for another pass

ld a,(x)
inc a
ld (x),a
sla a
ld (pos_x),a

jp mainloop

.chk_m ld a,(m) ;; }
ld b,a ;; } if m has not reached a value 
ld a,161 ;; } of 161 or more then jump to chk_y
cp b ;; }
jr nc,chk_y ;; }

xor a ;; ld a,(isone)
ld (m),a ;; otherwise m = 1

.chk_y  xor a ;;ld a,(isone)
ld (x),a
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
sla a
ld (pos_x),a ;; maintain pos_x

ld a,(y) ;; if y has not reached
ld b,a
ld a,(ycount) ;; value determine by ycount
cp b
jr z,resval ;; jump back to y_loop for another pass

ld a,(y)
inc a
ld (y),a ;; increment y
sla a
ld (pos_y),a

jp mainloop

.resval
xor a ;; ld a,(isone)
ld (x),a
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
sla a
ld (pos_x),a ;; maintain pos_x

;; xor a ;; ld a,(isone)
ld (y),a
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
sla a
ld (pos_y),a ;; maintain pos_y

ld a,(base) ;; }
add a,8 ;; } increment base by 8
ld (base),a ;; }
ld b,a
ld a,161 ;; if base > 161
cp b
jp c,setbase ;; jump to setbase if value has been reached

jp return ;; otherwise jump to return position
ret

.begin call &bc1a ;; SCR CHAR POSITION coverts this into a Screen Address

ld (scraddr),hl ;; Screen Address of Location
ld (storscraddr),hl ;; This is used because Scradr has to be Incremented

.sprloop ld d,1 ;; Width of the Image
ld e,d ;; Height of the Image

ld hl,(addrimg) ;; This points to the Bit Mask Data (the patten which
ld c,(hl) ;; gets drawn), and gets stored into the C register.

ld hl,(scraddr) ;; Address of the screen address.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ld (hl),c ;; much faster than using SCR FLOOD BOX for a 1x1 byte area!!!
; call &bc47 ;; SCR FLOOD BOX.
;; Entry: C = Encoded INK
;; D = Width of the Image
;; E = Height of the Image
;; HL = Address to draw the Image.

ld hl,(scraddr) ;; I then have to increment the value of screen
inc hl ;; address to the next position to draw the next spot
ld (scraddr),hl ;; along. It gets stored so I can reuse my registers.

ld hl,(addrimg) ;; The address for the Bit Mask Pattern is also
inc hl ;; increment to point to the next value and is also
ld (addrimg),hl ;; stored as well.

ld a,(count1) ;; This is my loop sequence and again I needed to store
inc a ;; values into memory. I wanted to use my old friend
ld (count1),a ;; DJNZ, though was proving to be a nightmare.
ld b,a ;; This one checks if count1 equals loop1 and if it

ld a,(loop1) ;; doesn't it will jump back to loop to do another pass.

cp b
jr nz,sprloop ;; The Jump is applied here back to the loop label.

ld a,(count1) ;; If it has reacted this point then count1 equals loop1
xor a ;; it must be set back to zero so it can work when it
ld (count1),a ;; returns back to the main loop.

ld hl,(storscraddr) ;; This is used to calculate the previous line.
call &bc26 ;; SCR NEXT LINE
ld (scraddr),hl ;; I store the value into scraddr for the main loop
ld (storscraddr),hl ;; and I also store the screen address for this routine.

ld a,(count2) ;; Once all that is done I have to do the same thing
inc a ;; here and check to see if count2 equals loop2. And
ld (count2),a ;; again the values need to be stored in memory and
ld b,a ;; recalled again for when I need to check.

ld a,(loop2) ;; As long as count2 is not equal to loop 2, it will

cp b ;; return back to the main loop, otherwise it will
jr nz,sprloop ;; proceed to exit, back to BASIC if called from there.


ld a,(count2) ;; though upon exit count2 needs to return to 0
xor a ;; Just so this routine can be recalled again.
ld (count2),a ;; values are returned into it's rightful place.

ret


.loop1 defb 8 ;; Width of the Image
.loop2 defb 16 ;; Height of the Image
.count1 defb 0 ;; Checks for when the Width of the Image is Reached
.count2 defb 0 ;; Checks for when the Height of the Image is Reached
.scraddr defw 0 ;; Holds the screen address in relation to the Width.
.storscraddr defw 0 ;; Retains original screen address to calculate next line.
.addofimage defw 0 ;; Points to the address of the image to Display
.bricks defb 0,0,0,0,0,0,0,0
defb 192,12,12,12,12,12,12,0
defb 192,12,12,12,12,12,12,0
defb 204,12,12,12,12,12,12,0
defb 0,0,0,0,0,0,0,0
defb 12,12,12,0,192,12,12,12
defb 12,12,12,0,192,12,12,12
defb 192,192,192,0,204,192,192,192
defb 0,0,0,0,0,0,0,0
defb 192,12,12,12,12,12,12,0
defb 192,12,12,12,12,12,12,0
defb 204,12,12,12,12,12,12,0
defb 0,0,0,0,0,0,0,0
defb 12,12,12,0,192,12,12,12
defb 12,12,12,0,192,12,12,12
defb 192,192,192,0,204,192,192,192

.blank defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
.isone defb 1 ;; Constant value of 1
.base defb 0
.m defb 0
.s defb 0
.y defb 0
.x defb 0
.pos_y defb 0
.pos_x defb 0
.addrimg
defw 0
.xcount defb 7
.ycount defb 7
.scr ;; defb 0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0

.map defb 0
defb 0,0,0,0,0,0,0,1
defb 1,0,0,0,0,0,0,0
defb 0,0,1,0,0,1,0,0
defb 0,0,0,0,0,0,0,0
defb 0,1,0,0,0,0,0,0
defb 1,0,1,0,0,0,0,0
defb 0,0,0,1,1,0,0,0
defb 0,0,0,0,0,0,0,1
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 1,0,0,0,0,1,1,1
defb 1,1,1,0,0,0,0,1
defb 1,1,1,0,0,0,0,1
defb 1,0,0,1,1,0,0,1
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 1,0,0,1,0,0,1,1
defb 1,0,0,1,1,0,0,1
defb 1,0,0,0,0,0,0,1
defb 1,0,0,0,0,0,0,1
defb 1,1,0,0,1,1,1,1

AMSDOS

Quote from: redbox on 18:29, 27 January 14
What are you trying to do here?

When I assembled and run the program I got the bricks appearing and disappearing randomly on the screen.

Well I was only getting the bricks appearing and disappearing around the edge and bottom of the screen, I could still see some of my data being supplied working accordingly. Have a look my early assembly example (movshp.asm) which is using TXT OUTPUT (&BB5A) which works if that's of any help. The idea here is to supply data from "map" and to patch it into "scr", but it's moving it through that to generate an 8x8 field, so as it moves the data further into "map" gets displayed.

It's only an example though I was interested to see how it could be applied in a graphical sense, I wasn't critical about what Sprite Driver to use for this, which is why it's a bit on the slow side.
* Using the old Amstrad Languages :D   * with the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

AMSDOS

Quote from: Axelay on 08:50, 28 January 14

The main problem I can see is that on a couple of occasions (after the chk_y and resval labels) you have not kept pos_x or pos_y in sync with the x or y values.  I'm attaching the fixed source, with two other changes.  One is that the update of the screen buffer didnt appear to be handled correctly in mainloop, so every block would be updated whether it needed to or not, and the other is that with SCR FLOOD BOX being used to write a single byte to the screen, I just couldnt resist replacing that with a simple load!  ;)  I've preceded the changes I made with a row of semi colons so you can spot them easily.

Thanks for that, yes I can now why not updating the pos_x or pos_y would cause those problems with the blinking. Not quite sure what you mean about the Screen Buffer, unfortunately my comments are vague in that area. Funny that SCR FLOOD BOX would irritate someone and even funnier that a simple LD (HL),C fixes it.  ;D

I made the sprite routine a little more compact by commenting out the ld d,1 ld e,d which SCR FLOOD BOX uses. Also I've removed the first defb 0 at the start of map, so now it's correctly displaying the maze that I had in my early text version of the program.  :D



org &4000

xor a
call &bc0e

xor a
ld b,a
ld c,a
call &bc32 ;; Set up Inks
ld a,1
ld bc,&0d0d
call &bc32
ld a,2
ld bc,&0a0a
call &bc32
ld a,3
ld bc,&0202
call &bc32

ld a,(x)
sla a
ld (pos_x),a

ld a,(y)
sla a
ld (pos_y),a

.setbase
xor a ;; ld a,(isone)
ld (base),a ;; base = 1

.return xor a ;; ld a,(isone)
ld (s),a ;; s = 1 (for position of Scr Array)
ld a,(base)
ld (m),a ;; m = base ( for position of map array)

.mainloop

ld hl,scr ;; setup scr array
ld a,(s) ;; s determines position
ld c,a ;; has to be incremented
ld b,0 ;; using bc
add hl,bc ;; hl holds position of scr
push hl ;; needs to be preserved
ld hl,map ;; setup map array
ld a,(m) ;; with m as position of it
ld c,a ;; again using
ld b,0 ;; bc to incrment with
add hl,bc ;; hl holds position of map
ld a,(hl) ;; store this into accumulator
pop hl ;; restore position of scr array
cp (hl) ;; compare contents scr with map position
jr z,skip ;; if it's the same then jump to skip

ld hl,map ;; }
ld a,(m) ;; }
ld c,a ;; }
ld b,0 ;; }
add hl,bc ;; }
ex hl,de ;; }
ld hl,scr ;; } Otherwise scr position
ld a,(s) ;; } equals map position
ld c,a ;; }
ld b,0 ;; }
add hl,bc ;; }
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ld (hl),e ;; }
        ld a,(de) ;; get new value from map
ld (hl),a ;; and write it to screen
;; inc hl ;; }
;; ld (hl),d ;; }

;; ld hl,blank
;; ld (addrimg),hl
;; ld hl,(y)

ld hl,map ;;
ld a,(m) ;;
ld c,a ;;
ld b,0 ;; if position of map
add hl,bc ;; is not equal 1 then
ld a,(hl) ;; jump to skip2
cp 1 ;;
jr nz,skip2 ;;


ld hl,bricks
ld (addrimg),hl

;; push af
ld hl,(pos_y)
call begin
;; pop af

cp 0
jr z,skip


.skip2 ld hl,blank
ld (addrimg),hl
ld hl,(pos_y)
call begin

.skip ld a,(s)
inc a ;; increment s to next position
ld (s),a

ld a,(m)
inc a ;; increment m to next position
ld (m),a

ld a,(x) ;; if x has not reached
ld b,a
ld a,(xcount) ;; value determine by xcount
cp b
jr z,chk_m ;; jump back to x_loop for another pass

ld a,(x)
inc a
ld (x),a
sla a
ld (pos_x),a

jp mainloop

.chk_m ld a,(m) ;; }
ld b,a ;; } if m has not reached a value 
ld a,161 ;; } of 161 or more then jump to chk_y
cp b ;; }
jr nc,chk_y ;; }

xor a ;; ld a,(isone)
ld (m),a ;; otherwise m = 1

.chk_y  xor a ;;ld a,(isone)
ld (x),a
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
sla a
ld (pos_x),a ;; maintain pos_x

ld a,(y) ;; if y has not reached
ld b,a
ld a,(ycount) ;; value determine by ycount
cp b
jr z,resval ;; jump back to y_loop for another pass

ld a,(y)
inc a
ld (y),a ;; increment y
sla a
ld (pos_y),a

jp mainloop

.resval
xor a ;; ld a,(isone)
ld (x),a
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
sla a
ld (pos_x),a ;; maintain pos_x

;; xor a ;; ld a,(isone)
ld (y),a
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
sla a
ld (pos_y),a ;; maintain pos_y

ld a,(base) ;; }
add a,8 ;; } increment base by 8
ld (base),a ;; }
ld b,a
ld a,161 ;; if base > 161
cp b
jp c,setbase ;; jump to setbase if value has been reached

jp return ;; otherwise jump to return position
ret

.begin call &bc1a ;; SCR CHAR POSITION coverts this into a Screen Address

ld (scraddr),hl ;; Screen Address of Location
ld (storscraddr),hl ;; This is used because Scradr has to be Incremented

.sprloop ;; ld d,1 ;; Width of the Image
;; ld e,d ;; Height of the Image

ld hl,(addrimg) ;; This points to the Bit Mask Data (the patten which
ld c,(hl) ;; gets drawn), and gets stored into the C register.

ld hl,(scraddr) ;; Address of the screen address.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ld (hl),c ;; much faster than using SCR FLOOD BOX for a 1x1 byte area!!!
; call &bc47 ;; SCR FLOOD BOX.
;; Entry: C = Encoded INK
;; D = Width of the Image
;; E = Height of the Image
;; HL = Address to draw the Image.

ld hl,(scraddr) ;; I then have to increment the value of screen
inc hl ;; address to the next position to draw the next spot
ld (scraddr),hl ;; along. It gets stored so I can reuse my registers.

ld hl,(addrimg) ;; The address for the Bit Mask Pattern is also
inc hl ;; increment to point to the next value and is also
ld (addrimg),hl ;; stored as well.

ld a,(count1) ;; This is my loop sequence and again I needed to store
inc a ;; values into memory. I wanted to use my old friend
ld (count1),a ;; DJNZ, though was proving to be a nightmare.
ld b,a ;; This one checks if count1 equals loop1 and if it

ld a,(loop1) ;; doesn't it will jump back to loop to do another pass.

cp b
jr nz,sprloop ;; The Jump is applied here back to the loop label.

ld a,(count1) ;; If it has reacted this point then count1 equals loop1
xor a ;; it must be set back to zero so it can work when it
ld (count1),a ;; returns back to the main loop.

ld hl,(storscraddr) ;; This is used to calculate the previous line.
call &bc26 ;; SCR NEXT LINE
ld (scraddr),hl ;; I store the value into scraddr for the main loop
ld (storscraddr),hl ;; and I also store the screen address for this routine.

ld a,(count2) ;; Once all that is done I have to do the same thing
inc a ;; here and check to see if count2 equals loop2. And
ld (count2),a ;; again the values need to be stored in memory and
ld b,a ;; recalled again for when I need to check.

ld a,(loop2) ;; As long as count2 is not equal to loop 2, it will

cp b ;; return back to the main loop, otherwise it will
jr nz,sprloop ;; proceed to exit, back to BASIC if called from there.


ld a,(count2) ;; though upon exit count2 needs to return to 0
xor a ;; Just so this routine can be recalled again.
ld (count2),a ;; values are returned into it's rightful place.

ret


.loop1 defb 8 ;; Width of the Image
.loop2 defb 16 ;; Height of the Image
.count1 defb 0 ;; Checks for when the Width of the Image is Reached
.count2 defb 0 ;; Checks for when the Height of the Image is Reached
.scraddr defw 0 ;; Holds the screen address in relation to the Width.
.storscraddr defw 0 ;; Retains original screen address to calculate next line.
.addofimage defw 0 ;; Points to the address of the image to Display
.bricks defb 0,0,0,0,0,0,0,0
defb 192,12,12,12,12,12,12,0
defb 192,12,12,12,12,12,12,0
defb 204,12,12,12,12,12,12,0
defb 0,0,0,0,0,0,0,0
defb 12,12,12,0,192,12,12,12
defb 12,12,12,0,192,12,12,12
defb 192,192,192,0,204,192,192,192
defb 0,0,0,0,0,0,0,0
defb 192,12,12,12,12,12,12,0
defb 192,12,12,12,12,12,12,0
defb 204,12,12,12,12,12,12,0
defb 0,0,0,0,0,0,0,0
defb 12,12,12,0,192,12,12,12
defb 12,12,12,0,192,12,12,12
defb 192,192,192,0,204,192,192,192

.blank defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
.isone defb 1 ;; Constant value of 1
.base defb 0
.m defb 0
.s defb 0
.y defb 0
.x defb 0
.pos_y defb 0
.pos_x defb 0
.addrimg
defw 0
.xcount defb 7
.ycount defb 7
.scr ;; defb 0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0

.map ;; defb 0
defb 0,0,0,0,0,0,0,1
defb 1,0,0,0,0,0,0,0
defb 0,0,1,0,0,1,0,0
defb 0,0,0,0,0,0,0,0
defb 0,1,0,0,0,0,0,0
defb 1,0,1,0,0,0,0,0
defb 0,0,0,1,1,0,0,0
defb 0,0,0,0,0,0,0,1
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 1,0,0,0,0,1,1,1
defb 1,1,1,0,0,0,0,1
defb 1,1,1,0,0,0,0,1
defb 1,0,0,1,1,0,0,1
defb 0,0,0,0,0,0,0,0
defb 0,0,0,0,0,0,0,0
defb 1,0,0,1,0,0,1,1
defb 1,0,0,1,1,0,0,1
defb 1,0,0,0,0,0,0,1
defb 1,0,0,0,0,0,0,1
defb 1,1,0,0,1,1,1,1
* Using the old Amstrad Languages :D   * with the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

Axelay

Quote from: AMSDOS on 10:10, 28 January 14
Not quite sure what you mean about the Screen Buffer, unfortunately my comments are vague in that area.


I was referring to the second block of code in mainloop, where you originally had:



   ld hl,map      ;; }
   ld a,(m)      ;; }
   ld c,a         ;; }
   ld b,0         ;; }
   add hl,bc      ;; }
   ex hl,de      ;; }
   ld hl,scr      ;; } Otherwise scr position
   ld a,(s)      ;; } equals map position
   ld c,a         ;; }
   ld b,0         ;; }
   add hl,bc      ;; }
   ld (hl),e      ;; }
This bit of code in mainloop is only executed if the preceding part of code found the contents pointed to in the scr buffer did not match the contents of the memory location pointed to in map.  So this section of code above would presumably be updating the scr table to reflect what is about to be printed to screen at the current location so when it next updates that block, it wont print anything if the block is the same.  But this code ends with ld (hl),e, where e is the low byte of the pointer to map, which means it's almost certainly marking scr with a value different to what it will find in map next time in the preceding code, so that the block will subsequently be updated whether it changes or not.  What it actually needs to be writing to scr is the contents pointed to by de in map, so it should be ld a,(de):ld (hl),a.


It is worth noting though that at the point of that branch in mainloop just before the code segment I posted above, a already contains the value of the new block, and hl already contains a pointer to the appropriate location in scr, so the entire segment of code above could be replaced with ld (hl),a:)

AMSDOS

Quote from: Axelay on 12:41, 30 January 14

I was referring to the second block of code in mainloop, where you originally had:



   ld hl,map      ;; }
   ld a,(m)      ;; }
   ld c,a         ;; }
   ld b,0         ;; }
   add hl,bc      ;; }
   ex hl,de      ;; }
   ld hl,scr      ;; } Otherwise scr position
   ld a,(s)      ;; } equals map position
   ld c,a         ;; }
   ld b,0         ;; }
   add hl,bc      ;; }
   ld (hl),e      ;; }
This bit of code in mainloop is only executed if the preceding part of code found the contents pointed to in the scr buffer did not match the contents of the memory location pointed to in map.  So this section of code above would presumably be updating the scr table to reflect what is about to be printed to screen at the current location so when it next updates that block, it wont print anything if the block is the same.  But this code ends with ld (hl),e, where e is the low byte of the pointer to map, which means it's almost certainly marking scr with a value different to what it will find in map next time in the preceding code, so that the block will subsequently be updated whether it changes or not.  What it actually needs to be writing to scr is the contents pointed to by de in map, so it should be ld a,(de):ld (hl),a.


It is worth noting though that at the point of that branch in mainloop just before the code segment I posted above, a already contains the value of the new block, and hl already contains a pointer to the appropriate location in scr, so the entire segment of code above could be replaced with ld (hl),a:)

I think what happened initially was I was using CPC BASIC 3 to translate my BASIC code into Assembly, which is what I pretty much came up with, which probably explains the lack of comments and it's pretty much a pile of high-level language turned into Assembly.
That would probably be right in that I make a whole lump of code and it could potentially be replaced by a single instruction.  :(
* Using the old Amstrad Languages :D   * with the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

redbox

Quote from: AMSDOS on 22:15, 31 January 14
I think what happened initially was I was using CPC BASIC 3 to translate my BASIC code into Assembly, which is what I pretty much came up with, which probably explains the lack of comments and it's pretty much a pile of high-level language turned into Assembly.
That would probably be right in that I make a whole lump of code and it could potentially be replaced by a single instruction.  :(

Nothing wrong with turning a high level language into assembler to see what's going on, it's just another way of learning.

Even C programmers have to resort to inline assembler sometimes when they realise their loops just aren't fast enough ;)

ervin

That's how I write my code.
I use ccz80 to get something working (and it creates fast code anyway), but then I use inline asm to speed up loops.


AMSDOS

I didn't mean to make it sound as if it was a bad thing and in a way the earlier code reinforces what the earlier BASIC program was doing even though all the information was already there when I was asking for it again, when I didn't need to and the information could simply be copied over to the scr array.  :D

It just overwhelms me that I can get bogged down in Assembly that things tend to get blown out to the point things can be extremely simplified because you've had the wool pulled over your eyes.  :o
* Using the old Amstrad Languages :D   * with the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

Powered by SMFPacks Menu Editor Mod