I wanna to scroll big 32bit height text, but I fail. The same image is scrolled both time with a char vertical offset.
/**
* hScroll 0-80
*/
void monter(unsigned int c,u16 hScroll) {
unsigned int l;
u8* plot_column;
for (l=0;l<8;l++) {
plot_column=(u8 *)(0x4000 + l*0x800 + 80*c + hScroll%80);
*plot_column=*plot_column+0X33;
plot_column=plot_column-1;
*plot_column=*plot_column+0X33;
}
}
u8 interruptCounter=0;
interruptHander() {
interruptCounter++;
if (interruptCounter==6) {interruptCounter=0;}
if (interruptCounter==3) {
calque4000(); // screen 4000.
hOffset=(hOffset+1)%80;
if (hOffset/40==0) {
monter(4,hOffset);
else {
monter(3,hOffset);
}
cpct_setVideoMemoryOffset(hOffset%40);
}
}
[attach=1]
On http://cpctech.cpcwiki.de/source/hardmess.asm (http://cpctech.cpcwiki.de/source/hardmess.asm) that runs with WinAPE assembler (call &2000)
I've got 3 variables inside hardmess.asm :
- screen_location : begin at &3000, increment, filter and &33FF, eat by CRTC R12/R13
- screen_plot_address : begin at &C000+80-2, increment two times, filter and &C7FF
- scroll_address : table of font pointer
I'll give a try later.
Still in progress...
void wait_frame_flyback() {
__asm
ld b,#0xf5 ;wait frame flyback
l1: in a,(c)
rra
jr nc,l1
__endasm;
}
void crtc(u16 R12R13) {
__asm
push ix
ld ix,#0
add ix,sp
ld h, 5 (ix)
ld l, 4 (ix)
ld bc,#0xbc00+12
out (c),c
inc b
out (c),h
dec b
inc c
out (c),c
inc b
out (c),l
pop ix
__endasm;
}
u8* screen_location=0x1000;
u8* screen_plot_address=0x4000+80-2;
void main(void) {
int s=0;
u8* p;
while (1) {
wait_frame_flyback();
screen_location++;
screen_location=((unsigned int)screen_location) & 0x13FF;
crtc((u16)screen_location);
screen_plot_address++;
screen_plot_address++;
screen_plot_address=((unsigned int)screen_plot_address) & 0x47FF;
p = cpct_getScreenPtr(screen_plot_address, 0,0);
s=(s+1)%32;
// 32 char of 2x8
cpct_drawSprite(g_tile_schtroumpf4x32_tileset[s], p, G_TILE_SCHTROUMPF4X32_00_W, G_TILE_SCHTROUMPF4X32_00_H);
}
}
Does stop at (no crash) :
...
Interesting.
Can you please post your project folder?
Quote from: ervin on 13:43, 23 December 20
Interesting.
Can you please post your project folder?
https://github.com/renaudhelias/CPCtelera-schtroumpfs (https://github.com/renaudhelias/CPCtelera-schtroumpfs) (trunk)
ASM cpctech https://github.com/renaudhelias/CPCtelera-schtroumpfs/blob/main/hardmess.asm (https://github.com/renaudhelias/CPCtelera-schtroumpfs/blob/main/hardmess.asm) personalized in &4000 runing ok (call &0138)
I'm very sorry, I don't know what is wrong.
:(
Quotesrc/main.c:264: warning 154: converting integral to pointer without a cast from type 'const-int literal'
Perhaps this way (int<=>unsigned int)
Was just a problem of variable init :
void wait_frame_flyback() {
__asm
ld b,#0xf5 ;wait frame flyback
l1: in a,(c)
rra
jr nc,l1
__endasm;
}
void crtc(u16 R12R13) {
__asm
push ix
ld ix,#0
add ix,sp
ld h, 5 (ix)
ld l, 4 (ix)
ld bc,#0xbc00+12
out (c),c
inc b
out (c),h
dec b
inc c
out (c),c
inc b
out (c),l
pop ix
__endasm;
}
u8* screen_location; //=0x1000;
u8* screen_plot_address; //=0x4000+80-2;
void main(void) {
int s=0;
u8* p;
screen_location=0x1000;
screen_plot_address=0x4000+80-2;
while (1) {
wait_frame_flyback();
screen_location++;
screen_location=((unsigned int)screen_location) & 0x13FF;
crtc((u16)screen_location);
screen_plot_address++;
screen_plot_address++;
screen_plot_address=((unsigned int)screen_plot_address) & 0x47FF;
p = cpct_getScreenPtr(screen_plot_address, 0,0);
s=(s+1)%32;
// 32 char of 2x8
cpct_drawSprite(g_tile_schtroumpf4x32_tileset[s], p, G_TILE_SCHTROUMPF4X32_00_W, G_TILE_SCHTROUMPF4X32_00_H);
}
}
That run fine now (with CPCtelera sprite 2x32 !)
https://github.com/renaudhelias/CPCtelera-schtroumpfs/releases/tag/CPCtelera-schtroumpfs_v0.2
[attach=1]
rupture+scrolling 32bit height CPCtelera.
https://github.com/renaudhelias/CPCtelera-schtroumpfs/releases/tag/CPCtelera-schtroumpfs_v0.3
[attach=1]
Merry Christmas - schtroumpf ;)
https://www.pouet.net/prod.php?which=87628 (https://www.pouet.net/prod.php?which=87628)
Quoterun"launch
Based on http://cpctech.cpcwiki.de/source/hardmess.asm (http://cpctech.cpcwiki.de/source/hardmess.asm) using CPCtelera sprites
3 ruptures (C000,8000,C000)
scroll in &8000 because the program is too big with char set. I regret that I'm not using 3 ruptures C000,8000,4000.
music in &C000 bank7.
[attach=1,msg195938]
I've got glitch on some char after a long message display.
I miss something from http://cpctech.cpcwiki.de/source/hardmess.asm (http://cpctech.cpcwiki.de/source/hardmess.asm) :picard:
[attach=1,msg195942]
[attach=2,msg195942]
My source just displaying &8000 area (like on the screenshots), same problem with &4000.
https://github.com/renaudhelias/CPCtelera-schtroumpfs/tree/main/hellorenaud/src (https://github.com/renaudhelias/CPCtelera-schtroumpfs/tree/main/hellorenaud/src)
I hacked the bug but using "space chars", my text is sized 128 (step%128), the bug in this case is on last chars (at fix offset)
https://github.com/renaudhelias/CPCtelera-schtroumpfs (https://github.com/renaudhelias/CPCtelera-schtroumpfs)
https://github.com/renaudhelias/CPCtelera-schtroumpfs/blob/main/hellorenaud/hellorenaud.dsk (https://github.com/renaudhelias/CPCtelera-schtroumpfs/blob/main/hellorenaud/hellorenaud.dsk)
I filled the 8000-BFFF with xFF (pink), the first scrolling has a pink line during AZERTYUIOPQSDFG message, the second scrolling time has a white line during AZERTYUIOPQSDFG message
[attach=1,msg196002]
I try my own draw function :
void draw(u8* image, u8* plot, u8 width, u8 height) {
u8 x;
u8 y;
u8* cur_plot;
u8* cur_image;
for (y=0;y<height;y++) {
for (x=0;x<width;x++) {
cur_plot=plot+0x4000+ ((y / 8u) * 80u) + ((y % 8u) * 2048u) + x;
//cur_image=image+y*width+x;
//cur_plot=((u16)cur_plot) & 0x7FFF;
*cur_plot=0x0F;//*cur_image;
}
}
}
I've got my bug :
[attach=1,msg196077]
That's running :
void draw(u8* image, u8* plot, u8 width, u8 height) {
u8 x;
u8 y;
u8* cur_plot;
u8* cur_image;
for (y=0;y<height;y++) {
for (x=0;x<width;x++) {
cur_plot=plot+0x4000+ ((y / 8u) * 80u) + ((y % 8u) * 2048u) + x;
if (cur_plot<0x4000) {
cur_plot=cur_plot-0x4000;
}
//cur_image=image+y*width+x;
*cur_plot=0x0F;//*cur_image;
}
}
}
[attach=2,msg196077]
But with chars it still bug (no more pink line, but still white lines) :
[attach=3,msg196077]
I try to modulo while strange things happen :
void draw(u8* image, u8* plot, u8 width, u8 height) {
u8 x;
u8 y;
u8* cur_plot;
u8* cur_image;
for (y=0;y<height;y++) {
for (x=0;x<width;x++) {
cur_plot=plot+ 0x4000 +((y / 8u) * 80u) + ((y % 8u) * 2048u) + x;
cur_image=image+y*width+x;
if (cur_plot<0x4000) {
cur_plot=cur_plot-0x4000;
cur_image=image+((y+1)%height)*width+x;
}
*cur_plot=*cur_image;
}
}
}
Still not correct but here I saw some time two lines per character, and when it happens (two line only), this lines seems interchangeables :
[attach=4,msg196077]
void draw(u8* image, u8* plot, u8 width, u8 height) {
u8 x;
u8 y;
u8* cur_plot;
u8* cur_image;
for (y=0;y<height;y++) {
for (x=0;x<width;x++) {
cur_plot=plot+ 0x4000 +((y / 8u) * 80u) + ((y % 8u) * 2048u) + x;
if (cur_plot<0x4000) {
cur_plot=cur_plot-0x4000;
cur_image=image+((y+1)%height)*width+x;
*cur_plot=0xF0;
} else {
cur_image=image+y*width+x;
*cur_plot=*cur_image;
}
}
}
}
Using this code, lines appears in red ! (0xF0)
[attach=1]
A cursory glance at your calculations suggest you're assuming that all the bytes on a line will be contiguous. But if you hardware scroll the screen this won't necessarily be true, simply adding X to get further along the line doesn't work for the character row that includes the wrap-around
Quote from: andycadley on 11:26, 30 December 20A cursory glance at your calculations suggest you're assuming that all the bytes on a line will be contiguous. But if you hardware scroll the screen this won't necessarily be true, simply adding X to get further along the line doesn't work for the character row that includes the wrap-around
So I need to isolate the complete 1st, 2nd and 3nd char-row that includes the wrap-around and try a mod 8 on then ?
http://cpctech.cpcwiki.de/source/hardmess.asm is simple, I think you can compensate the *plot offset.
I succeed in compensation but it is very slow (for loop instead of using standard sprite function)
I think that I have to reverse about one screen back, in order to put the sprite correctly using cpct_drawTileAligned2x8_f() function.
Is there a method for reversing one screen offset back ? ::)
void draw_char(u8 c, u8* image, u8* plot) {
...
// that last_plot test work fine
last_plot=plot+ 0x4000 +80u*c+ 0x3801;
if (last_plot<0x4000) {
// that test for detecting a char outside of screen don't work. But as last_plot do work, I use last_plot.
//if (plot-0x8000>640*200/8 ) {
// 0xFFCF : last value of a screen snapshot, don't work also
//if (plot+0x4000>0xFFCF || plot+0x4000<0x4000) {
// minus one screen (rewind) - DON'T WORK, that is what I want to correct here...
//(0xC000 + ((nY / 8u) * 80u) + ((nY % 8u) * 2048u) + nX)
//(0xC000 + ((640 / 8u) * 80u) + ((640 % 8u) * 2048u) + 200)
// (640 / 8u) * 80u == 0x1900
// 640*200/8 == 0x3E80
//cur_plot = plot - 640*200/8;
cur_plot = plot - 0x4000 + 80u*c;
// so then don't work
p = cpct_getScreenPtr(cur_plot+0x4000, 0,8*c);
cpct_drawTileAligned2x8_f((u8*)image+(2* 8 ) *c, p);
// all that work fine (hacking (without screen rewind), but slowly
// for (y=0;y<8;y++) {
// for (x=0;x<2;x++) {
// cur_plot=plot+ 0x4000 +80u*c+ ((y % 8u) * 2048u) + x;
// cur_image=image+(c*8+((y+1)%8 ))*2+x;
// if (cur_plot<0x4000) {
// cur_plot=cur_plot-0x4000;
// }
// *cur_plot=*cur_image;
// }
// }
} else {
// no problem by here
p = cpct_getScreenPtr(plot+0x4000, 0,8*c);
cpct_drawTileAligned2x8_f((u8*)image+(2* 8 )*c, p);
}
Two plot counters, of same size, with a fix offset ? One per screen...
https://github.com/renaudhelias/CPCtelera-schtroumpfs/blob/CPCtelera-schtroumpfs_v0.6/hellorenaud/hellorenaud.dsk (https://github.com/renaudhelias/CPCtelera-schtroumpfs/blob/CPCtelera-schtroumpfs_v0.6/hellorenaud/hellorenaud.dsk)
It runs 8)
[attach=1,msg196215]
https://github.com/renaudhelias/CPCtelera-schtroumpfs/blob/main/hellorenaud/src/txt_scroll_hard.c (https://github.com/renaudhelias/CPCtelera-schtroumpfs/blob/main/hellorenaud/src/txt_scroll_hard.c)
I used finally 1 addons screen counter, and several char counters.
https://www.youtube.com/watch?v=GtMpdsgGsFo
the horizontal scrolling with the cpc is always an impure display that does not give a clean picture in the game.
you can't reach the atari800 and the c64 with this scroll.
greeting