1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-12-25 18:30:21 +00:00

Attempts to get at least as far as picking visible sprite indices.

This commit is contained in:
Thomas Harte 2018-10-06 19:27:19 -04:00
parent 76f3b9f6ba
commit e6510dc87b
2 changed files with 55 additions and 46 deletions

View File

@ -16,7 +16,7 @@ using namespace TI::TMS;
namespace {
const uint8_t StatusInterrupt = 0x80;
const uint8_t StatusFifthSprite = 0x40;
const uint8_t StatusSpriteOverflow = 0x40;
const int StatusSpriteCollisionShift = 5;
const uint8_t StatusSpriteCollision = 0x20;
@ -91,33 +91,38 @@ Outputs::CRT::CRT *TMS9918::get_crt() {
return crt_.get();
}
void Base::test_sprite(int sprite_number, int screen_row) {
/* if(!(status_ & StatusFifthSprite)) {
void Base::reset_sprite_collection() {
sprite_set_.sprites_stopped = false;
sprite_set_.fetched_sprite_slot = sprite_set_.active_sprite_slot;
sprite_set_.active_sprite_slot = 0;
}
void Base::posit_sprite(int sprite_number, int sprite_position, int screen_row) {
if(!(status_ & StatusSpriteOverflow)) {
status_ = static_cast<uint8_t>((status_ & ~31) | sprite_number);
}
if(sprites_stopped_)
if(sprite_set_.sprites_stopped)
return;
const int sprite_position = ram_[sprite_attribute_table_address_ + static_cast<size_t>(sprite_number << 2)];
// const int sprite_position = ram_[sprite_attribute_table_address_ + static_cast<size_t>(sprite_number << 2)];
// A sprite Y of 208 means "don't scan the list any further".
if(sprite_position == 208) {
sprites_stopped_ = true;
if(mode_timing_.allow_sprite_terminator && sprite_position == 208) {
sprite_set_.sprites_stopped = true;
return;
}
const int sprite_row = (screen_row - sprite_position)&255;
if(sprite_row < 0 || sprite_row >= sprite_height_) return;
const int active_sprite_slot = sprite_sets_[active_sprite_set_].active_sprite_slot;
if(active_sprite_slot == 4) {
status_ |= StatusFifthSprite;
if(sprite_set_.active_sprite_slot == mode_timing_.maximum_visible_sprites) {
status_ |= StatusSpriteOverflow;
return;
}
SpriteSet::ActiveSprite &sprite = sprite_sets_[active_sprite_set_].active_sprites[active_sprite_slot];
SpriteSet::ActiveSprite &sprite = sprite_set_.active_sprites[sprite_set_.active_sprite_slot];
sprite.index = sprite_number;
sprite.row = sprite_row >> (sprites_magnified_ ? 1 : 0);
sprite_sets_[active_sprite_set_].active_sprite_slot++;*/
++sprite_set_.active_sprite_slot;
}
void Base::get_sprite_contents(int field, int cycles_left, int screen_row) {
@ -254,7 +259,7 @@ void TMS9918::run_for(const HalfCycles cycles) {
// Left border.
intersect(73, mode_timing_.first_pixel_output_column, output_border(end - start));
// In pixel area:
// Pixel region.
intersect(
mode_timing_.first_pixel_output_column,
mode_timing_.next_border_column,
@ -629,7 +634,7 @@ uint8_t TMS9918::get_register(int address) {
// Reads from address 1 get the status register.
uint8_t result = status_;
status_ &= ~(StatusInterrupt | StatusFifthSprite | StatusSpriteCollision);
status_ &= ~(StatusInterrupt | StatusSpriteOverflow | StatusSpriteCollision);
line_interrupt_pending_ = false;
return result;
}

View File

@ -157,6 +157,8 @@ class Base {
//
int end_of_frame_interrupt_position = 342;
int line_interrupt_position = -1;
bool allow_sprite_terminator = true;
} mode_timing_;
uint8_t line_interrupt_target = 0;
@ -218,10 +220,12 @@ class Base {
} active_sprites[8];
int active_sprite_slot = 0;
bool sprites_stopped_ = false;
int fetched_sprite_slot = 0;
bool sprites_stopped = false;
} sprite_set_;
inline void test_sprite(int sprite_number, int screen_row);
inline void reset_sprite_collection();
inline void posit_sprite(int sprite_number, int sprite_y, int screen_row);
inline void get_sprite_contents(int start, int cycles, int screen_row);
enum class ScreenMode {
@ -273,7 +277,7 @@ class Base {
}
void external_slot() {
void do_external_slot() {
// TODO: write or read a value if one is queued and ready to read/write.
// (and, later: update the command engine, if this is an MSX2).
switch(queued_access_) {
@ -303,7 +307,7 @@ class Base {
case n
#define external_slot(n) \
slot(n): external_slot();
slot(n): do_external_slot();
#define external_slots_2(n) \
external_slot(n); \
@ -596,13 +600,10 @@ class Base {
- sprite n+1, tile graphic second word
*/
#define sprite_y_read(location) \
slot(location):
/*
TODO: sprite_y_read should fetch:
- sprite n and n+1, y position
*/
#define sprite_y_read(location, sprite) \
slot(location): \
posit_sprite(sprite, ram_[sprite_attribute_table_address_ + sprite], row_); \
posit_sprite(sprite, ram_[sprite_attribute_table_address_ + sprite + 1], row_); \
#define fetch_tile_name(column) {\
const size_t scrolled_column = (column - horizontal_offset) & 0x1f;\
@ -620,21 +621,21 @@ class Base {
master_system_.tile_graphics[column][3] = ram_[master_system_.names[column].offset+3]; \
}
#define background_render_block(location, column) \
#define background_render_block(location, column, sprite) \
slot(location): fetch_tile_name(column) \
external_slot(location+1); \
slot(location+2): \
slot(location+3): fetch_tile(column) \
slot(location+4): fetch_tile_name(column+1) \
sprite_y_read(location+5); \
sprite_y_read(location+5, sprite); \
slot(location+6): \
slot(location+7): fetch_tile(column+1) \
slot(location+8): fetch_tile_name(column+2) \
sprite_y_read(location+9); \
sprite_y_read(location+9, sprite+2); \
slot(location+10): \
slot(location+11): fetch_tile(column+2) \
slot(location+12): fetch_tile_name(column+3) \
sprite_y_read(location+13); \
sprite_y_read(location+13, sprite+4); \
slot(location+14): \
slot(location+15): fetch_tile(column+3)
@ -664,25 +665,28 @@ class Base {
sprite_fetch_block(21, 4);
sprite_fetch_block(27, 6);
external_slots_2(33);
slot(33):
reset_sprite_collection();
do_external_slot();
external_slot(34);
sprite_y_read(35);
sprite_y_read(36);
sprite_y_read(37);
sprite_y_read(38);
sprite_y_read(39);
sprite_y_read(40);
sprite_y_read(41);
sprite_y_read(42);
sprite_y_read(35, 0);
sprite_y_read(36, 2);
sprite_y_read(37, 4);
sprite_y_read(38, 6);
sprite_y_read(39, 8);
sprite_y_read(40, 10);
sprite_y_read(41, 12);
sprite_y_read(42, 14);
background_render_block(43, 0);
background_render_block(59, 4);
background_render_block(75, 8);
background_render_block(91, 12);
background_render_block(107, 16);
background_render_block(123, 20);
background_render_block(139, 24); // TODO: this and the next one should ignore master_system_.vertical_scroll.
background_render_block(156, 28);
background_render_block(43, 0, 16);
background_render_block(59, 4, 22);
background_render_block(75, 8, 28);
background_render_block(91, 12, 34);
background_render_block(107, 16, 40);
background_render_block(123, 20, 46);
background_render_block(139, 24, 52); // TODO: this and the next one should ignore master_system_.vertical_scroll.
background_render_block(156, 28, 58);
return;
}