megadrive_test2
changeset 5:ea70f3da150f
color cycling tunnel
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Tue, 20 Jun 2017 06:08:58 +0300 |
parents | 72ab63f262bf |
children | df2c6b3c6f2e |
files | .hgignore Makefile src/intr.s src/main.c src/vdp.c src/vdp.h tools/ppm2md.c tools/tunnel.c |
diffstat | 8 files changed, 212 insertions(+), 82 deletions(-) [+] |
line diff
1.1 --- a/.hgignore Mon Jun 19 08:02:51 2017 +0300 1.2 +++ b/.hgignore Tue Jun 20 06:08:58 2017 +0300 1.3 @@ -4,3 +4,7 @@ 1.4 \.map$ 1.5 \.elf$ 1.6 \.bin$ 1.7 +tools/ppm2md$ 1.8 +tools/tunnel$ 1.9 +\.ppm$ 1.10 +tun_data\.h$
2.1 --- a/Makefile Mon Jun 19 08:02:51 2017 +0300 2.2 +++ b/Makefile Tue Jun 20 06:08:58 2017 +0300 2.3 @@ -9,8 +9,9 @@ 2.4 2.5 warn = -pedantic -Wall 2.6 dbg = -g 2.7 +opt = -O2 2.8 def = -DGAMENAME=\"testgame\" -DVERSTR=\"01\" -D__NO_CTYPE 2.9 -inc = -Isrc -Isrc/libc 2.10 +inc = -I. -Isrc -Isrc/libc 2.11 2.12 tool_prefix = m68k-linux-gnu- 2.13 2.14 @@ -28,12 +29,18 @@ 2.15 $(bin): $(elf) 2.16 $(OBJCOPY) -O binary $< $@ 2.17 2.18 -$(elf): $(obj) 2.19 +$(elf): tun_data.h $(obj) 2.20 $(LD) -o $@ $(obj) -Map link.map $(LDFLAGS) 2.21 2.22 +tun_data.h: tunnel.ppm 2.23 + cat $< | tools/ppm2md tun_ >$@ 2.24 + 2.25 +tunnel.ppm: 2.26 + tools/tunnel >$@ 2.27 + 2.28 .PHONY: clean 2.29 clean: 2.30 - rm -f $(obj) $(elf) $(bin) 2.31 + rm -f $(obj) $(elf) $(bin) tun_data.h tunnel.ppm 2.32 2.33 .PHONY: run 2.34 run: $(bin)
3.1 --- a/src/intr.s Mon Jun 19 08:02:51 2017 +0300 3.2 +++ b/src/intr.s Tue Jun 20 06:08:58 2017 +0300 3.3 @@ -102,5 +102,5 @@ 3.4 rte 3.5 3.6 intr_vblank: 3.7 - |jsr vblank_handler 3.8 + jsr vblank_handler 3.9 rte
4.1 --- a/src/main.c Mon Jun 19 08:02:51 2017 +0300 4.2 +++ b/src/main.c Tue Jun 20 06:08:58 2017 +0300 4.3 @@ -1,41 +1,29 @@ 4.4 #include <stdint.h> 4.5 #include "vdp.h" 4.6 +#include "tun_data.h" 4.7 4.8 -uint32_t pat0[] = { 4.9 - 0x00000000, 4.10 - 0x00000000, 4.11 - 0x00000000, 4.12 - 0x00010000, 4.13 - 0x00000000, 4.14 - 0x00000000, 4.15 - 0x00000000, 4.16 - 0x00000000 4.17 +#define NAMETAB_A 6 4.18 +#define NAMETAB_B 6 4.19 + 4.20 +void load_pattern(int idx, void *data); 4.21 +void set_tile(int nametab_idx, int x, int y, int tile_idx, int palidx); 4.22 + 4.23 +#define CYCLE_BEG 1 4.24 +#define CYCLE_END 14 4.25 +static uint16_t pal[16] = { 4.26 + VDP_PACK_RGB(0, 0, 0), /* 0: fixed */ 4.27 + VDP_PACK_RGB(0, 0, 0), /* 1: cycle start */ 4.28 + VDP_PACK_RGB(0, 0, 0), VDP_PACK_RGB(0, 0, 0), 4.29 + VDP_PACK_RGB(0, 0, 0), VDP_PACK_RGB(0, 0, 0), 4.30 + VDP_PACK_RGB(0, 0, 0), VDP_PACK_RGB(0, 0, 0), 4.31 + VDP_PACK_RGB(0, 0, 0), VDP_PACK_RGB(0, 0, 0), 4.32 + VDP_PACK_RGB(0, 0, 0), VDP_PACK_RGB(0, 0, 0), 4.33 + VDP_PACK_RGB(0, 0, 0), /* 12: \ */ 4.34 + VDP_PACK_RGB(7, 0, 3), /* 13: > beam */ 4.35 + VDP_PACK_RGB(0, 0, 0), /* 14: / cycle end */ 4.36 + VDP_PACK_RGB(7, 0, 3) /* 15: fixed */ 4.37 }; 4.38 4.39 -uint32_t pat1[] = { 4.40 - 0x11111111, 4.41 - 0x11000011, 4.42 - 0x10100101, 4.43 - 0x10011001, 4.44 - 0x10011001, 4.45 - 0x10100101, 4.46 - 0x11000011, 4.47 - 0x11111111 4.48 -}; 4.49 - 4.50 -uint32_t pat2[] = { 4.51 - 0x11111111, 4.52 - 0x10011001, 4.53 - 0x10011001, 4.54 - 0x11111111, 4.55 - 0x11111111, 4.56 - 0x10011001, 4.57 - 0x10011001, 4.58 - 0x11111111 4.59 -}; 4.60 - 4.61 -void load_pattern(int idx, void *data); 4.62 -void set_tile(int x, int y, int tile_idx, int palidx); 4.63 4.64 int main(void) 4.65 { 4.66 @@ -43,39 +31,35 @@ 4.67 4.68 vdp_init(); 4.69 4.70 - vdp_set_pal_entry(0, 0, 0, 0, 0); 4.71 - vdp_set_pal_entry(0, 1, 7, 1, 3); 4.72 + vdp_setreg(VDP_REG_MODE2, vdp_getreg(VDP_REG_MODE2) | VDP_MODE2_V30CELL); 4.73 + 4.74 + vdp_begin_palette(0, 0); 4.75 + for(i=0; i<16; i++) { 4.76 + VDP_PORT_DATA = pal[i]; 4.77 + } 4.78 vdp_set_bgcolor(0, 0); 4.79 4.80 - load_pattern(0, pat0); 4.81 - load_pattern(1, pat1); 4.82 - load_pattern(2, pat2); 4.83 + for(i=0; i<tun_xtiles * tun_ytiles; i++) { 4.84 + load_pattern(i, tun_tiles[i]); 4.85 + } 4.86 4.87 - vdp_set_nametab_idx(VDP_PLANE_A, 6); 4.88 + vdp_set_nametab_idx(VDP_PLANE_A, NAMETAB_A); 4.89 + vdp_set_nametab_idx(VDP_PLANE_B, NAMETAB_B); 4.90 4.91 - for(i=0; i<20; i++) { 4.92 - for(j=0; j<20; j++) { 4.93 - set_tile(j, i, 1, 0); 4.94 + for(i=0; i<tun_ytiles; i++) { 4.95 + for(j=0; j<tun_xtiles; j++) { 4.96 + set_tile(NAMETAB_A, j, i, i * tun_xtiles + j, 0); 4.97 } 4.98 } 4.99 4.100 //vdp_enable_hintr(12); 4.101 - //vdp_enable_vintr(); 4.102 + vdp_enable_vintr(); 4.103 4.104 for(;;); 4.105 4.106 return 0; 4.107 } 4.108 4.109 -/* 4.110 -uint16_t testcol = 0x00c0; 4.111 - 4.112 -void vblank_handler(void) 4.113 -{ 4.114 - testcol = 0x00c0; 4.115 -} 4.116 -*/ 4.117 - 4.118 void load_pattern(int idx, void *data) 4.119 { 4.120 int i; 4.121 @@ -88,13 +72,28 @@ 4.122 } 4.123 } 4.124 4.125 -void set_tile(int x, int y, int tile_idx, int palidx) 4.126 +void set_tile(int nametab_idx, int x, int y, int tile_idx, int palidx) 4.127 { 4.128 uint16_t tile_ent, addr; 4.129 4.130 tile_ent = vdp_nametab_entry(tile_idx, palidx, VDP_TILE_LOW_PRIO); 4.131 4.132 - addr = vdp_nametab_addr(6) + (y * 64 + x) * 2; 4.133 + addr = vdp_nametab_addr(nametab_idx) + (y * 64 + x) * 2; 4.134 vdp_setup_access(addr, VDP_MEM_WRITE, VDP_MEM_VRAM); 4.135 VDP_PORT_DATA = tile_ent; 4.136 } 4.137 + 4.138 +void vblank_handler(void) 4.139 +{ 4.140 + int idx = CYCLE_BEG; 4.141 + uint16_t first = pal[idx]; 4.142 + 4.143 + vdp_begin_palette(0, idx); 4.144 + while(idx < CYCLE_END) { 4.145 + pal[idx] = pal[idx + 1]; 4.146 + VDP_PORT_DATA = pal[idx]; 4.147 + ++idx; 4.148 + } 4.149 + pal[idx] = first; 4.150 + VDP_PORT_DATA = pal[idx]; 4.151 +}
5.1 --- a/src/vdp.c Mon Jun 19 08:02:51 2017 +0300 5.2 +++ b/src/vdp.c Tue Jun 20 06:08:58 2017 +0300 5.3 @@ -2,8 +2,31 @@ 5.4 5.5 void vdp_init(void) 5.6 { 5.7 + int i; 5.8 + 5.9 vdp_setreg(VDP_REG_MODE1, VDP_MODE1_BASE); 5.10 vdp_setreg(VDP_REG_MODE2, VDP_MODE2_BASE | VDP_MODE2_DISP); 5.11 5.12 + vdp_set_nametab_addr(VDP_PLANE_A, 0xc000); 5.13 + vdp_set_nametab_addr(VDP_PLANE_B, 0xe000); 5.14 + vdp_disable_layer(VDP_PLANE_WIN); 5.15 + vdp_set_scroll_table(0xd000); 5.16 + vdp_set_sprite_table(0xd400); 5.17 + 5.18 + vdp_setreg(VDP_REG_MODE3, VDP_MODE3_BASE); 5.19 + vdp_setreg(VDP_REG_MODE4, VDP_MODE4_BASE | VDP_MODE4_H40CELL); 5.20 + vdp_setreg(VDP_REG_SCROLL_SIZE, VDP_SCROLL_H64 | VDP_SCROLL_V32); 5.21 + 5.22 vdp_set_autoinc(2); 5.23 + vdp_set_bgcolor(0, 0); 5.24 + 5.25 + vdp_setreg(VDP_REG_HINTR, 0); 5.26 + vdp_setreg(VDP_REG_WIN_XPOS, 0); 5.27 + vdp_setreg(VDP_REG_WIN_YPOS, 0); 5.28 + 5.29 + /* clear vmem at the planes A/B name tables, scroll table, and sprite table */ 5.30 + vdp_setup_access(0xd000, VDP_MEM_WRITE, VDP_MEM_VRAM); 5.31 + for(i=0xd000; i<65536; i++) { 5.32 + VDP_PORT_DATA = 0; 5.33 + } 5.34 }
6.1 --- a/src/vdp.h Mon Jun 19 08:02:51 2017 +0300 6.2 +++ b/src/vdp.h Tue Jun 20 06:08:58 2017 +0300 6.3 @@ -157,11 +157,15 @@ 6.4 vdp_setreg(VDP_REG_AUTOINC, stride); 6.5 } 6.6 6.7 +static inline void vdp_begin_palette(int pidx, int cidx) 6.8 +{ 6.9 + uint16_t paddr = (pidx << 5) | (cidx << 1); 6.10 + vdp_setup_access(paddr, VDP_MEM_WRITE, VDP_MEM_CRAM); 6.11 +} 6.12 + 6.13 static inline void vdp_set_pal_entry(int pidx, int cidx, int r, int g, int b) 6.14 { 6.15 - uint16_t paddr = (pidx << 5) | (cidx << 1); 6.16 - 6.17 - vdp_setup_access(paddr, VDP_MEM_WRITE, VDP_MEM_CRAM); 6.18 + vdp_begin_palette(pidx, cidx); 6.19 VDP_PORT_DATA = VDP_PACK_RGB(r, g, b); 6.20 } 6.21 6.22 @@ -188,22 +192,18 @@ 6.23 6.24 static inline void vdp_set_nametab_addr(int plane, uint16_t addr) 6.25 { 6.26 - int reg; 6.27 switch(plane) { 6.28 case VDP_PLANE_A: 6.29 - reg = VDP_REG_NAMETAB_A; 6.30 + vdp_setreg(VDP_REG_NAMETAB_A, (addr >> 10) & 0x38); 6.31 break; 6.32 case VDP_PLANE_B: 6.33 - reg = VDP_REG_NAMETAB_B; 6.34 + vdp_setreg(VDP_REG_NAMETAB_B, (addr >> 13) & 7); 6.35 break; 6.36 case VDP_PLANE_WIN: 6.37 - reg = VDP_REG_NAMETAB_WIN; 6.38 + vdp_setreg(VDP_REG_NAMETAB_WIN, (addr >> 10) & 0x7e); 6.39 + default: 6.40 break; 6.41 - default: 6.42 - return; 6.43 } 6.44 - 6.45 - vdp_setreg(reg, (addr >> 10) & 0x38); 6.46 } 6.47 6.48 static inline uint16_t vdp_nametab_addr(int idx) 6.49 @@ -216,11 +216,37 @@ 6.50 vdp_set_nametab_addr(plane, vdp_nametab_addr(idx)); 6.51 } 6.52 6.53 +static inline void vdp_disable_layer(int plane) 6.54 +{ 6.55 + switch(plane) { 6.56 + case VDP_PLANE_A: 6.57 + vdp_setreg(VDP_REG_NAMETAB_A, 0x40); 6.58 + break; 6.59 + case VDP_PLANE_B: 6.60 + vdp_setreg(VDP_REG_NAMETAB_B, 0x08); 6.61 + break; 6.62 + case VDP_PLANE_WIN: 6.63 + vdp_setreg(VDP_REG_NAMETAB_WIN, 0x40); 6.64 + default: 6.65 + break; 6.66 + } 6.67 +} 6.68 + 6.69 static inline uint16_t vdp_nametab_entry(int tileidx, int palidx, uint16_t flags) 6.70 { 6.71 return tileidx | (((uint16_t)palidx & 0x3) << 13) | flags; 6.72 } 6.73 6.74 +static inline void vdp_set_sprite_table(uint16_t addr) 6.75 +{ 6.76 + vdp_setreg(VDP_REG_SPRITE_TAB, addr >> 9); 6.77 +} 6.78 + 6.79 +static inline void vdp_set_scroll_table(uint16_t addr) 6.80 +{ 6.81 + vdp_setreg(VDP_REG_SCROLL_TAB, addr >> 10); 6.82 +} 6.83 + 6.84 void vdp_init(void); 6.85 6.86 #endif /* VDP_H_ */
7.1 --- a/tools/ppm2md.c Mon Jun 19 08:02:51 2017 +0300 7.2 +++ b/tools/ppm2md.c Tue Jun 20 06:08:58 2017 +0300 7.3 @@ -3,26 +3,92 @@ 7.4 #include <string.h> 7.5 #include <ctype.h> 7.6 7.7 +#define RODATA_STR "__attribute__((section(\".rodata\")))" 7.8 + 7.9 unsigned char *read_image(int *xsz, int *ysz, int *maxval); 7.10 7.11 -int main(void) 7.12 +int main(int argc, char **argv) 7.13 { 7.14 - int i, j, width, height, maxval; 7.15 - unsigned char *pixels; 7.16 + int i, j, width, height, xtiles, ytiles, maxval; 7.17 + unsigned char *pixels, *tiles, *src, *dest; 7.18 + const char *prefix = "img_"; 7.19 + 7.20 + if(argv[1]) { 7.21 + prefix = argv[1]; 7.22 + } 7.23 7.24 if(!(pixels = read_image(&width, &height, &maxval))) { 7.25 return 1; 7.26 } 7.27 fprintf(stderr, "read image %dx%d (maxval: %d)\n", width, height, maxval); 7.28 7.29 - /* reduce colors */ 7.30 + xtiles = width / 8; 7.31 + ytiles = height / 8; 7.32 + /* each tile is 32 bytes, 8 rows of 4 bytes each */ 7.33 + if(!(tiles = malloc(xtiles * ytiles * 32))) { 7.34 + free(pixels); 7.35 + return 1; 7.36 + } 7.37 7.38 - /* slice tiles */ 7.39 - for(i=0; i<height / 8; i++) { 7.40 - for(j=0; j<width / 8; j++) { 7.41 + /* if we have 15 as max val, we'll assume they are straight palette indices 7.42 + * otherwise, do color quantization and palette allocation 7.43 + */ 7.44 + if(maxval == 15) { 7.45 + /* just drop green/blue components in-place, keep red as index */ 7.46 + dest = src = pixels; 7.47 + for(i=0; i<width * height; i++) { 7.48 + *dest++ = *src; 7.49 + src += 3; 7.50 + } 7.51 + } else { 7.52 + /* TODO */ 7.53 + } 7.54 + 7.55 + /* after processing, we have 1 color index per byte */ 7.56 + 7.57 + /* slice tiles and pack indices as nibbles */ 7.58 + dest = tiles; 7.59 + for(i=0; i<ytiles; i++) { 7.60 + for(j=0; j<xtiles; j++) { 7.61 + int x, y; 7.62 + int tilestart = (i * xtiles * 8 + j) * 8; 7.63 + 7.64 + for(y=0; y<8; y++) { 7.65 + for(x=0; x<4; x++) { 7.66 + src = pixels + tilestart + y * width + x * 2; 7.67 + *dest++ = (src[0] << 4) | (src[1] & 0xf); 7.68 + } 7.69 + } 7.70 + 7.71 } 7.72 } 7.73 7.74 + /* output as C array */ 7.75 + printf("/* generated by ppm2md */\n"); 7.76 + printf("int %sxtiles " RODATA_STR " = %d;\n", prefix, xtiles); 7.77 + printf("int %sytiles " RODATA_STR " = %d;\n", prefix, ytiles); 7.78 + printf("unsigned char %stiles[][32] " RODATA_STR " = {", prefix); 7.79 + 7.80 + src = tiles; 7.81 + for(i=0; i<xtiles * ytiles; i++) { 7.82 + if(i > 0) { 7.83 + printf(",\n"); 7.84 + } else { 7.85 + putchar('\n'); 7.86 + } 7.87 + printf("\t{"); 7.88 + for(j=0; j<32; j++) { 7.89 + if(j == 0) { 7.90 + printf("%u", (unsigned int)*src++); 7.91 + } else { 7.92 + printf(", %u", (unsigned int)*src++); 7.93 + } 7.94 + } 7.95 + printf(" }"); 7.96 + } 7.97 + printf("\n};\n"); 7.98 + 7.99 + 7.100 return 0; 7.101 } 7.102
8.1 --- a/tools/tunnel.c Mon Jun 19 08:02:51 2017 +0300 8.2 +++ b/tools/tunnel.c Tue Jun 20 06:08:58 2017 +0300 8.3 @@ -2,13 +2,14 @@ 8.4 #include <stdlib.h> 8.5 #include <math.h> 8.6 8.7 -#define XSZ 512 8.8 -#define YSZ 512 8.9 +#define XSZ 320 8.10 +#define YSZ 240 8.11 8.12 int main(void) 8.13 { 8.14 int i, j; 8.15 unsigned char *pixels, *pptr; 8.16 + float aspect = (float)XSZ / (float)YSZ; 8.17 8.18 pixels = malloc(XSZ * YSZ); 8.19 pptr = pixels; 8.20 @@ -16,15 +17,19 @@ 8.21 for(i=0; i<YSZ; i++) { 8.22 float y = 2.0 * (float)i / (float)YSZ - 1.0; 8.23 for(j=0; j<XSZ; j++) { 8.24 - float x = 2.0 * (float)j / (float)XSZ - 1.0; 8.25 + float x = aspect * (2.0 * (float)j / (float)XSZ - 1.0); 8.26 float tu = atan2(y, x) / M_PI * 0.5 + 0.5; 8.27 float d = sqrt(x * x + y * y); 8.28 - float tv = d == 0.0 ? 0.0 : 1.0 / d; 8.29 + float tv = d == 0.0 ? 0.0 : 0.5 / d; 8.30 8.31 - int ty = (int)(tv * 64.0) & 0xf; 8.32 + int ty = (int)(tv * 64.0) % 14 + 1; 8.33 int tx = (int)(tu * 256.0) & 0xf; 8.34 8.35 - *pptr++ = tx ? ty : 0; 8.36 + if(d < 0.2) { 8.37 + *pptr++ = 0; 8.38 + } else { 8.39 + *pptr++ = tx ? ty : 0xf; 8.40 + } 8.41 } 8.42 } 8.43