Guest User

scroller example v2

a guest
Mar 28th, 2022
332
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 20.55 KB | None | 0 0
  1. // __________________________
  2. // ██▀█▀██▀▀▀█▀▀█▀█  ▄▄▄ ▄▄  │   ▄▄▄                ▄▄      
  3. // █  ▄ █▄ ▀██▄ ▀▄█ ██   ██  │  ▀█▄  ▄▀██ ▄█▄█ ██▀▄ ██  ▄███
  4. // █  █ █▀▀ ▄█  █ █ ▀█▄█ ██▄▄│  ▄▄█▀ ▀▄██ ██ █ ██▀  ▀█▄ ▀█▄▄
  5. // ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀──────────┘                 ▀▀
  6. //  Simple scroller using 16x16 metatiles, nothing is precalulated
  7. //  
  8. //─────────────────────────────────────────────────────────────────────────────
  9.  
  10. //=============================================================================
  11. // INCLUDES
  12. //=============================================================================
  13. #include "msxgl.h"
  14.  
  15. #define USE_ASM 1
  16.  
  17. //=============================================================================
  18. // READ-ONLY DATA
  19. //=============================================================================
  20.  
  21. // Data table
  22. const unsigned char s_tiles[] =
  23. {
  24.     // nothing
  25.  
  26.     0b00000000,
  27.     0b00000000,
  28.     0b00000000,
  29.     0b00000000,
  30.     0b00000000,
  31.     0b00000000,
  32.     0b00000000,
  33.     0b00000000,
  34.  
  35.     // brick
  36.  
  37.     0b11111111,
  38.     0b00010000,
  39.     0b00010000,
  40.     0b00010000,
  41.     0b11111111,
  42.     0b00000001,
  43.     0b00000001,
  44.     0b00000001,
  45.  
  46.     //block 1
  47.    
  48.     0b01111111,
  49.     0b10111111,
  50.     0b11011111,
  51.     0b11101010,
  52.     0b11110101,
  53.     0b11101010,
  54.     0b11110101,
  55.     0b11101010,
  56.  
  57.     0b11111110,
  58.     0b11111100,
  59.     0b11111000,
  60.     0b10101000,
  61.     0b01010000,
  62.     0b10101000,
  63.     0b01010000,
  64.     0b10101000,
  65.  
  66.     0b11110101,
  67.     0b11101010,
  68.     0b11110101,
  69.     0b11101010,
  70.     0b11110101,
  71.     0b11100000,
  72.     0b11000000,
  73.     0b10000000,
  74.  
  75.     0b01010000,
  76.     0b10101000,
  77.     0b01010000,
  78.     0b10101000,
  79.     0b01010000,
  80.     0b00000100,
  81.     0b00000010,
  82.     0b00000001,    
  83.    
  84.     //block 2
  85.    
  86.     0b11111111,
  87.     0b11010101,
  88.     0b10101010,
  89.     0b11010101,
  90.     0b10101010,
  91.     0b11010101,
  92.     0b10101010,
  93.     0b11010101,
  94.    
  95.     0b10111110,
  96.     0b00110100,
  97.     0b10101010,
  98.     0b00110100,
  99.     0b10101010,
  100.     0b00000001,
  101.     0b10111110,
  102.     0b00110100,
  103.    
  104.     0b10101010,
  105.     0b11010101,
  106.     0b00101010,
  107.     0b11000101,
  108.     0b10110000,
  109.     0b11011110,
  110.     0b10101010,
  111.     0b00000001,
  112.    
  113.     0b10101010,
  114.     0b00110100,
  115.     0b01101010,
  116.     0b11010100,
  117.     0b10101010,
  118.     0b11010100,
  119.     0b10101000,
  120.     0b10000000,    
  121.    
  122.     // question mark
  123.     0b00101010,
  124.     0b00000000,
  125.     0b10100000,
  126.     0b00000101,
  127.     0b10001011,
  128.     0b00000110,
  129.     0b10001010,
  130.     0b00000110,
  131.  
  132.     0b10101010,
  133.     0b00000001,
  134.     0b00000101,
  135.     0b01000001,
  136.     0b10100001,
  137.     0b01010001,
  138.     0b00110001,
  139.     0b01010001,
  140.  
  141.     0b10000000,
  142.     0b00000001,
  143.     0b10000000,
  144.     0b00000001,
  145.     0b10000000,
  146.     0b00100000,
  147.     0b10000000,
  148.     0b11111111,
  149.  
  150.     0b11110001,
  151.     0b01000001,
  152.     0b11000001,
  153.     0b00000001,
  154.     0b11000001,
  155.     0b11000101,
  156.     0b00000001,
  157.     0b11111111,
  158.    
  159.     //castle door
  160.     0b00001100,
  161.     0b00110000,
  162.     0b01000000,
  163.     0b11000000,
  164.     0b10000000,
  165.     0b10000000,
  166.     0b00000000,
  167.     0b00000000,
  168.  
  169.     0b00110001,
  170.     0b00001101,
  171.     0b00000011,
  172.     0b00000011,
  173.     0b00000001,
  174.     0b00000001,
  175.     0b00000000,
  176.     0b00000000,
  177.  
  178.  
  179.     // turret
  180.  
  181.     0b11110000,
  182.     0b00010000,
  183.     0b00010000,
  184.     0b00010000,
  185.     0b11111111,
  186.     0b00000001,
  187.     0b00000001,
  188.     0b00000001,
  189.  
  190.     // brick
  191.  
  192.     0b00011111,
  193.     0b00010000,
  194.     0b00010000,
  195.     0b00010000,
  196.     0b11111111,
  197.     0b00000001,
  198.     0b00000001,
  199.     0b00000001,
  200.  
  201.     // stick
  202.  
  203.     0b11000000,
  204.     0b11000000,
  205.     0b11000000,
  206.     0b11000000,
  207.     0b11000000,
  208.     0b11000000,
  209.     0b11000000,
  210.     0b11000000,
  211.  
  212.     // flag
  213.     0b10101010,
  214.     0b01010101,
  215.     0b00101010,
  216.     0b00010101,
  217.     0b00001010,
  218.     0b00000101,
  219.     0b00000010,
  220.     0b00000001,
  221.  
  222.     0b10101010,
  223.     0b01111101,
  224.     0b11010110,
  225.     0b10010011,
  226.     0b10111010,
  227.     0b11101111,
  228.     0b01111110,
  229.     0b01010101,
  230.  
  231.     0b00000000,
  232.     0b00000000,
  233.     0b00000000,
  234.     0b00000000,
  235.     0b00000000,
  236.     0b00000000,
  237.     0b00000000,
  238.     0b00000000,
  239.    
  240. };
  241.  
  242. // 16x16 metatiles are made of 4 8x8 tiles
  243.  
  244. const unsigned char g_metatile[] = {
  245.     0,0,0,0,  // none
  246.     1,1,1,1,  // brick
  247.     2,3,4,5,  // block 1
  248.     6,7,8,9,  // block 2
  249.     10,11,12,13,//question mark
  250.     1,1,14,15,  // brick
  251.     16,17,1,1,  // brick
  252.     1,0,1,0,   // window 1      7  
  253.     0,1,0,1,   // window 2      8
  254.     0,18,0,18,  //stick         9
  255.     19,20,0,19, // flag
  256.  };
  257.  
  258. // list of metatiles to scroll
  259. const unsigned char s_level0[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0};
  260. const unsigned char s_level1[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,9,0,0,0,0,0,6,6,6,0,0,0,0};
  261. const unsigned char s_level2[] = {0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,4,1,4,1,0,0,0,0,0,0,2,2,0,0,0,0,9,0,0,0,0,0,7,1,8,0,0,0,0};
  262. const unsigned char s_level3[] = {0,0,0,0,0,0,0,0,0,0,0,2,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,0,9,0,0,0,0,6,6,6,6,6,0,0,0};
  263. const unsigned char s_level4[] = {0,0,0,0,0,0,0,0,0,2,0,2,0,0,2,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,0,0,0,0,9,0,0,0,0,1,1,5,1,1,0,0,0};
  264. const unsigned char s_level5[] = {0,0,0,0,0,0,0,0,0,2,0,2,0,0,2,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,0,0,0,0,2,0,0,0,0,1,1,0,1,1,0,0,0};
  265. const unsigned char s_level6[] = {3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3};
  266.  
  267. const unsigned char *s_levels[] = {s_level0, s_level1, s_level2, s_level3, s_level4, s_level5, s_level6, s_level6 };
  268.  
  269. struct SEQ
  270. {
  271.     unsigned char a, b;
  272. };
  273.  
  274. #define PATTERN_SIZE 36
  275. #define NAME_ROWS 16
  276. unsigned char g_tile_pairs_size = 0;
  277. struct SEQ tile_pairs[PATTERN_SIZE];
  278. unsigned char g_patterns[8*PATTERN_SIZE];
  279. unsigned char g_table_names[32*NAME_ROWS];
  280. unsigned char *g_p_table_names = g_table_names;
  281. unsigned char g_offset_l=0;
  282. unsigned int  g_offset_h=0;
  283.  
  284.  
  285. void set_offset(unsigned int offset)
  286. {
  287.     g_offset_h = offset / 8;
  288.  
  289. #if USE_ASM == 0
  290.     g_offset_l = (offset & 7);
  291. #else    
  292.     g_offset_l = (offset & 7)*3;
  293. #endif    
  294. }
  295.  
  296. //
  297. // This code scrolls just one tile, this function is not used in this sample but I left it here as a reference as it might help understand more code below
  298. //
  299. void scroll_single_tile(unsigned char p1, unsigned char p2, unsigned char  dest)  __sdcccall(0)
  300. {
  301. #if USE_ASM == 0
  302.     unsigned char offset1 = g_offset_l;    
  303.     unsigned char offset2 = 8-g_offset_l;    
  304.     unsigned char *pchar1 =  s_tiles + p1*8;    
  305.     unsigned char *pchar2 =  s_tiles + p2*8;
  306.     unsigned char *dptr   =  g_patterns + dest*8;  
  307.  
  308.     *dptr++ = (*pchar1++ << offset1) | (*pchar2++ >> offset2);
  309.     *dptr++ = (*pchar1++ << offset1) | (*pchar2++ >> offset2);
  310.     *dptr++ = (*pchar1++ << offset1) | (*pchar2++ >> offset2);
  311.     *dptr++ = (*pchar1++ << offset1) | (*pchar2++ >> offset2);
  312.     *dptr++ = (*pchar1++ << offset1) | (*pchar2++ >> offset2);
  313.     *dptr++ = (*pchar1++ << offset1) | (*pchar2++ >> offset2);
  314.     *dptr++ = (*pchar1++ << offset1) | (*pchar2++ >> offset2);
  315.     *dptr++ = (*pchar1++ << offset1) | (*pchar2++ >> offset2);  
  316. #else
  317.   __asm    
  318.     .macro scroll_SHIFT amount
  319.         .rept 8            
  320.             ld a,(de)
  321.             inc de
  322.  
  323.             push de
  324.            
  325.             .rept amount
  326.             sla a
  327.             .endm  
  328.            
  329.             ld d,a
  330.  
  331.             ld a,(bc)    
  332.             inc bc
  333.            
  334.             .rept 8 - amount
  335.             srl a
  336.             .endm  
  337.            
  338.             or d
  339.            
  340.             pop de
  341.            
  342.             ld (hl),a    
  343.             inc hl
  344.         .endm  
  345.     .endm  
  346.  
  347.     push    ix
  348.     ld      ix, #0
  349.     add     ix, sp
  350.  
  351.     ;---------------------------------
  352.  
  353.     ; _s_tiles + p1*8  //TODO: Use 16 bit math as otherwise corruption happens when there are more than 32 scrolling tiles
  354.     ld a, 4(IX)
  355.     sla a
  356.     sla a    
  357.     sla a
  358.  
  359.     ld de,#_s_tiles    
  360.  
  361.     add a,e
  362.     ld e,a
  363.     adc a,d
  364.     sub e
  365.     ld d,a    
  366.  
  367.     ;---------------------------------
  368.  
  369.     ; _s_tiles + p2*8  //TODO: same as above
  370.     ld a, 5(IX)
  371.     sla a
  372.     sla a    
  373.     sla a
  374.  
  375.     ld bc,#_s_tiles    
  376.  
  377.     add a,c
  378.     ld c,a
  379.     adc a,b
  380.     sub c
  381.     ld b,a    
  382.  
  383.    
  384.     ;---------------------------------
  385.    
  386.     ; g_patterns + dest*8    //TODO: same as above
  387.     ld a, 6(IX)
  388.     sla a
  389.     sla a    
  390.     sla a
  391.  
  392.     ld hl,#_g_patterns
  393.  
  394.     add a,l
  395.     ld l,a
  396.     adc a,h
  397.     sub l
  398.     ld h,a  
  399.  
  400.     ; jump table ---------------------------
  401.      
  402.     push hl
  403.    
  404.     ld hl, #scroll_nexty
  405.    
  406.     ld a, (#_g_offset_l)
  407.    
  408.     add a,l
  409.     ld l,a
  410.     adc a,h
  411.     sub l
  412.     ld h,a      
  413.    
  414.     jp (hl)
  415.  
  416. scroll_nexty:    
  417.     jp scroll_shift_0
  418.     jp scroll_shift_1
  419.     jp scroll_shift_2
  420.     jp scroll_shift_3
  421.     jp scroll_shift_4
  422.     jp scroll_shift_5
  423.     jp scroll_shift_6
  424.     jp scroll_shift_7
  425. scroll_shift_0:
  426.     pop hl
  427.     scroll_SHIFT 0
  428.     jp done
  429. scroll_shift_1:
  430.     pop hl
  431.     scroll_SHIFT 1
  432.     jp done
  433. scroll_shift_2:
  434.     pop hl
  435.     scroll_SHIFT 2
  436.     jp done
  437. scroll_shift_3:
  438.     pop hl
  439.     scroll_SHIFT 3
  440.     jp done
  441. scroll_shift_4:
  442.     pop hl
  443.     scroll_SHIFT 4
  444.     jp done
  445. scroll_shift_5:
  446.     pop hl
  447.     scroll_SHIFT 5
  448.     jp done
  449. scroll_shift_6:
  450.     pop hl
  451.     scroll_SHIFT 6
  452.     jp done
  453. scroll_shift_7:
  454.     pop hl
  455.     scroll_SHIFT 7
  456.     jp done    
  457. scroll_done:    
  458.     pop ix    
  459.   __endasm;
  460. #endif
  461. }
  462.  
  463.  
  464. // 98h
  465. #define P_VDP_0         0x98            ///< Primary MSX port for VDP port #0
  466. #define P_VDP_DATA      P_VDP_0         ///< VRAM data port (read/write)
  467.  
  468. // 99h
  469. #define P_VDP_1         0x99            ///< Primary MSX port for VDP port #1
  470. #define P_VDP_REG       P_VDP_1         ///< Register setup port (write) (bit 7=1 in second write)
  471. #define P_VDP_ADDR      P_VDP_1         ///< VRAM address port (write) (bit 7=0 in second write, bit 6: read/write access (0=read, 1=write))
  472.  
  473. #define F_VDP_WRIT  0x40
  474.  
  475. void VDP_set_vram_dest_16K(u16 dest) __sdcccall(1)
  476. {
  477.     dest;
  478.  
  479.     __asm                
  480.         // Setup address register
  481.         ld      a, l
  482.         di //~~~~~~~~~~~~~~~~~~~~~~~~~~
  483.         out     (P_VDP_ADDR), a         // RegPort = (dest & 0xFF)
  484.         ld      a, h
  485.         and     a, #0x3F
  486.         add     a, #F_VDP_WRIT
  487.         ei //~~~~~~~~~~~~~~~~~~~~~~~~~~
  488.         out     (P_VDP_ADDR), a         // RegPort = ((dest >> 8) & 0x3F) + F_VDP_WRIT
  489.     __endasm;
  490. }
  491.  
  492. void VDP_write_16K(u8 count, const u8* src) __sdcccall(1)
  493. {
  494.     src, count;
  495.     __asm
  496.         //exit if count is 0
  497.         or a
  498.         jr z, vdp_write_wrt16_exit_loop
  499.         ld      b, a                // count
  500.        
  501.         ld      c, #P_VDP_DATA       
  502.         ex      de, hl
  503.        
  504.         // Fast loop           
  505.     write_wrt16_loop_start:
  506.         outi                            // out(c) ; hl++ ; b--
  507.         jp      nz, write_wrt16_loop_start
  508.        
  509. vdp_write_wrt16_exit_loop:
  510.  
  511.     __endasm;
  512. }
  513.  
  514.  
  515. void VDP_write_block_16K(const u8* src, u8 count) __sdcccall(1)
  516. {
  517.     src, count;
  518.     __asm
  519.         ld      c, #P_VDP_DATA       
  520.  
  521.         //exit if count is 0
  522.         or a
  523.         jr z, vdp_exit_loop
  524.        
  525.         // Fast loop   
  526.         ld      b, a                // count
  527.     write_block_wrt16_loop_start:
  528.         .rept 8            
  529.         outi                            // out(c) ; hl++ ; b--
  530.         .endm
  531.         jp      nz, write_block_wrt16_loop_start
  532.        
  533. vdp_exit_loop:
  534.  
  535.     __endasm;
  536. }
  537.  
  538.  
  539.  
  540. void begin_frame()
  541. {
  542.     g_tile_pairs_size = 0;
  543. }
  544.  
  545. void track_tile_pairs(unsigned char a, unsigned char b) __sdcccall(1)
  546. {
  547. #if USE_ASM == 0
  548.     // check if we have alerady computed that pattern
  549.     // TODO: remove tiles that are not present in the screen, that reduces the number of tiles to scroll
  550.     unsigned char i=0;
  551.     for(;i<g_tile_pairs_size;i++)
  552.     {
  553.         if ((a==tile_pairs[i].a) && (b==tile_pairs[i].b))
  554.         {            
  555.             g_p_table_names[o]=i+1;
  556.             return;
  557.         }
  558.     }
  559.  
  560.     tile_pairs[i].a=a;
  561.     tile_pairs[i].b=b;
  562.    
  563.     g_tile_pairs_size++;
  564.    
  565.     g_p_table_names[o]=i+1;                
  566. #else
  567.     __asm
  568.     ld d, a           ; a
  569.     ld e, l           ; b
  570.     ld hl, #_tile_pairs
  571.    
  572.     xor a
  573.     ld c,a
  574.  
  575.     ld a, (#_g_tile_pairs_size)
  576.     or a
  577.     jr z,notfound
  578.  
  579.     ld b,a    
  580. loopa11:    
  581.     ld a,(hl)
  582.     inc hl
  583.     cp d
  584.     jr nz, nope1
  585.    
  586.     ld a,(hl)
  587.     cp e
  588.     jr z, foundit    
  589.  
  590. nope1:
  591.     inc hl
  592.     inc c
  593.     djnz loopa11
  594. ;------------------------------------
  595.  
  596.     ; store a,b
  597. notfound:    
  598.     ld (hl),d
  599.     inc hl
  600.     ld (hl),e    
  601.    
  602.     inc c
  603.     ld hl, #_g_tile_pairs_size
  604.     ld (hl),c
  605.     dec c
  606.    
  607. foundit:    
  608.  
  609.     ; g_table_names[o]=i+1;    
  610.        
  611.     ld hl, (#_g_p_table_names)
  612.  
  613.     inc c
  614.     ld (hl),c    
  615.  
  616.     __endasm;  
  617. #endif    
  618. }
  619.    
  620.  
  621. void scroll_patterns()
  622. {
  623. #if USE_ASM == 0
  624.     for(unsigned char i=0;i<g_tile_pairs_size;i++)
  625.     {
  626.         scroll_single_tile(tile_pairs[i].a, tile_pairs[i].b, i);
  627.     }
  628. #else
  629.     __asm
  630.  
  631.     ;----------------------------------------------------
  632.     ; scrolls horizontally a 8x8 tile by a certain amount
  633.     ; tiles input: de, bc
  634.     ; scrolled output:   hl
  635.     ; amount: macro parameter
  636.     ;----------------------------------------------------
  637.     .macro SHIFT amount
  638.         .rept 8            
  639.             ld a,(de)
  640.             inc de
  641.             push de
  642.                 .rept amount
  643.                 sla a
  644.                 .endm  
  645.                
  646.                 ld d,a
  647.  
  648.                 ld a, (bc)    
  649.                 inc bc
  650.                
  651.                 .rept 8 - amount
  652.                 srl a
  653.                 .endm  
  654.                
  655.                 or d
  656.            
  657.                 ld (hl), a    
  658.                 inc hl
  659.             pop de
  660.         .endm  
  661.     .endm  
  662.  
  663.     ;----------------------------------------------------
  664.     ; scrolls horizontally a 8x8 tile
  665.     ; tiles input: de, bc
  666.     ; scrolled output:   hl
  667.     ; amount: _g_offset
  668.     ;----------------------------------------------------
  669.     .macro JUMP_TABLE
  670.     push hl
  671.  
  672.     ld hl, #nexty
  673.    
  674.     ld a, (#_g_offset_l)
  675.  
  676.     add a,l
  677.     ld l,a
  678.     adc a,h
  679.     sub l
  680.     ld h,a      
  681.    
  682.     jp (hl)
  683.  
  684. nexty:    
  685.     jp shift_0
  686.     jp shift_1
  687.     jp shift_2
  688.     jp shift_3
  689.     jp shift_4
  690.     jp shift_5
  691.     jp shift_6
  692.     jp shift_7
  693. shift_0:
  694.     pop hl
  695.     SHIFT 0
  696.     jp done
  697. shift_1:
  698.     pop hl
  699.     SHIFT 1
  700.     jp done
  701. shift_2:
  702.     pop hl
  703.     SHIFT 2
  704.     jp done
  705. shift_3:
  706.     pop hl
  707.     SHIFT 3
  708.     jp done
  709. shift_4:
  710.     pop hl
  711.     SHIFT 4
  712.     jp done
  713. shift_5:
  714.     pop hl
  715.     SHIFT 5
  716.     jp done
  717. shift_6:
  718.     pop hl
  719.     SHIFT 6
  720.     jp done
  721. shift_7:
  722.     pop hl
  723.     SHIFT 7
  724.     jp done        
  725. done:      
  726.     .endm  
  727.    
  728.     ; -----------------------------------------------
  729.     ; loop for all the tile pairs in the table struct
  730.     ; -----------------------------------------------
  731.     ld a, (#_g_tile_pairs_size)
  732.     ld b,a    
  733.     xor a
  734.     ld c,a
  735.     ld hl, #_tile_pairs
  736. loopa1:
  737.     push bc
  738.  
  739.     ld a,c
  740.     push af
  741.        
  742.     ;-------------------- p1: de = _s_tiles[tile_pairs[i].a*8];   //TODO: Use 16 bit math as otherwise corruption happens when there are more than 32 scrolling tiles
  743.     ld a, (hl)
  744.     inc hl
  745.     sla a
  746.     sla a    
  747.     sla a
  748.    
  749.     ld de,#_s_tiles    
  750.    
  751.     add a,e
  752.     ld e,a
  753.     adc a,d
  754.     sub e
  755.     ld d,a  
  756.  
  757.     ;-------------------- p2:  bc = _s_tiles[tile_pairs[i].b*8]; i++  //TODO: Use 16 bit math as otherwise corruption happens when there are more than 32 scrolling tiles
  758.     ld a, (hl)
  759.     inc hl
  760.     sla a
  761.     sla a    
  762.     sla a
  763.    
  764.     ld bc,#_s_tiles    
  765.    
  766.     add a,c
  767.     ld c,a
  768.     adc a,b
  769.     sub c
  770.     ld b,a      
  771.  
  772.     ;--------------------- dest: bc = g_patterns + (i*8)    //TODO: Use 16 bit math as otherwise corruption happens when there are more than 32 scrolling tiles
  773.     pop af    ; get i
  774.    
  775.     ; g_patterns + dest*8
  776.     sla a
  777.     sla a    
  778.     sla a
  779.  
  780.     push hl  
  781.  
  782.     ld hl,#_g_patterns
  783.  
  784.     add a,l
  785.     ld l,a
  786.     adc a,h
  787.     sub l
  788.     ld h,a            
  789.    
  790.     JUMP_TABLE    
  791.  
  792.     pop hl
  793.    
  794.     ;-----------------------------------------------
  795.     pop bc
  796.     inc c
  797.     dec b
  798.     jr z, exit
  799.     jp loopa1  
  800.    
  801. exit:    
  802.     __endasm;  
  803. #endif    
  804. }
  805.  
  806.  
  807.  
  808. ////////////////////////////// 16x16 tiles
  809.  
  810. inline unsigned char get_data(const unsigned char * level, unsigned char x, unsigned char y)
  811. {
  812.     return g_metatile[4*level[x/2] + (x&1) + y];
  813. }
  814.  
  815. inline void get_meta(const unsigned char * level, unsigned char x, unsigned char y, unsigned char * a, unsigned char * b)
  816. {
  817.     *a = get_data(level, x, y);
  818.     *b = get_data(level, x + 1, y);    
  819. }
  820.  
  821. void scroll_level_meta(const unsigned char * level)
  822. {
  823.     for(unsigned char y=0;y<2;y++)
  824.     {
  825.         for(unsigned char o=0;o<32;o++)
  826.         {
  827.             unsigned char a,b;
  828.             get_meta(level, o + g_offset_h, y*2, &a, &b);
  829.             track_tile_pairs(a, b);
  830.             g_p_table_names++;
  831.         }
  832.     }        
  833. }
  834.  
  835. //#define SAFE_SCROLL //safe but super slow, just there as a reference
  836.  
  837. void update_vram_names()
  838. {
  839.     VDP_set_vram_dest_16K(g_ScreenLayoutLow+32*6); //starts drawing at y=6 to center vertically things a bit
  840.     u8 *dest = g_table_names;
  841.     for (u8 i = 0; i< NAME_ROWS;i++)
  842.     {  
  843.         #ifdef SAFE_SCROLL
  844.         VDP_write_block_16K(dest, 32);
  845.         #else
  846.         unsigned char n = ((u8)g_offset_h) & 31;
  847.         VDP_write_16K(32-n, dest + n);
  848.         VDP_write_16K(n   , dest + 0);
  849.         #endif
  850.         dest+=32;
  851.     }
  852. }
  853.  
  854. void update_vram_patterns()
  855. {
  856.     VDP_set_vram_dest_16K(g_ScreenPatternLow + 8);
  857.     VDP_write_block_16K(g_patterns, g_tile_pairs_size*8);    
  858. }
  859.  
  860. void update_all_frame()
  861. {
  862.     begin_frame();
  863.  
  864.     g_p_table_names = g_table_names;
  865.     for (u8 i = 0; i< NAME_ROWS/2;i++)
  866.     {      
  867.         scroll_level_meta(s_levels[i]);
  868.     }
  869.     scroll_patterns();      
  870.  
  871.     Halt();
  872.  
  873.     update_vram_names();
  874.     update_vram_patterns();
  875. }
  876.  
  877. void update_right_column()
  878. {    
  879.     #ifdef SAFE_SCROLL
  880.     g_p_table_names = g_table_names + 31;    
  881.     #else
  882.     g_p_table_names = g_table_names + ((((u8)g_offset_h)+31)&31);    
  883.     #endif
  884.  
  885.     for(unsigned int y=0;y<NAME_ROWS;y++)
  886.     {
  887.         #ifdef SAFE_SCROLL
  888.         unsigned char *p = g_table_names + y*32;
  889.         for(unsigned char x=0;x<32-1;x++)
  890.             p[x] = p[x+1];        
  891.         #endif
  892.        
  893.         unsigned char a,b;
  894.         get_meta(s_levels[y/2], g_offset_h + 31, (y&1)*2, &a, &b);
  895.        
  896.         track_tile_pairs(a, b);        
  897.         g_p_table_names+=32;
  898.     }        
  899. }
  900.  
  901. void update_left_column()
  902. {    
  903.     #ifdef SAFE_SCROLL
  904.     g_p_table_names = g_table_names + 0;    
  905.     #else
  906.     g_p_table_names = g_table_names + ((((u8)g_offset_h)+0)&31);    
  907.     #endif
  908.  
  909.     for(unsigned int y=0;y<NAME_ROWS;y++)
  910.     {
  911.         #ifdef SAFE_SCROLL    
  912.         unsigned char *p = g_table_names + y*32;
  913.         for(signed char x=31;x>0;x--)
  914.             p[x] = p[x-1];        
  915.         #endif
  916.        
  917.         unsigned char a,b;
  918.         get_meta(s_levels[y/2], g_offset_h, (y&1)*2, &a, &b);
  919.                
  920.         track_tile_pairs(a, b);        
  921.         g_p_table_names+=32;
  922.     }        
  923. }
  924.  
  925.  
  926. //=============================================================================
  927. // MAIN LOOP
  928. //=============================================================================
  929. #include "font\font_mgl_std0.h"
  930.  
  931. //-----------------------------------------------------------------------------
  932. /// Program entry point
  933. void main()
  934. {
  935.     VDP_SetMode(VDP_MODE_GRAPHIC2);
  936.    
  937.     VDP_SetColor(0xF0);
  938.     VDP_FillVRAM(0x00, 0x0000, 0, 256*64); // Clear 16KB VRAM
  939.     VDP_EnableVBlank(true);
  940.  
  941.     // use just 1 tiles set for all the screen
  942.     VDP_RegWrite(3, 0x9f); g_ScreenColorLow    = 0x2000;
  943.     VDP_RegWrite(4, 0x00);
  944.    
  945.     Print_SetTextFont(g_Font_MGL_Std0, 1);
  946.        
  947.     unsigned int offset = 0;
  948.     signed char offset8 = 0;
  949.  
  950.     set_offset(offset);
  951.     update_all_frame();
  952.  
  953.     while(1)
  954.     {        
  955.         if(Keyboard_IsKeyPressed(KEY_RIGHT) && offset<512+72)
  956.         {
  957.             offset+=1;
  958.             set_offset(offset);          
  959.             offset8++;
  960.             if (offset8>7)
  961.             {
  962.                 offset8=0;
  963.                 update_right_column();
  964.             }
  965.         }
  966.        
  967.         if(Keyboard_IsKeyPressed(KEY_LEFT) && offset>0)
  968.         {
  969.             offset-=1;
  970.             set_offset(offset);          
  971.             offset8--;
  972.             if (offset8<0)
  973.             {
  974.                 offset8=7;
  975.                 update_left_column();
  976.             }
  977.         }
  978.        
  979.         scroll_patterns();      
  980.         Halt();
  981.         update_vram_patterns();
  982.         update_vram_names();    
  983.    }
  984. }
  985.  
  986.  
Advertisement
Add Comment
Please, Sign In to add comment