cscg22-gearboy

CSCG 2022 Challenge 'Gearboy'
git clone https://git.sinitax.com/sinitax/cscg22-gearboy
Log | Files | Refs | sfeed.txt

text_scroller.c (2979B)


      1#include <gbdk/platform.h>
      2#include <stdint.h>
      3#include <stdio.h>
      4
      5const uint8_t scanline_offsets_tbl[] = {0, 1, 2, 3, 3, 2, 1, 0, 0, 1, 2, 3, 3, 2, 1, 0};
      6const uint8_t * scanline_offsets = scanline_offsets_tbl;
      7
      8#define SCROLL_POS 15
      9#define SCROLL_POS_PIX_START ((SCROLL_POS + DEVICE_SCREEN_Y_OFFSET) * 8) - 1
     10#define SCROLL_POS_PIX_END ((SCROLL_POS + DEVICE_SCREEN_X_OFFSET + 1) * 8) - 1
     11
     12uint8_t scroller_x = 0;
     13void scanline_isr() {
     14#if defined(NINTENDO)
     15    switch (LYC_REG) {
     16        case 0: 
     17            SCX_REG = 0;
     18            LYC_REG = SCROLL_POS_PIX_START;
     19            break;
     20        case SCROLL_POS_PIX_START:
     21            SCX_REG = scroller_x;
     22            LYC_REG = SCROLL_POS_PIX_END;
     23            break;
     24        case SCROLL_POS_PIX_END:
     25            SCX_REG = LYC_REG = 0;
     26            break;
     27    }
     28#elif defined(SEGA)
     29    if (VCOUNTER == (SCROLL_POS_PIX_START - 8)) {
     30        while (VCOUNTER != SCROLL_POS_PIX_START);
     31        VDP_CMD = -scroller_x; VDP_CMD = VDP_RSCX;
     32        while (VCOUNTER != SCROLL_POS_PIX_START + 8);
     33    } else {
     34        VDP_CMD = 0; VDP_CMD = VDP_RSCX;
     35    }
     36#endif
     37}
     38
     39const uint8_t scroller_text[] = "This is a text scroller demo for GBDK-2020. You can use ideas, that are "\
     40"shown in this demo, to make different parallax effects, scrolling of tilemaps which are larger than 32x32 "\
     41"tiles and TEXT SCROLLERS, of course! Need to write something else to make this text longer than 256 characters. "\
     42"The quick red fox jumps over the lazy brown dog. 0123456789.          ";
     43
     44const uint8_t * scroller_next_char = scroller_text;
     45uint8_t * scroller_vram_addr;
     46uint8_t * base, * limit;
     47
     48void main() {
     49    printf(" Scrolling %d chars", sizeof(scroller_text) - 1);
     50
     51    CRITICAL {
     52        add_LCD(scanline_isr);
     53#if defined(NINTENDO)
     54        STAT_REG |= STATF_LYC; LYC_REG = 0;
     55#endif
     56    }
     57#if defined(SEGA)
     58    __WRITE_VDP_REG(VDP_R10, 0x07);
     59#endif
     60    set_interrupts(VBL_IFLAG | LCD_IFLAG);
     61    
     62    HIDE_LEFT_COLUMN;    
     63    base = (uint8_t *)((uint16_t)get_bkg_xy_addr(0, SCROLL_POS) & (DEVICE_SCREEN_MAP_ENTRY_SIZE==1?0xffe0:0xffc0));
     64    limit = base + (DEVICE_SCREEN_BUFFER_WIDTH * DEVICE_SCREEN_MAP_ENTRY_SIZE);
     65
     66    scroller_vram_addr = base + ((DEVICE_SCREEN_X_OFFSET + DEVICE_SCREEN_WIDTH) * DEVICE_SCREEN_MAP_ENTRY_SIZE);
     67    if (scroller_vram_addr >= limit) scroller_vram_addr = base;
     68    
     69    set_vram_byte(scroller_vram_addr, *scroller_next_char - 0x20);
     70    
     71    while (1) {
     72        scroller_x++;
     73        if ((scroller_x & 0x07) == 0) {
     74            // next letter
     75            scroller_next_char++;
     76            if (*scroller_next_char == 0) scroller_next_char = scroller_text;
     77            
     78            // next vram position
     79            scroller_vram_addr += DEVICE_SCREEN_MAP_ENTRY_SIZE;
     80            if (scroller_vram_addr >= limit) scroller_vram_addr = base;
     81            
     82            // put next char
     83            set_vram_byte(scroller_vram_addr, *scroller_next_char - 0x20);
     84        }
     85        wait_vbl_done();        
     86    }
     87}