OSDN Git Service

show sprite developed.
authorastoria-d <astoria-d@mail.goo.ne.jp>
Tue, 26 Mar 2013 08:35:48 +0000 (17:35 +0900)
committerastoria-d <astoria-d@mail.goo.ne.jp>
Tue, 26 Mar 2013 08:35:48 +0000 (17:35 +0900)
emulator/ppu.c
emulator/ppucore/Makefile
emulator/ppucore/ppucore.c
emulator/ppucore/sprite.c [new file with mode: 0644]
emulator/ppucore/sprite.h
emulator/ppucore/vram.c
emulator/ppucore/vram.h
emulator/ppucore/vscreen.c

index c519299..3952a19 100644 (file)
@@ -46,8 +46,8 @@ static ppu_write_t *ppucore_write_func[8] = {
     ppu_ctrl1_set,
     ppu_ctrl2_set,
     null_write,
-    sprite_data_set,
     sprite_addr_set,
+    sprite_data_set,
     ppu_scroll_set,
     ppu_vram_addr_set,
     ppu_vram_data_set
index fdeb341..bb0a0aa 100644 (file)
@@ -5,7 +5,7 @@ TEST_BIN=dummy-driver2
 DUMMY_OBJS=dummy-driver2.o debug.o cartridge.o 
 
 OBJS=ppucore.o vram.o vscreen.o palette.o \
-        vga_xfer.o
+        vga_xfer.o sprite.o
         
 LIBS=-L../../libs -L./ -lmotones -pthread -lrt -lppucore
 
index d7202cd..230e903 100644 (file)
@@ -7,6 +7,7 @@
 #include "vram.h"
 #include "ppucore.h"
 #include "vga_xfer.h"
+#include "sprite.h"
 
 int vscreen_init(void);
 void clean_vscreen(void);
@@ -17,6 +18,8 @@ void set_nmi_pin(int val);
 void set_bg_pattern_bank(unsigned char bank);
 void set_spr_pattern_bank(unsigned char bank);
 void set_bg_name_tbl_base(unsigned char sw);
+void spr_ram_tbl_set(unsigned short offset, unsigned char data);
+int show_sprite(int foreground);
 
 
 void dump_ppu_reg(void);
@@ -70,18 +73,23 @@ struct ppu_vram_addr_reg {
     unsigned int cnt :1;
 };
 
+struct ppu_scroll_reg {
+    unsigned char x;
+    unsigned char y;
+    unsigned int cnt :1;
+};
 /*ppu core register instances*/
 
 static struct ppu_ctrl_reg1 ctrl_reg1;
 static struct ppu_ctrl_reg2 ctrl_reg2;
 static struct ppu_status_reg status_reg;
 static struct ppu_vram_addr_reg vram_addr_reg;
+static struct ppu_scroll_reg scroll_reg;
+static struct ppu_sprite_reg sprite_reg;
 
 static unsigned char sprite_ram_addr_reg;
-static unsigned char sprite_ram_data_reg;
 static unsigned char sprite_ram_dma_reg;
 static unsigned char vram_data_reg;
-static unsigned char scroll_reg;
 static unsigned char vram_dma_reg;
 
 //value set by the ctrl_reg1.
@@ -116,7 +124,7 @@ static void *ppucore_loop(void* arg) {
         clock_gettime(CLOCK_REALTIME, &begin);
         if (ctrl_reg2.show_sprite) {
             //sprite in the back
-            ;
+            show_sprite(FALSE);
         }
         if (ctrl_reg2.show_bg/**/) {
             //back ground image
@@ -124,7 +132,7 @@ static void *ppucore_loop(void* arg) {
         }
         if (ctrl_reg2.show_sprite) {
             //foreground sprite
-            ;
+            show_sprite(TRUE);
         }
         if (updated) 
             vga_xfer();
@@ -217,15 +225,39 @@ unsigned char ppu_status_get(void) {
 }
 
 void sprite_addr_set(unsigned char addr) {
+    dprint("sprite_addr_set addr=%02x\n", addr);
     sprite_ram_addr_reg = addr;
+    sprite_reg.cnt = 0;
 }
 
 void sprite_data_set(unsigned char data) {
-    sprite_ram_data_reg = data;
+    dprint("sprite_data_set addr=%02x, data=%02x, cnt:%d\n", 
+            sprite_ram_addr_reg, data, sprite_reg.cnt);
+    switch (sprite_reg.cnt) {
+        case 0:
+        default:
+            sprite_reg.y = data;
+            break;
+        case 1:
+            sprite_reg.index = data;
+            break;
+        case 2:
+            memcpy(&sprite_reg.sa, &data, sizeof(struct sprite_attr));
+            break;
+        case 3:
+            sprite_reg.x = data;
+            break;
+    }
+    spr_ram_tbl_set(sprite_ram_addr_reg + sprite_reg.cnt, data);
+    sprite_reg.cnt++;
 }
 
 void ppu_scroll_set(unsigned char data) {
-    scroll_reg = data;
+    dprint("scroll set %s = %02x\n", (scroll_reg.cnt == 0 ? "x" : "y"), data);
+    if (scroll_reg.cnt++ == 0)
+        scroll_reg.x = data;
+    else
+        scroll_reg.y = data;
 }
 
 void ppu_vram_addr_set(unsigned char half_addr) {
@@ -274,12 +306,12 @@ int ppucore_init(void) {
     memset(&ctrl_reg2, 0,  sizeof(ctrl_reg1));
     memset(&status_reg, 0, sizeof(status_reg));
     memset(&vram_addr_reg, 0, sizeof(vram_addr_reg));
+    memset(&scroll_reg, 0, sizeof(scroll_reg));
+    memset(&sprite_reg, 0, sizeof(sprite_reg));
 
     sprite_ram_addr_reg = 0;
-    sprite_ram_data_reg = 0;
     sprite_ram_dma_reg = 0;
     vram_data_reg = 0;
-    scroll_reg = 0;
     vram_dma_reg = 0;
     vram_read_cnt = 0;
 
@@ -290,6 +322,10 @@ int ppucore_init(void) {
     if (!ret)
         return FALSE;
 
+    ret = sprite_init();
+    if (!ret)
+        return FALSE;
+
     ret = vscreen_init();
     if (!ret)
         return FALSE;
@@ -324,6 +360,7 @@ void clean_ppucore(void) {
     dprint("ppucore thread joined.\n");
 
     clean_vram();
+    clean_sprite();
     clean_vscreen();
 }
 
diff --git a/emulator/ppucore/sprite.c b/emulator/ppucore/sprite.c
new file mode 100644 (file)
index 0000000..3f16147
--- /dev/null
@@ -0,0 +1,42 @@
+#include <stdlib.h>
+#include <string.h>
+
+#include "tools.h"
+#include "vga.h"
+#include "vram.h"
+#include "ppucore.h"
+#include "sprite.h"
+
+void palette_index_to_rgb15(unsigned char index, struct rgb15* rgb);
+
+
+static unsigned char * sprite_ram;
+
+void spr_ram_tbl_set(unsigned short offset, unsigned char data) {
+    sprite_ram[offset & SPR_RAM_ADDR_MASK] = data;
+}
+
+void spr_ram_data_get(unsigned char index, unsigned char *x, unsigned char *y, 
+        unsigned char *tile_id, struct sprite_attr *sa) {
+    //index is multiple of 4.
+    index *= 4;
+    index &= SPR_RAM_ADDR_MASK;
+
+    *y = sprite_ram[index++];
+    *tile_id = sprite_ram[index++];
+    memcpy(sa, sprite_ram + index++, sizeof(struct sprite_attr));
+    *x = sprite_ram[index++];
+}
+
+int sprite_init(void) {
+    sprite_ram = malloc(SPRITE_RAM_SIZE);
+    if (sprite_ram == NULL)
+        return FALSE;
+    memset(sprite_ram, 0, SPRITE_RAM_SIZE);
+    return TRUE;
+}
+
+void clean_sprite(void) {
+    free(sprite_ram);
+}
+
index 1cbad24..2effa6d 100644 (file)
@@ -14,5 +14,20 @@ struct sprite_attr {
     unsigned int flip_v     :1;
 } __attribute__ ((packed));
 
+struct ppu_sprite_reg {
+    unsigned char y;
+    unsigned char index;
+    struct sprite_attr sa;
+    unsigned char x;
+    unsigned int cnt        :2;
+};
+
+#define SPRITE_RAM_SIZE         0x100
+#define SPRITE_CNT              (SPRITE_RAM_SIZE / 4)
+#define SPR_RAM_ADDR_MASK       (SPRITE_RAM_SIZE - 1)
+
+int sprite_init(void);
+void clean_sprite(void);
+
 #endif /*__sprite_h__*/
 
index 2c44717..634d75c 100644 (file)
@@ -15,7 +15,6 @@ void dump_mem(const char* msg, unsigned short base,
 void set_bgtile(int tile_id);
 
 /*vram definition*/
-static unsigned char * sprite_ram;
 
 static unsigned char * bg_palette_tbl;
 static unsigned char * spr_palette_tbl;
@@ -117,15 +116,6 @@ static void bg_palette_tbl_set(unsigned short offset, unsigned char data) {
     bg_palette_tbl[offset] = data;
 }
 
-
-static unsigned char spr_ram_tbl_get(unsigned short offset) {
-    return sprite_ram[offset];
-}
-
-static void spr_ram_tbl_set(unsigned short offset, unsigned char data) {
-    sprite_ram[offset] = data;
-}
-
 void vram_data_set(unsigned short addr, unsigned char data) {
 #ifdef PPU_TEST
     if (!first_time)
@@ -322,23 +312,6 @@ static void test_ppu(void) {
 }
 #endif /* PPU_TEST */
 
-int show_background(void) {
-    int i;
-
-#ifdef PPU_TEST
-    if (1 /*first_time*/) {
-        test_ppu();
-        first_time = FALSE;
-    }
-    return TRUE;
-#endif /*PPU_TEST */
-
-    for (i = 0; i < H_SCREEN_TILE_SIZE * V_SCREEN_TILE_SIZE; i++) {
-        set_bgtile(i);
-    }
-    return TRUE;
-}
-
 static int attr_index_to_gp(int tile_index) {
     int tile_x, tile_y, gp_x, gp_y;
 
@@ -486,10 +459,6 @@ int vram_init(void) {
     if (pattern_tbl1 == NULL)
         return FALSE;
 
-    sprite_ram = malloc(SPRITE_RAM_SIZE);
-    if (sprite_ram == NULL)
-        return FALSE;
-
     name_tbl0 = malloc(NAME_TBL_SIZE);
     if (name_tbl0 == NULL)
         return FALSE;
@@ -522,7 +491,6 @@ int vram_init(void) {
 
     memset(pattern_tbl0, 0, PATTERN_TBL_SIZE);
     memset(pattern_tbl1, 0, PATTERN_TBL_SIZE);
-    memset(sprite_ram, 0, SPRITE_RAM_SIZE);
     memset(name_tbl0, 0, NAME_TBL_SIZE);
     memset(name_tbl1, 0, NAME_TBL_SIZE);
     memset(attr_tbl0, 0, ATTR_TBL_SIZE);
@@ -540,8 +508,6 @@ void clean_vram(void) {
     free(pattern_tbl0);
     free(pattern_tbl1);
 
-    free(sprite_ram);
-
     free(name_tbl0);
     free(name_tbl1);
 
index babb5bd..7d9800b 100644 (file)
@@ -80,12 +80,10 @@ struct palette_unit {
 #define ATTR_TBL_SIZE       (VIRT_SCREEN_TILE_SIZE * VIRT_SCREEN_TILE_SIZE \
                             / ATTR_GROUP_UNIT / ATTR_UNIT_PER_BYTE)
 #define PALETTE_TBL_SIZE    0x10
-#define SPRITE_RAM_SIZE     0xff
 
 #define PATTERN_ADDR_MASK       (PATTERN_TBL_SIZE - 1)
 #define ATTR_TBL_ADDR_MASK      (ATTR_TBL_SIZE - 1)
 #define PALETTE_TBL_ADDR_MASK   (PALETTE_TBL_SIZE - 1)
-#define SPR_RAM_ADDR_MASK       (SPRITE_RAM_SIZE - 1)
 
 #define PPU_ADDR_MASK       (0x4000 - 1)
 #define PALETTE_START       0x3F00
index f95e37b..58e82c6 100644 (file)
@@ -11,6 +11,8 @@
 void load_attribute(unsigned char bank, int tile_index, struct palette *plt);
 void load_pattern(unsigned char bank, unsigned char ptn_index, struct tile_2* pattern);
 void load_spr_attribute(struct sprite_attr sa, struct palette *plt);
+void spr_ram_data_get(unsigned char index, unsigned char *x, unsigned char *y, 
+        unsigned char *tile_id, struct sprite_attr *sa);
 
 struct tile_rgb15_line {
     struct rgb15 d[8];
@@ -101,17 +103,28 @@ void set_bgtile(int tile_id) {
                 set_data->l[i].d[7 - j] = plt.col[pi];
             }
             else {
-                //TODO
-                //for the time being, transparent bg color is black..
+                //TODO for the time being, transparent bg color is black..
+                /*
                 set_data->l[i].d[7 - j].r = 0;
                 set_data->l[i].d[7 - j].g = 0;
                 set_data->l[i].d[7 - j].b = 0;
+                */
             }
         }
     }
 
 }
 
+int show_background(void) {
+    int i;
+
+    for (i = 0; i < H_SCREEN_TILE_SIZE * V_SCREEN_TILE_SIZE; i++) {
+        set_bgtile(i);
+    }
+    return TRUE;
+}
+
+
 void set_sprite(int x, int y, int tile_id, struct sprite_attr sa) {
     struct palette plt;
     struct tile_2 ptn;
@@ -158,6 +171,29 @@ void set_sprite(int x, int y, int tile_id, struct sprite_attr sa) {
     }
 }
 
+int show_sprite(int foreground) {
+    int i;
+    struct sprite_attr sa;
+    unsigned char x, y, tile;
+
+    if (foreground) {
+        for (i = 0; i < SPRITE_CNT; i++) {
+            spr_ram_data_get(i, &x, &y, &tile, &sa);
+            if (sa.priority)
+                set_sprite(x, y, tile, sa);
+        }
+    }
+    else {
+        for (i = 0; i < SPRITE_CNT; i++) {
+            spr_ram_data_get(i, &x, &y, &tile, &sa);
+            if (!sa.priority)
+                set_sprite(x, y, tile, sa);
+        }
+    }
+    return TRUE;
+}
+
+
 void set_bg_pattern_bank(unsigned char bank) {
     bg_pattern_bank = bank;
 }