News:

Printed Amstrad Addict magazine announced, check it out here!

Main Menu
avatar_rexbeng

CORSAIR_Trainer

Started by rexbeng, 17:11, 12 October 20

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Axelay

Quote from: sigh on 20:00, 17 October 20
Man...this game is hard!

I own Radiant Silvergun, Battle Garegga on my Sega Saturn and Ketsui and Esp.Rade on my PS3 and PS4. All of these are tricky games and Corsair Trainer has now joined them in the difficulty ranks :D .
Congrats to the team for producing an excellent game. Wonderful coding by Axelay as usual. Rexbeng - wonderful job on the artwork and McKlain's solid sound engineering completes this package.
Well done!


Can't say I had those games in mind when I was thinking of the difficulty, but thanks for the comparison.  :)


Quote from: lmimmfn on 00:19, 19 October 20Do you think it would be possible to update your code to hide the redraw at the top of the screen? I want to try my hand at an arcade game, im ok with Z80 code,i would just like a routine that works. The mode 2 proposal with colour change where both colours are the same seems like a good fix but can it be interrupt driven or does it need specific timing( which sux :) )



Here you go.  Bear in mind this is that old prototype with the screen movement at the top hidden.  No update of the comments, nor updating with whatever changes I might have subsequently made to the current code base for Corsair.  It waits during the first interrupt for quite some time to show the highest possible line of the screen.  If you don't want to find stable code to put there in the interrupt and not waste cpu time, you can remove the delay and move the second mode/colour change to the second interrupt, but you'll lose 2 characters from the top of the screen.





org &4000
nolist
run start


start:
;; standard screen is 39 chars tall and vsync at 30
;; with 25 chars displayed
;;
;; we want to change this to 26 chars displayed with vsync at 31
;;
;; Char Lines to end of screen: 39-31 = 8
;; Scan Lines to end of screen: 8*8 = 64
;; Interrupt occurs two lines after VSYNC, so lines until end of screen when interrupt occurs: 64-2 = 62
;;
;; If we then wait for one interrupt, we will be 10 (62-52 = 10) lines into the next screen.
;;
;; Then interrupts are:
;; 10, 62, 114, 166, 218
;;
;; And we will then be 10 lines into second screen.




di
ld bc,&7f10
out (c),c
ld bc,&7f54
out (c),c


; narrow the screen
ld bc,&bc01
out (c),c
ld bc,&bd00+32
out (c),c
; and centre it
ld bc,&bc02
out (c),c
ld bc,&bd00+42
out (c),c




;; set new vsync we want
ld bc,&bc07
out (c),c
ld bc,&bd00+31+4
out (c),c


;; wait for 2 vsyncs to allow it to stabalise and so that we can sync with that
ld e,2
wait_two_vsyncs:
ld b,&f5
wait_vsync_end:
in a,(c)
rra
jr c,wait_vsync_end
wait_vsync_start:
in a,(c)
rra
jr nc,wait_vsync_start
dec e
jp nz,wait_two_vsyncs


;; synchronised with start of vsync and we are synchronised with CRTC too, and we have the
;; same number of lines to next screen as we want.


;; set initial interrupt routine
ld hl,int_rout1
ld (int_rout_ptr+1),hl


;; set interrupt
ld a,&c3
ld hl,int_start
ld (&0038),a
ld (&0039),hl
;; enable
ei


main_loop:
ld b,&f5
vsync:
in a,(c)
rra
jr nc,vsync


halt


halt


call scroll_down


jp main_loop


;;---------


int_start:
push bc
push hl
push af
int_rout_ptr:
jp int_rout1




;;---------
;; first interrupt after vsync
int_rout1:
;;ld bc,&7f10
;;out (c),c
;;ld bc,&7f4b
;;out (c),c


;; set vsync position to turn it off
ld bc,&bc07
out (c),c
ld bc,&bdff
out (c),c


;; screen address for main part of screen
;; will not trigger until screen restarts
ld hl,(scroll_offset)
ld a,&30
or a,h
ld bc,&bc0c
out (c),c
inc b
out (c),a
ld bc,&bc0d
out (c),c
inc b
out (c),l


;; set height of main part of screen
;; since we are already past the end of the previous screen
;; this will take no effect.
ld bc,&bc06
out (c),c
ld bc,&bd00+25+4
out (c),c


ld bc,&bc05         ;; select vertical adjust register of CRTC
out (c),c
inc b
ld a,(scroll_fine_next)
out (c),a
ld (scroll_fine),a


; mask movement of screen top
;set mode 2
  ld bc,&7F8e
  out (c),c
; set colours to border
  ld bc,&7f00
  out (c),c
  ld a,&54
  out (c),a ; background to match border
  inc c
  out (c),c
  out (c),a ; ink 1 to match border


; wait until at lowest point of screen top
  ld b,246
.int1delaylp
  defs 5 ; some nops
  djnz int1delaylp
;set mode 1
  ld bc,&7F8d
  out (c),c
; set colours to standard mode 1
  ld bc,&7f00
  out (c),c
  ld a,&44
  out (c),a ; background to dark blue
  inc c
  out (c),c
  ld a,&4a
  out (c),a ; ink 1 to yellow


ld hl,int_rout2
jp int_end


;;---------
int_rout2:
;; 10 lines until end of screen
;;ld bc,&7f10
;;out (c),c
;;ld bc,&7f43
;;out (c),c


ld hl,int_rout3
jp int_end


;;---------
int_rout3:
;;ld bc,&7f10
;;out (c),c
;;ld bc,&7f42
;;out (c),c


;; now at line 42.
ld bc,&bc04
out (c),c
ld bc,&bd00+25-1+4-1 ; less 1 because of R5 offset
out (c),c




ld hl,int_rout4
jp int_end


;;---------
int_rout4:


;;ld bc,&7f10
;;out (c),c
;;ld bc,&7f40
;;out (c),c




ld hl,int_rout5
jp int_end


;;---------
int_rout5:


;;ld bc,&7f10
;;out (c),c
;;ld bc,&7f49
;;out (c),c




ld bc,&bc0c
out (c),c
ld bc,&bd00+&18
out (c),c
ld bc,&bc0d
out (c),c
ld bc,&bd00
out (c),c


ld bc,&bc05         ;; select vertical adjust register of CRTC
out (c),c
inc b
ld a,(scroll_fine)
xor a,7
inc a
out (c),a


ld hl,int_rout6
jp int_end


;;---------
int_rout6:
;;ld bc,&7f10
;;out (c),c
;;ld bc,&7f53
;;out (c),c


;; 2 lines before end of screen


;; 128 cycles
ld b,42-1 ; need one less after addition of push af
int_delay:
djnz int_delay


;; set display height of screen
ld bc,&bc06
out (c),c
ld bc,&bd00+1+3
out (c),c


;; set height of screen
ld bc,&bc04
out (c),c
ld bc,&bd00+14-1-4
out (c),c


;; set vsync position
ld bc,&bc07
out (c),c
ld bc,&bd00+6
out (c),c


ld hl,int_rout1
jp int_end


int_end:
ld (int_rout_ptr+1),hl
pop af
pop hl
pop bc
ei
ret


;;end start


.scroll_down
;; check fine value first
    ld a,(scroll_fine_next)
    inc a
    and 7
    ld (scroll_fine_next),a
    or a
    ret nz


;; get the current scroll offset
    ld hl,(scroll_offset)
    ld bc,32
    or a
    sbc hl,bc


;; ensure scroll offset is in range &000-&3ff
    ld a,h
    and &3
    ld h,a


;; store new scroll offset. It is now ready to be written to the CRTC.
    ld (scroll_offset),hl
    ret


;; the scroll offset in CRTC character units
.scroll_offset
    defw 0
;; offset for fine scroll
.scroll_fine
    defb 0
.scroll_fine_next
    defb 0

lmimmfn

#26
Quote from: Gryzor on 07:31, 19 October 20
Which page are you referring to?
Ignore this
6128 for the win!!!

lmimmfn

#27
Thanks very much Axelay, will give it a whirl tonight.


@Gryzor, ignore my previous post, can you Sticky Axelays vertical scrolling routine above in the programming section?
6128 for the win!!!

lmimmfn

Quote from: Axelay on 14:24, 19 October 20

Can't say I had those games in mind when I was thinking of the difficulty, but thanks for the comparison.  :)




Here you go.  Bear in mind this is that old prototype with the screen movement at the top hidden.  No update of the comments, nor updating with whatever changes I might have subsequently made to the current code base for Corsair.  It waits during the first interrupt for quite some time to show the highest possible line of the screen.  If you don't want to find stable code to put there in the interrupt and not waste cpu time, you can remove the delay and move the second mode/colour change to the second interrupt, but you'll lose 2 characters from the top of the screen.





org &4000
nolist
run start


start:
;; standard screen is 39 chars tall and vsync at 30
;; with 25 chars displayed
;;
;; we want to change this to 26 chars displayed with vsync at 31
;;
;; Char Lines to end of screen: 39-31 = 8
;; Scan Lines to end of screen: 8*8 = 64
;; Interrupt occurs two lines after VSYNC, so lines until end of screen when interrupt occurs: 64-2 = 62
;;
;; If we then wait for one interrupt, we will be 10 (62-52 = 10) lines into the next screen.
;;
;; Then interrupts are:
;; 10, 62, 114, 166, 218
;;
;; And we will then be 10 lines into second screen.




di
ld bc,&7f10
out (c),c
ld bc,&7f54
out (c),c


; narrow the screen
ld bc,&bc01
out (c),c
ld bc,&bd00+32
out (c),c
; and centre it
ld bc,&bc02
out (c),c
ld bc,&bd00+42
out (c),c




;; set new vsync we want
ld bc,&bc07
out (c),c
ld bc,&bd00+31+4
out (c),c


;; wait for 2 vsyncs to allow it to stabalise and so that we can sync with that
ld e,2
wait_two_vsyncs:
ld b,&f5
wait_vsync_end:
in a,(c)
rra
jr c,wait_vsync_end
wait_vsync_start:
in a,(c)
rra
jr nc,wait_vsync_start
dec e
jp nz,wait_two_vsyncs


;; synchronised with start of vsync and we are synchronised with CRTC too, and we have the
;; same number of lines to next screen as we want.


;; set initial interrupt routine
ld hl,int_rout1
ld (int_rout_ptr+1),hl


;; set interrupt
ld a,&c3
ld hl,int_start
ld (&0038),a
ld (&0039),hl
;; enable
ei


main_loop:
ld b,&f5
vsync:
in a,(c)
rra
jr nc,vsync


halt


halt


call scroll_down


jp main_loop


;;---------


int_start:
push bc
push hl
push af
int_rout_ptr:
jp int_rout1




;;---------
;; first interrupt after vsync
int_rout1:
;;ld bc,&7f10
;;out (c),c
;;ld bc,&7f4b
;;out (c),c


;; set vsync position to turn it off
ld bc,&bc07
out (c),c
ld bc,&bdff
out (c),c


;; screen address for main part of screen
;; will not trigger until screen restarts
ld hl,(scroll_offset)
ld a,&30
or a,h
ld bc,&bc0c
out (c),c
inc b
out (c),a
ld bc,&bc0d
out (c),c
inc b
out (c),l


;; set height of main part of screen
;; since we are already past the end of the previous screen
;; this will take no effect.
ld bc,&bc06
out (c),c
ld bc,&bd00+25+4
out (c),c


ld bc,&bc05         ;; select vertical adjust register of CRTC
out (c),c
inc b
ld a,(scroll_fine_next)
out (c),a
ld (scroll_fine),a


; mask movement of screen top
;set mode 2
  ld bc,&7F8e
  out (c),c
; set colours to border
  ld bc,&7f00
  out (c),c
  ld a,&54
  out (c),a ; background to match border
  inc c
  out (c),c
  out (c),a ; ink 1 to match border


; wait until at lowest point of screen top
  ld b,246
.int1delaylp
  defs 5 ; some nops
  djnz int1delaylp
;set mode 1
  ld bc,&7F8d
  out (c),c
; set colours to standard mode 1
  ld bc,&7f00
  out (c),c
  ld a,&44
  out (c),a ; background to dark blue
  inc c
  out (c),c
  ld a,&4a
  out (c),a ; ink 1 to yellow


ld hl,int_rout2
jp int_end


;;---------
int_rout2:
;; 10 lines until end of screen
;;ld bc,&7f10
;;out (c),c
;;ld bc,&7f43
;;out (c),c


ld hl,int_rout3
jp int_end


;;---------
int_rout3:
;;ld bc,&7f10
;;out (c),c
;;ld bc,&7f42
;;out (c),c


;; now at line 42.
ld bc,&bc04
out (c),c
ld bc,&bd00+25-1+4-1 ; less 1 because of R5 offset
out (c),c




ld hl,int_rout4
jp int_end


;;---------
int_rout4:


;;ld bc,&7f10
;;out (c),c
;;ld bc,&7f40
;;out (c),c




ld hl,int_rout5
jp int_end


;;---------
int_rout5:


;;ld bc,&7f10
;;out (c),c
;;ld bc,&7f49
;;out (c),c




ld bc,&bc0c
out (c),c
ld bc,&bd00+&18
out (c),c
ld bc,&bc0d
out (c),c
ld bc,&bd00
out (c),c


ld bc,&bc05         ;; select vertical adjust register of CRTC
out (c),c
inc b
ld a,(scroll_fine)
xor a,7
inc a
out (c),a


ld hl,int_rout6
jp int_end


;;---------
int_rout6:
;;ld bc,&7f10
;;out (c),c
;;ld bc,&7f53
;;out (c),c


;; 2 lines before end of screen


;; 128 cycles
ld b,42-1 ; need one less after addition of push af
int_delay:
djnz int_delay


;; set display height of screen
ld bc,&bc06
out (c),c
ld bc,&bd00+1+3
out (c),c


;; set height of screen
ld bc,&bc04
out (c),c
ld bc,&bd00+14-1-4
out (c),c


;; set vsync position
ld bc,&bc07
out (c),c
ld bc,&bd00+6
out (c),c


ld hl,int_rout1
jp int_end


int_end:
ld (int_rout_ptr+1),hl
pop af
pop hl
pop bc
ei
ret


;;end start


.scroll_down
;; check fine value first
    ld a,(scroll_fine_next)
    inc a
    and 7
    ld (scroll_fine_next),a
    or a
    ret nz


;; get the current scroll offset
    ld hl,(scroll_offset)
    ld bc,32
    or a
    sbc hl,bc


;; ensure scroll offset is in range &000-&3ff
    ld a,h
    and &3
    ld h,a


;; store new scroll offset. It is now ready to be written to the CRTC.
    ld (scroll_offset),hl
    ret


;; the scroll offset in CRTC character units
.scroll_offset
    defw 0
;; offset for fine scroll
.scroll_fine
    defb 0
.scroll_fine_next
    defb 0

This is beautiful, thank you so much.
6128 for the win!!!

Gryzor

Quote from: lmimmfn on 20:38, 19 October 20
Thanks very much Axelay, will give it a whirl tonight.


@Gryzor, ignore my previous post, can you Sticky Axelays vertical scrolling routine above in the programming section?

It must be a separate post to be pinned, I can't just take a text snippet... Feel free anyone to create a new post in that forum and notify me to pin it :)

lmimmfn

Quote from: Gryzor on 07:28, 20 October 20
It must be a separate post to be pinned, I can't just take a text snippet... Feel free anyone to create a new post in that forum and notify me to pin it :)
No problem, i can create a thread tomorrow with Axelay's code, linking related threads and of course attributing the work to those involved and ping you afterwards.

6128 for the win!!!

Gryzor

Sounds great! Perhaps a wiki article would be better suited, but whatever people want 😁

lmimmfn

Quote from: Gryzor on 19:35, 20 October 20
Sounds great! Perhaps a wiki article would be better suited, but whatever people want 😁
Actually you're correct, wiki would be better, will take longer so will do that at the weekend.
Thanks!
6128 for the win!!!

Gryzor

No problem :) If you need any help let me know :)

fgbrain

QuoteIt is really weird, for the Amiga( my second machine ) most of the optimization info/tricks are freely available but not in the CPC world?


About vertical pixel perfect hw scrolling,  Pict from Logon System did an article in A 100% back in May 1993.
Can be found now at: https://cpcrulez.fr/coding_logon48-scroll_vertical.htm

_____

6128 (UK keyboard, Crtc type 0/2), 6128+ (UK keyboard), 3.5" and 5.25" drives, Reset switch and Digiblaster (selfmade), Inicron Romram box, Bryce Megaflash, SVideo & PS/2 mouse, , Magnum Lightgun, X-MEM, X4 Board, C4CPC, Multiface2 X4, RTC X4 and Gotek USB Floppy emulator.

lmimmfn

Quote from: fgbrain on 18:16, 21 October 20


About vertical pixel perfect hw scrolling,  Pict from Logon System did an article in A 100% back in May 1993.

Can be found now at: https://cpcrulez.fr/coding_logon48-scroll_vertical.htm


Thanks, i did read this before and article is great but running the logon 48 demo, it wouldnt work unless playing with vsynch in WinApe, but when i update the wiki ill add this also.
6128 for the win!!!

TotO

Congratulation for the first place! 8)
"You make one mistake in your life and the internet will never let you live it down" (Keith Goodyer)

rexbeng

Quote from: TotO on 13:24, 25 October 20
Congratulation for the first place! 8)
Thanks, but it proved to be not much of a competition after all. Still it was nice that more people than the usual got at least a glimpse of what the CPC can do.
We are so sorry that you dont find the game very pleasant to play though!  ;D

TotO

Quote from: rexbeng on 22:05, 25 October 20
Thanks, but it proved to be not much of a competition after all. Still it was nice that more people than the usual got at least a glimpse of what the CPC can do.
We are so sorry that you dont find the game very pleasant to play though!  ;D
OK. So, congratulation to have won the attention of peoples around the CPC.
And don't worry, may be I will prefer the final release... ;D
"You make one mistake in your life and the internet will never let you live it down" (Keith Goodyer)

rexbeng


Gryzor

Well first place is first place, and the title is really good on its own, so... congratulations :)

Axelay


Axel

Was there ever a full version of this? It looks so elegant.



rexbeng


Powered by SMFPacks Menu Editor Mod