#include "ppucore.h"
void vscreenn_dot_get(int x, int y, struct rgb15 *col);
-struct rgb15 *get_vscreen_head(void);
+struct rgb15* get_current_vscreen(void);
#define VSCREEN_WIDTH (H_SCREEN_TILE_SIZE * TILE_DOT_SIZE)
#define VSCREEN_HEIGHT (V_SCREEN_TILE_SIZE * TILE_DOT_SIZE)
void show_leftside_bg(void) {
}
-static int vga_y;
-static int vscrn_y, vscrn_y_old;
static struct rgb15 *vga_col;
-
-void vga_xfer_old(int scanline) {
- int vscrn_x, vscrn_x_old;
- int vga_x;
- struct rgb15 *col_old;
-
- if (scanline == 0) {
- vga_y = 0;
- vscrn_y_old = -1;
- vga_col = vga_base;
- }
-
- vscrn_x_old = -1;
- col_old = vga_col;
- while (1) {
- vscrn_y = vga_y * VSCREEN_HEIGHT / VGA_HEIGHT;
- if (vscrn_y != scanline)
- break;
-
- if (vscrn_y != vscrn_y_old) {
- for (vga_x = 0; vga_x < VGA_WIDTH; vga_x++) {
- vscrn_x = vga_x * VSCREEN_WIDTH / VGA_WIDTH;
- if (vscrn_x != vscrn_x_old) {
- vscreenn_dot_get(vscrn_x, vscrn_y, vga_col);
- }
- else {
- *vga_col = *col_old;
- }
-
- vscrn_x_old = vscrn_x;
- col_old = vga_col;
- vga_col++;
- }
- }
- else {
- memcpy(vga_col, col_old, VGA_WIDTH * sizeof (struct rgb15));
- col_old = vga_col;
- vga_col += VGA_WIDTH;
- }
-
- vga_y++;
- vscrn_y_old = vscrn_y;
- }
-}
-
-static struct rgb15 *vs_col, *vs_head;
-static struct rgb15 *vga_col;
-
-void vga_posinit(void) {
- vs_head = (struct rgb15 *)get_vscreen_head();
-}
-
void vga_xfer(int vs_x, int vs_y) {
+ struct rgb15 *vs_col;
int vga_x, vga_y, vga_x_next;
struct rgb15 *vga_col_next;
//x direction scale is 640/256.
//y direction scale is 480/240
- if (vs_x == 0) {
- int tile_id, tile_id_y;
- int inner_y;
-
- tile_id_y = vs_y / TILE_DOT_SIZE;
- tile_id = tile_id_y * H_SCREEN_TILE_SIZE;
- inner_y = vs_y % TILE_DOT_SIZE;
-
- vs_col = vs_head + tile_id * TILE_DOT_SIZE * TILE_DOT_SIZE + inner_y * TILE_DOT_SIZE;
-
- vga_y = vs_y * VGA_HEIGHT / VSCREEN_HEIGHT;
+ vs_col = get_current_vscreen();
+ if (vs_col == NULL)
+ return ;
+ vga_x = vs_x * VGA_WIDTH / VSCREEN_WIDTH;
+ vga_y = vs_y * VGA_HEIGHT / VSCREEN_HEIGHT;
+ if (vs_x == 0)
vga_col = vga_base + vga_y * VGA_WIDTH;
- }
- else {
- if (vs_x % TILE_DOT_SIZE) {
- vs_col++;
- }
- else {
- vs_col += (TILE_DOT_SIZE - 1) * TILE_DOT_SIZE + 1;
- }
- }
- vga_x = vs_x * VGA_WIDTH / VSCREEN_WIDTH;
vga_x_next = (vs_x + 1) * VGA_WIDTH / VSCREEN_WIDTH;
vga_col_next = vga_col + vga_x_next - vga_x;
*(vga_col + VGA_WIDTH) = *vs_col;
vga_col++;
}
-
}
int vga_xfer_init(void) {
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 load_spr_palette(struct sprite_attr sa, struct palette *plt);
void sprite0_hit_set(void);
unsigned char spr_ram_tbl_get(unsigned short offset);
unsigned char vram_data_get(unsigned short addr);
void palette_index_to_rgb15(unsigned char index, struct rgb15* rgb);
-
#define TRANSPARENT_PALETTE_ADDR 0x3F10
-struct tile_rgb15_line {
- struct rgb15 d[8];
-};
-
-struct tile_rgb15 {
- struct tile_rgb15_line l[8];
-};
-
struct sprite_buf_reg {
struct palette plt;
struct tile_2 ptn;
int sprite_num;
};
-static struct tile_rgb15 *vscreen;
+static struct rgb15 *vscreen;
static unsigned char bg_pattern_bank;
static unsigned char spr_pattern_bank;
static unsigned short bg_name_tbl_base;
static unsigned char bg_attr_tbl_bank;
-
#define SPRITE_PREFETCH_CNT 8
static struct ppu_sprite_reg sprite_temp_buf [SPRITE_PREFETCH_CNT];
static struct sprite_buf_reg sprite_buf [SPRITE_PREFETCH_CNT];
static int sprite_hit_cnt;
static int bg_transparent;
-void vscreenn_dot_get(int x, int y, struct rgb15 *col) {
- int tile_id, tile_id_x, tile_id_y;
- int inner_x, inner_y;
- struct tile_rgb15* tile;
-
- tile_id_x = x / TILE_DOT_SIZE;
- tile_id_y = y / TILE_DOT_SIZE;
- tile_id = tile_id_x + tile_id_y * H_SCREEN_TILE_SIZE;
- tile = vscreen + tile_id;
-
- inner_x = x % TILE_DOT_SIZE;
- inner_y = y % TILE_DOT_SIZE;
- *col = tile->l[inner_y].d[inner_x];
-}
-
-void vscreenn_dot_set(int x, int y, struct rgb15 *col) {
- int tile_id, tile_id_x, tile_id_y;
- int inner_x, inner_y;
- struct tile_rgb15* tile;
-
- tile_id_x = x / TILE_DOT_SIZE;
- tile_id_y = y / TILE_DOT_SIZE;
- tile_id = tile_id_x + tile_id_y * H_SCREEN_TILE_SIZE;
- tile = vscreen + tile_id;
-
- inner_x = x % TILE_DOT_SIZE;
- inner_y = y % TILE_DOT_SIZE;
- tile->l[inner_y].d[inner_x] = *col;
-}
-
static int pal_index(struct tile_2 *ptn, int l, int dot_x) {
switch (dot_x) {
case 0:
}
}
-void set_bgtile(int tile_id) {
- struct palette plt;
- struct tile_2 ptn;
- unsigned char name_index;
- struct tile_rgb15* set_data;
- int i,j;
-
- load_attribute(bg_attr_tbl_bank, tile_id, &plt);
-
- name_index = vram_data_get(bg_name_tbl_base + tile_id);
- load_pattern(bg_pattern_bank, name_index, &ptn);
-
- set_data = vscreen + tile_id;
- for (i = 0; i < TILE_DOT_SIZE; i++) {
- //display shows left to right with high bit to low bit
- for (j = 0; j < 8; j++) {
- int pi = pal_index(&ptn, i, j);
- if (pi) {
- //dprint("%d, %d, colind:%d\n", j, i, pi);
- set_data->l[i].d[7 - j] = plt.col[pi];
- }
- else {
- //transparent bg color is read from sprite 0x10 color.
- pi = vram_data_get(TRANSPARENT_PALETTE_ADDR);
- palette_index_to_rgb15(pi, &set_data->l[i].d[7 - j]);
- /*
- 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 load_background_old(int scanline) {
- int i, start, end;
-
- //load tile must be executed every 8 scanlines only.
- if (scanline % TILE_DOT_SIZE)
- return TRUE;
-
- start = scanline / TILE_DOT_SIZE * H_SCREEN_TILE_SIZE;
- end = start + H_SCREEN_TILE_SIZE;
- for (i = start; i < end; i++) {
- set_bgtile(i);
- }
- return TRUE;
-}
-
static struct palette plt;
static struct tile_2 ptn;
-static struct tile_rgb15* set_data;
+static struct rgb15* set_data;
+
+struct rgb15* get_current_vscreen(void) {
+ return set_data;
+}
int load_background(int x, int y) {
//dprint("load bg x:%d, y:%d...\n", x, y);
int inner_x, inner_y;
+ if (x == 0 && y == 0) {
+ set_data = vscreen + x + y * H_SCREEN_TILE_SIZE * TILE_DOT_SIZE;
+ }
+ else {
+ set_data++;
+ }
//tile loading happens every 8 dots only.
if (x % TILE_DOT_SIZE == 0) {
load_attribute(bg_attr_tbl_bank, tile_id, &plt);
name_index = vram_data_get(bg_name_tbl_base + tile_id);
load_pattern(bg_pattern_bank, name_index, &ptn);
- set_data = vscreen + tile_id;
}
-
- inner_x = x % TILE_DOT_SIZE;
+ //pattern dot is stored right to left order (little endian.).
+ inner_x = 7 - x % TILE_DOT_SIZE;
inner_y = y % TILE_DOT_SIZE;
int pi = pal_index(&ptn, inner_y, inner_x);
if (pi) {
//dprint("%d, %d, colind:%d\n", j, i, pi);
- set_data->l[inner_y].d[7 - inner_x] = plt.col[pi];
+ *set_data = plt.col[pi];
bg_transparent = FALSE;
}
else {
//transparent bg color is read from sprite 0x10 color.
pi = vram_data_get(TRANSPARENT_PALETTE_ADDR);
- palette_index_to_rgb15(pi, &set_data->l[inner_y].d[7 - inner_x]);
+ palette_index_to_rgb15(pi, set_data);
bg_transparent = TRUE;
}
return TRUE;
}
-
-void set_sprite(int x, int y, int tile_id, struct sprite_attr sa) {
- struct palette plt;
- struct tile_2 ptn;
- int i, j;
-
- load_spr_attribute(sa, &plt);
-
- load_pattern(spr_pattern_bank, tile_id, &ptn);
-
- //display shows left to right with high bit to low bit
- for (i = 0; i < TILE_DOT_SIZE; i++) {
- if (sa.flip_h) {
- if (sa.flip_v) {
- for (j = 0; j < 8; j++) {
- int pi = pal_index(&ptn, i, j);
- if (pi)
- vscreenn_dot_set(x + j, y + 7 - i, &plt.col[pi]);
- }
- }
- else {
- for (j = 0; j < 8; j++) {
- int pi = pal_index(&ptn, i, j);
- if (pi)
- vscreenn_dot_set(x + j, y + i, &plt.col[pi]);
- }
- }
- }
- else {
- if (sa.flip_v) {
- for (j = 0; j < 8; j++) {
- int pi = pal_index(&ptn, i, j);
- if (pi)
- vscreenn_dot_set(x + 7 - j, y + 7 - i, &plt.col[pi]);
- }
- }
- else {
- for (j = 0; j < 8; j++) {
- int pi = pal_index(&ptn, i, j);
- if (pi)
- vscreenn_dot_set(x + 7 - j, y + i, &plt.col[pi]);
- }
- }
- }
- }
-}
-
-int load_sprite_old(int foreground, int scanline) {
- int i;
- struct sprite_attr sa;
- unsigned char x, y, tile, tmp;
-
- //sprite priority:
- //draw lowest priority first,
- //high priority late. highest priority comes top.
- for (i = SPRITE_CNT - 1; i >= 0; i--) {
- y = spr_ram_tbl_get(4 * i);
- if (scanline != y)
- continue;
-
- tmp = spr_ram_tbl_get(4 * i + 2);
- memcpy(&sa, &tmp, sizeof(struct sprite_attr));
- if (sa.priority != foreground)
- continue;
-
- tile = spr_ram_tbl_get(4 * i + 1);
- x = spr_ram_tbl_get(4 * i + 3);
-
- set_sprite(x, y, tile, sa);
- if (i == 0) {
- sprite0_hit_set();
- }
- }
-
- return TRUE;
-}
-
//prefetch sprite step 1.
//load sprite temp buffer.
int sprite_prefetch1(int srch_line) {
spr_buf_bottom = sprite_hit_cnt > SPRITE_PREFETCH_CNT ? SPRITE_PREFETCH_CNT : sprite_hit_cnt;
for (i = 0; i < spr_buf_bottom; i++) {
- load_spr_attribute(sprite_temp_buf[i].sa, &sprite_buf[i].plt);
+ load_spr_palette(sprite_temp_buf[i].sa, &sprite_buf[i].plt);
load_pattern(spr_pattern_bank, sprite_temp_buf[i].index, &sprite_buf[i].ptn);
}
return spr_buf_bottom;
}
-int load_sprite(int foreground, int x, int y) {
+int load_sprite(int background, int x, int y) {
int i;
int spr_buf_bottom;
int pi;
int x_in, y_in;
int draw_x_in, draw_y_in;
- if (sprite_temp_buf[i].sa.priority != foreground)
+ set_data->r = set_data->g = set_data->b = 0;
+
+ if (sprite_temp_buf[i].sa.priority != background)
continue;
x_in = x % TILE_DOT_SIZE;
}
}
- //dprint("spr#%d, dot set x:%d, y:%d\n", sprite_temp_buf[i].index, x, y);
pi = pal_index(&sprite_buf[i].ptn, draw_y_in, draw_x_in);
if (pi) {
- vscreenn_dot_set(x, y, &sprite_buf[i].plt.col[pi]);
+ //dprint("spr#%d, id:%d, dot set x:%d, y:%d\n",
+ // sprite_buf[i].sprite_num, sprite_temp_buf[i].index, x, y);
+ *set_data = sprite_buf[i].plt.col[pi];
if (sprite_temp_buf[i].sa.priority && sprite_buf[i].sprite_num == 0)
sprite0_hit_set();
return TRUE;
}
}
}
+ //spr_data->r = spr_data->g = spr_data->b = 0;
return FALSE;
}
bg_attr_tbl_bank = sw;
}
-struct rgb15 *get_vscreen_head(void) {
- return (struct rgb15 *)vscreen;
-}
-
int vscreen_init(void) {
bg_pattern_bank = 0;
spr_pattern_bank = 0;
sprite_hit_cnt = 0;
- vscreen = (struct tile_rgb15 *) malloc(
- sizeof (struct tile_rgb15) * VIRT_SCREEN_TILE_SIZE * VIRT_SCREEN_TILE_SIZE);
+ vscreen = (struct rgb15 *) malloc(
+ sizeof (struct rgb15) * H_SCREEN_TILE_SIZE * V_SCREEN_TILE_SIZE
+ * TILE_DOT_SIZE * TILE_DOT_SIZE);
if (vscreen == NULL)
return FALSE;
- memset(vscreen, 0, sizeof (struct tile_rgb15) * VIRT_SCREEN_TILE_SIZE * VIRT_SCREEN_TILE_SIZE);
+ memset(vscreen, 0, sizeof (struct rgb15) * H_SCREEN_TILE_SIZE * V_SCREEN_TILE_SIZE
+ * TILE_DOT_SIZE * TILE_DOT_SIZE);
+ set_data = NULL;
//dprint("tile_1_line:%d tile_2 size:%d\n", sizeof(struct tile_1_line), sizeof(struct tile_2));