Incomplete addition of shadow/highlight mode for Genesis

This commit is contained in:
transistor 2021-12-29 10:54:43 -08:00
parent 1534644409
commit 5d6af61531
2 changed files with 35 additions and 19 deletions

View File

@ -59,7 +59,7 @@ const MODE3_BF_V_SCROLL_MODE: u8 = 0x04;
const MODE3_BF_H_SCROLL_MODE: u8 = 0x03;
const MODE4_BF_H_CELL_MODE: u8 = 0x01;
//const MODE4_BF_SHADOW_HIGHLIGHT: u8 = 0x08;
const MODE4_BF_SHADOW_HIGHLIGHT: u8 = 0x08;
@ -81,6 +81,13 @@ pub enum TargetType {
Vsram,
}
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum ColourMode {
Normal,
Shadow,
Highlight,
}
pub struct Ym7101State {
pub status: u16,
pub vram: [u8; 0x10000],
@ -305,12 +312,18 @@ impl Ym7101State {
(self.mode_3 & MODE3_BF_EXTERNAL_INTERRUPT) != 0
}
pub fn get_palette_colour(&self, palette: u8, colour: u8) -> u32 {
pub fn get_palette_colour(&self, palette: u8, colour: u8, mode: ColourMode) -> u32 {
if colour == 0 {
return 0xFFFFFFFF;
}
let shift_enabled = (self.mode_4 & MODE4_BF_SHADOW_HIGHLIGHT) != 0;
let rgb = read_beu16(&self.cram[(((palette * 16) + colour) * 2) as usize..]);
(((rgb & 0xF00) as u32) >> 4) | (((rgb & 0x0F0) as u32) << 8) | (((rgb & 0x00F) as u32) << 20)
if !shift_enabled || mode == ColourMode::Normal {
(((rgb & 0xF00) as u32) >> 4) | (((rgb & 0x0F0) as u32) << 8) | (((rgb & 0x00F) as u32) << 20)
} else {
let offset = if mode == ColourMode::Highlight { 0x808080 } else { 0x00 };
(((rgb & 0xF00) as u32) >> 5) | (((rgb & 0x0F0) as u32) << 7) | (((rgb & 0x00F) as u32) << 19) | offset
}
}
pub fn get_pattern_iter<'a>(&'a self, pattern_name: u16, line: i8) -> PatternIterator<'a> {
@ -318,7 +331,8 @@ impl Ym7101State {
let pattern_palette = ((pattern_name & 0x6000) >> 13) as u8;
let h_rev = (pattern_name & 0x0800) != 0;
let v_rev = (pattern_name & 0x1000) != 0;
PatternIterator::new(&self, pattern_addr as u32, pattern_palette, h_rev, v_rev, line)
let mode = if (pattern_name & 0x8000) != 0 { ColourMode::Shadow } else { ColourMode::Normal };
PatternIterator::new(&self, pattern_addr as u32, pattern_palette, mode, h_rev, v_rev, line)
}
pub fn get_hscroll(&self, hcell: usize, line: usize) -> (u32, u32) {
@ -385,7 +399,7 @@ impl Ym7101State {
}
pub fn draw_background(&mut self, frame: &mut Frame) {
let bg_colour = self.get_palette_colour((self.background & 0x30) >> 4, self.background & 0x0f);
let bg_colour = self.get_palette_colour((self.background & 0x30) >> 4, self.background & 0x0f, ColourMode::Normal);
frame.clear(bg_colour);
}
@ -421,19 +435,14 @@ impl Ym7101State {
for cell_y in 0..cells_v {
for line in 0..8 {
let (_, hscrolling_b) = self.get_hscroll(cell_y, line as usize);
let (hscrolling_a, hscrolling_b) = self.get_hscroll(cell_y, line as usize);
for cell_x in 0..cells_h {
let (_, vscrolling_b) = self.get_vscroll(cell_x);
let pattern_b = self.get_scroll_b_pattern(cell_x, cell_y, hscrolling_b as usize, vscrolling_b as usize);
self.draw_pattern_line(frame, pattern_b, (cell_x << 3) as u32 + (hscrolling_b % 8), (cell_y << 3) as u32 + line as u32 - (vscrolling_b % 8), line);
}
}
}
for cell_y in 0..cells_v {
for line in 0..8 {
let (hscrolling_a, _) = self.get_hscroll(cell_y, line as usize);
for cell_x in 0..cells_h {
let (vscrolling_a, _) = self.get_vscroll(cell_x);
@ -524,6 +533,7 @@ fn decode_scroll_size(size: u8) -> usize {
pub struct PatternIterator<'a> {
state: &'a Ym7101State,
palette: u8,
mode: ColourMode,
base: usize,
h_rev: bool,
v_rev: bool,
@ -533,10 +543,11 @@ pub struct PatternIterator<'a> {
}
impl<'a> PatternIterator<'a> {
pub fn new(state: &'a Ym7101State, start: u32, palette: u8, h_rev: bool, v_rev: bool, line: i8) -> Self {
pub fn new(state: &'a Ym7101State, start: u32, palette: u8, mode: ColourMode, h_rev: bool, v_rev: bool, line: i8) -> Self {
Self {
state,
palette,
mode,
base: start as usize,
h_rev,
v_rev,
@ -553,9 +564,9 @@ impl<'a> Iterator for PatternIterator<'a> {
fn next(&mut self) -> Option<Self::Item> {
let offset = self.base + (if !self.v_rev { self.line } else { 7 - self.line }) as usize * 4 + (if !self.h_rev { self.col } else { 3 - self.col }) as usize;
let value = if (!self.h_rev && !self.second) || (self.h_rev && self.second) {
self.state.get_palette_colour(self.palette, self.state.vram[offset] >> 4)
self.state.get_palette_colour(self.palette, self.state.vram[offset] >> 4, self.mode)
} else {
self.state.get_palette_colour(self.palette, self.state.vram[offset] & 0x0f)
self.state.get_palette_colour(self.palette, self.state.vram[offset] & 0x0f, self.mode)
};
if !self.second {

View File

@ -1,15 +1,14 @@
* you need to refactor the ym7101 stuff
* can you make vram/cram/vsram be Addressables that can be accessed the same way? Would this add too much overhead?
* you can directly use a MemoryBlock, and separate out the dma
* there is an issue with Mortal Kombat 2 where it will crash randomly at the start of a fight. The code is actually swapping
stacks a bunch of times, and at some point, the stack is corrupted or something and it `rts`s to the wrong address...
* go through the testcases.rs file and make sure they were decoded correctly
* should you rename devices.rs traits.rs?
* add command line arguments to speed up or slow down either the frame rate limiter or the simulated time per frame
* can you make the connections between things (like memory adapters), be expressed in a way that's more similar to the electrical design?
like specifying that address pins 10-7 should be ignored/unconnected, pin 11 will connect to "chip select", etc
* should you add a unique ID to devices, such that they can be indexed, and their step functions can reset the next_run count and run them immediately
Audio:
@ -33,6 +32,10 @@ Audio:
System/Traits:
* can you make the connections between things (like memory adapters), be expressed in a way that's more similar to the electrical design?
like specifying that address pins 10-7 should be ignored/unconnected, pin 11 will connect to "chip select", etc
* should you add a unique ID to devices, such that they can be indexed, and their step functions can reset the next_run count and run them immediately
* should you simulate bus arbitration?
* interrupts could be done in a better way
* need a better way of handling disparate reads/writes to I/O spaces, rather than having multiple devices or having a massive chunk of address space allocated, continuously
@ -47,6 +50,7 @@ Debugger:
* add a way to delete a watcher
* can you improve how the watcher implementation in the Bus works, instead of setting a flag and then checking it every cycle, pass in the System to Addressable??
* can you use the breakpoint address parser in other commands?
* get stack tracing working again, but can you do it with just data?
* how can you improve the debugger?
* the command line definitely needs to be fixed so it prints the prompt correctly
* debugger could maybe even allows arrows left/right for editing, and up/down for history
@ -61,6 +65,7 @@ Genesis/Mega Drive:
* in some games the controller doesn't seem to work at all (Earthworm Jim, and Mortal Kombat)
* refactor ym7101 into multiple files perhaps. You can separate the DMA stuff, the address/interfacing parts, and the graphics state
* colours are still broken in Sonic1
* sonic3 needs some kind of nvram to run
* implement sn76489 and ym2612 for audio
* the 68000/Z80 bank switching is probably buggy, and there's that other banking stuff in the 0xC00000 range, which isn't implemented at all