-snes_ppu: Converted OAM code from bsnes ppu-fast, nw

This commit is contained in:
MooglyGuy 2019-11-14 00:29:29 +01:00
parent 6018a48cc2
commit 4c53d5611d
4 changed files with 351 additions and 633 deletions

File diff suppressed because it is too large Load Diff

View File

@ -61,8 +61,9 @@ public:
bool screen_disabled() const { return bool(m_screen_disabled); } bool screen_disabled() const { return bool(m_screen_disabled); }
uint8_t last_visible_line() const { return m_beam.last_visible_line; } uint8_t last_visible_line() const { return m_beam.last_visible_line; }
uint16_t current_vert() const { return m_beam.current_vert; } uint16_t current_vert() const { return m_beam.current_vert; }
uint8_t saved_oam_address_low() const { return m_oam.saved_address_low; }
uint8_t saved_oam_address_high() const { return m_oam.saved_address_high; } void oam_address_reset();
void oam_set_first_object();
void clear_time_range_over() { m_stat77 &= 0x3f; } void clear_time_range_over() { m_stat77 &= 0x3f; }
void toggle_field() { m_stat78 ^= 0x80; } void toggle_field() { m_stat78 ^= 0x80; }
@ -70,10 +71,9 @@ public:
{ {
m_htmult = 1; m_htmult = 1;
m_interlace = 1; m_interlace = 1;
m_obj_interlace = 1; m_oam.interlace = 0;
} }
void set_current_vert(uint16_t value); void set_current_vert(uint16_t value);
void set_first_sprite() { m_oam.first_sprite = m_oam.priority_rotation ? ((m_oam.address >> 1) & 127) : 0; }
protected: protected:
/* offset-per-tile modes */ /* offset-per-tile modes */
@ -146,20 +146,17 @@ protected:
struct struct
{ {
uint8_t address_low;
uint8_t address_high;
uint8_t saved_address_low;
uint8_t saved_address_high;
uint16_t address; uint16_t address;
uint16_t priority_rotation; uint16_t base_address;
uint16_t next_charmap; uint8_t priority_rotation;
uint8_t next_size; uint16_t tile_data_address;
uint8_t size; uint8_t name_select;
uint32_t next_name_select; uint8_t base_size;
uint32_t name_select; uint8_t first;
uint8_t first_sprite;
uint8_t flip;
uint16_t write_latch; uint16_t write_latch;
uint8_t data_latch;
uint8_t interlace;
uint8_t priority[4];
} m_oam; } m_oam;
struct struct
@ -187,27 +184,6 @@ protected:
uint8_t extbg; uint8_t extbg;
} m_mode7; } m_mode7;
struct OAM
{
uint16_t tile;
int16_t x, y;
uint8_t size, vflip, hflip, priority_bits, pal;
uint8_t nameselect;
int height, width;
};
struct OAM m_oam_spritelist[SNES_SCR_WIDTH / 2];
uint8_t m_oam_itemlist[32];
struct TILELIST {
int16_t x;
uint16_t priority, pal, tileaddr;
int hflip;
};
struct TILELIST m_oam_tilelist[34];
#if SNES_LAYER_DEBUG #if SNES_LAYER_DEBUG
struct DEBUGOPTS struct DEBUGOPTS
{ {
@ -217,7 +193,6 @@ protected:
uint8_t windows_disabled; uint8_t windows_disabled;
uint8_t mosaic_disabled; uint8_t mosaic_disabled;
uint8_t colormath_disabled; uint8_t colormath_disabled;
uint8_t sprite_reversed;
uint8_t select_pri[5]; uint8_t select_pri[5];
}; };
struct DEBUGOPTS m_debug_options; struct DEBUGOPTS m_debug_options;
@ -240,12 +215,8 @@ protected:
uint16_t m_mosaic_table[16][4096]; uint16_t m_mosaic_table[16][4096];
uint8_t m_clipmasks[6][SNES_SCR_WIDTH]; uint8_t m_clipmasks[6][SNES_SCR_WIDTH];
uint8_t m_update_windows;
uint8_t m_update_offsets;
uint8_t m_update_oam_list;
uint8_t m_mode; uint8_t m_mode;
uint8_t m_interlace; //doubles the visible resolution uint8_t m_interlace; //doubles the visible resolution
uint8_t m_obj_interlace;
uint8_t m_screen_brightness; uint8_t m_screen_brightness;
uint8_t m_screen_disabled; uint8_t m_screen_disabled;
uint8_t m_pseudo_hires; uint8_t m_pseudo_hires;
@ -265,17 +236,42 @@ protected:
uint16_t m_vram_read_buffer; uint16_t m_vram_read_buffer;
uint16_t m_vmadd; uint16_t m_vmadd;
inline uint16_t get_bgcolor(uint8_t direct_colors, uint16_t palette, uint8_t color); struct object_item
inline void set_scanline_pixel(int screen, int16_t x, uint16_t color, uint8_t priority, uint8_t layer, int blend); {
inline void draw_oamtile(uint32_t tileaddr, int16_t tile_x, uint8_t priority, uint8_t flip, uint16_t pal, uint8_t *palbuf, uint8_t *pribuf); bool valid;
uint8_t index;
uint8_t width;
uint8_t height;
};
struct object_tile
{
bool valid;
uint16_t x;
uint8_t y;
uint8_t pri;
uint8_t pal;
uint8_t hflip;
uint32_t data;
};
struct object
{
uint16_t x;
uint8_t y;
uint8_t character;
uint8_t name_select;
uint8_t vflip;
uint8_t hflip;
uint8_t pri;
uint8_t pal;
uint8_t size;
};
inline uint32_t get_tile(uint8_t layer_idx, uint32_t hoffset, uint32_t voffset); inline uint32_t get_tile(uint8_t layer_idx, uint32_t hoffset, uint32_t voffset);
void update_line(uint16_t curline, uint8_t layer, uint8_t direct_colors); void update_line(uint16_t curline, uint8_t layer, uint8_t direct_colors);
void update_line_mode7(uint16_t curline, uint8_t layer_idx); void update_line_mode7(uint16_t curline, uint8_t layer_idx);
void update_obsel(void); void update_objects(uint16_t curline);
void oam_list_build(void);
int is_sprite_on_scanline(uint16_t curline, uint8_t sprite);
void update_objects_rto(uint16_t curline);
void update_objects(uint8_t priority_oam0, uint8_t priority_oam1, uint8_t priority_oam2, uint8_t priority_oam3);
void update_mode_0(uint16_t curline); void update_mode_0(uint16_t curline);
void update_mode_1(uint16_t curline); void update_mode_1(uint16_t curline);
void update_mode_2(uint16_t curline); void update_mode_2(uint16_t curline);
@ -298,13 +294,16 @@ protected:
void dynamic_res_change(); void dynamic_res_change();
inline uint32_t get_vram_address(); inline uint32_t get_vram_address();
DECLARE_READ8_MEMBER( oam_read ); uint8_t read_oam(uint16_t address);
DECLARE_WRITE8_MEMBER( oam_write ); void write_oam(uint16_t address, uint8_t data);
uint8_t read_object(uint16_t address);
void write_object(uint16_t address, uint8_t data);
DECLARE_READ8_MEMBER( cgram_read ); DECLARE_READ8_MEMBER( cgram_read );
DECLARE_WRITE8_MEMBER( cgram_write ); DECLARE_WRITE8_MEMBER( cgram_write );
DECLARE_READ8_MEMBER( vram_read ); DECLARE_READ8_MEMBER( vram_read );
DECLARE_WRITE8_MEMBER( vram_write ); DECLARE_WRITE8_MEMBER( vram_write );
std::unique_ptr<uint16_t[]> m_oam_ram; /* Object Attribute Memory */ object m_objects[128]; /* Object Attribute Memory (OAM) */
std::unique_ptr<uint16_t[]> m_cgram; /* Palette RAM */ std::unique_ptr<uint16_t[]> m_cgram; /* Palette RAM */
std::unique_ptr<uint8_t[]> m_vram; /* Video RAM (TODO: Should be 16-bit, but it's easier this way) */ std::unique_ptr<uint8_t[]> m_vram; /* Video RAM (TODO: Should be 16-bit, but it's easier this way) */
std::unique_ptr<std::unique_ptr<uint16_t[]>[]> m_light_table; /* Luma ramp */ std::unique_ptr<std::unique_ptr<uint16_t[]>[]> m_light_table; /* Luma ramp */

View File

@ -1080,9 +1080,7 @@ static INPUT_PORTS_START( snes )
PORT_CONFSETTING( 0x20, "OAM1 only" ) PORT_CONFSETTING( 0x20, "OAM1 only" )
PORT_CONFSETTING( 0x30, "OAM2 only" ) PORT_CONFSETTING( 0x30, "OAM2 only" )
PORT_CONFSETTING( 0x40, "OAM3 only" ) PORT_CONFSETTING( 0x40, "OAM3 only" )
PORT_CONFNAME( 0x80, 0x00, "Draw sprite in reverse order" ) PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNUSED )
PORT_CONFSETTING( 0x00, DEF_STR( Off ) )
PORT_CONFSETTING( 0x80, DEF_STR( On ) )
PORT_START("DEBUG4") PORT_START("DEBUG4")
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle Mode 0 draw") PORT_TOGGLE PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Toggle Mode 0 draw") PORT_TOGGLE

View File

@ -102,15 +102,8 @@ TIMER_CALLBACK_MEMBER(snes_state::snes_hirq_tick_callback)
TIMER_CALLBACK_MEMBER(snes_state::snes_reset_oam_address) TIMER_CALLBACK_MEMBER(snes_state::snes_reset_oam_address)
{ {
// make sure we're in the 65816's context since we're messing with the OAM and stuff
address_space &space = m_maincpu->space(AS_PROGRAM);
if (!m_ppu->screen_disabled()) //Reset OAM address, byuu says it happens at H=10 if (!m_ppu->screen_disabled()) //Reset OAM address, byuu says it happens at H=10
{ m_ppu->oam_address_reset();
space.write_byte(OAMADDL, m_ppu->saved_oam_address_low()); /* Reset oam address */
space.write_byte(OAMADDH, m_ppu->saved_oam_address_high());
m_ppu->set_first_sprite();
}
} }
TIMER_CALLBACK_MEMBER(snes_state::snes_reset_hdma) TIMER_CALLBACK_MEMBER(snes_state::snes_reset_hdma)
@ -235,7 +228,7 @@ TIMER_CALLBACK_MEMBER(snes_state::snes_hblank_tick)
hdma(cpu0space); hdma(cpu0space);
if (m_screen->vpos() > 0) if (m_screen->vpos() > 0)
m_screen->update_partial((m_ppu->interlace() == 2) ? (m_ppu->current_vert() * m_ppu->interlace()) : m_ppu->current_vert()); m_screen->update_partial((m_ppu->interlace() == 2) ? (m_ppu->current_vert() * m_ppu->interlace()) : m_ppu->current_vert() - 1);
} }
// signal hblank // signal hblank