CPCWiki forum

General Category => Programming => Topic started by: Typhon on 22:12, 23 November 23

Title: Flicker with CPCTelera - how to avoid?
Post by: Typhon on 22:12, 23 November 23
So me again, with another question.

I'm working on a remake of the old arcade game Nibbler for my first CPCTelera project. All well and good so far, and I'm using the CPC port from 1984 by Mosaik Software (https://www.cpc-power.com/index.php?page=detail&num=2476) as a basis:

(https://i.ibb.co/pWNdkKd/Screenshot-2023-11-23-20-44-20.png)

I'm using Rasters, all is fine, however, I notice the demo mode, where the snake moves around the screen by itself is, unlike the BASIC version (!), very flickery.

A video of this can be seen here (https://drive.google.com/file/d/1t_aw4xLE7vF3PWYyupCq_TJee24ksKTI/view?usp=sharing).

Here is the main loop I run:

                            cpct_setBlendMode(CPCT_BLEND_XOR);
             _demo_draw_snake(&demo_snake);
             while (!kp) {
                ++count;
               
                // Alternate the Demo Text
                if (count == 15001)
                        _demo_draw_text(2);
                else if (count == 30001)
                        _demo_draw_text(1);
                // Animate the Snake
                if (count % 200 == 0) {
                        // Copy the old snake
                        util_copy_snake(&demo_snake, &demo_snake_buf);
                        // Update the snake
                        g_do_snake_move(demo_pf, &demo_snake, 26);
                        // Check for a keypress
                        cpct_scanKeyboard();
                        kp = cpct_isAnyKeyPressed();
                        cpct_waitVSYNC();
                        _demo_draw_snake(&demo_snake_buf);
                        _demo_draw_snake(&demo_snake);

                }

                if (count > 30002)
                        count = 0;             
}
   

And this is my draw code for the snake itself:

void _demo_draw_snake(snake_t *snake) {
        u8 *p_head_pos, *p_body_pos;
        u8 cx, cy, pf_x = 0, pf_y = 17;
        // Draw the Body
        for (u8 seg_idx = 1; seg_idx < snake->length; seg_idx++) {
               
                cx = (snake->body[seg_idx].x + pf_x) * VIDEO_CHAR_M1_BYTES_W;
                cy = (snake->body[seg_idx].y + pf_y) * VIDEO_CHAR_M1_BYTES_H;
                p_body_pos = v_screen_p(cx, cy);
                cpct_drawSpriteBlended(p_body_pos, VIDEO_CHAR_M1_BYTES_H,
                        VIDEO_CHAR_M1_BYTES_W, sprite_tileset[4]);
        }
        // And draw the Head
        cx = (snake->body[0].x + pf_x) * VIDEO_CHAR_M1_BYTES_W;
        cy = (snake->body[0].y + pf_y) * VIDEO_CHAR_M1_BYTES_H;
        p_head_pos = v_screen_p(cx, cy);
        cpct_drawSpriteBlended(p_head_pos, VIDEO_CHAR_M1_BYTES_H,
                VIDEO_CHAR_M1_BYTES_W, sprite_tileset[snake->direction]);
}


I have noticed that anything other than a couple of draws of sprites will flicker. Do I need to change my timings, or do I need to optimise my drawing code?

I have noted that this flicker occurs regardless of using raster interrupts or not.

Code will be available on github at some point soon as soon as I have something vaguely playable btw.

Best,
T.
Title: Re: Flicker with CPCTelera - how to avoid?
Post by: Typhon on 10:58, 24 November 23
OK, so first response from the Discord confirms I'm a muppet. I was redrawing the whole snake everytime.

Which I don't need to do. I simply need to draw the new head and erase the old tail, when it moves. Or just draw the new head, and the first segment of the body, when it grows. 

Argh. That hopefully should help.
Title: Re: Flicker with CPCTelera - how to avoid?
Post by: ervin on 13:31, 24 November 23
Yes that should certainly help.
It should make it a bit faster as well.
Title: Re: Flicker with CPCTelera - how to avoid?
Post by: Typhon on 22:37, 24 November 23
It certainly did!

Thank you!
Powered by SMFPacks Menu Editor Mod