mirror of
https://github.com/holub/mame
synced 2025-06-05 20:33:45 +03:00
Experimental flux viewer, activate by #define FLUX_SCREEN 1 in floppy.cpp
This commit is contained in:
parent
d981a61ea6
commit
56db26dcbe
@ -24,6 +24,7 @@
|
||||
#include "formats/fs_unformatted.h"
|
||||
#include "formats/fsblk_vec.h"
|
||||
|
||||
#include "screen.h"
|
||||
#include "speaker.h"
|
||||
#include "formats/imageutl.h"
|
||||
#include "zippath.h"
|
||||
@ -38,6 +39,8 @@
|
||||
|
||||
#define PITCH_SEEK_SAMPLES 1
|
||||
|
||||
#define FLUX_SCREEN 0
|
||||
|
||||
#define FLOPSND_TAG "floppysound"
|
||||
|
||||
// device type definition
|
||||
@ -261,7 +264,8 @@ floppy_image_device::floppy_image_device(const machine_config &mconfig, device_t
|
||||
image_dirty(false),
|
||||
ready_counter(0),
|
||||
m_make_sound(false),
|
||||
m_sound_out(nullptr)
|
||||
m_sound_out(nullptr),
|
||||
m_flux_screen(*this, "flux")
|
||||
{
|
||||
extension_list[0] = '\0';
|
||||
m_err = IMAGE_ERROR_INVALIDIMAGE;
|
||||
@ -475,6 +479,27 @@ void floppy_image_device::device_start()
|
||||
save_item(NAME(image_dirty));
|
||||
save_item(NAME(ready_counter));
|
||||
save_item(NAME(phases));
|
||||
|
||||
m_flux_per_pixel_infos.resize(flux_screen_sx*flux_screen_sy);
|
||||
flux_per_pixel_info *ppi = m_flux_per_pixel_infos.data();
|
||||
for(int y = 0; y != flux_screen_sy; y++) {
|
||||
int head = y >= flux_screen_sy / 2 ? 1 : 0;
|
||||
int yc = (flux_screen_sy/2-1)/2 + (flux_screen_sy/2)*head;
|
||||
int dy = y - yc;
|
||||
for(int x = 0; x != flux_screen_sx; x++) {
|
||||
const int xc = (flux_screen_sx - 1)/2;
|
||||
int dx = x - xc;
|
||||
int r = int(sqrt(dx*dx + dy*dy) + 0.5);
|
||||
ppi->m_r = r;
|
||||
if(r > flux_max_r || r < flux_min_r)
|
||||
ppi->m_position = 0xffffffff;
|
||||
else
|
||||
ppi->m_position = int((200e6 / 2 / M_PI) * atan2(dy, dx) + 100000000.5) % 200000000;
|
||||
ppi->m_combined_track = 0;
|
||||
ppi->m_color = 0;
|
||||
ppi ++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void floppy_image_device::device_reset()
|
||||
@ -592,9 +617,143 @@ image_init_result floppy_image_device::call_load()
|
||||
if (!cur_load_cb.isnull())
|
||||
return cur_load_cb(this);
|
||||
|
||||
flux_image_prepare();
|
||||
return image_init_result::PASS;
|
||||
}
|
||||
|
||||
void floppy_image_device::flux_image_prepare()
|
||||
{
|
||||
int tracks = 0, heads = 0, rez = 0;
|
||||
image->get_maximal_geometry(tracks, heads);
|
||||
rez = image->get_resolution();
|
||||
|
||||
int trackm = (tracks - 1) << rez;
|
||||
int tmask = (1 << rez) - 1;
|
||||
|
||||
m_flux_per_combined_track_infos.clear();
|
||||
m_flux_per_combined_track_infos.resize(trackm+1);
|
||||
for(int track = 0; track <= trackm; track++) {
|
||||
int refr = 200 + (trackm - 0.5 - track) * 290 / (trackm+1) + 200;
|
||||
int span = int((200e6 / 2 / M_PI) / refr);
|
||||
m_flux_per_combined_track_infos[track].m_span = span;
|
||||
m_flux_per_combined_track_infos[track].m_track = track >> rez;
|
||||
m_flux_per_combined_track_infos[track].m_subtrack = track & tmask;
|
||||
}
|
||||
|
||||
flux_per_pixel_info *ppi = m_flux_per_pixel_infos.data();
|
||||
for(int head = 0; head != heads; head++)
|
||||
for(unsigned int i=0; i != flux_screen_sx*flux_screen_sy/2; i++) {
|
||||
if(ppi->m_position != 0xffffffff) {
|
||||
int trk = (trackm + 1) * (flux_max_r - ppi->m_r) / (flux_max_r - flux_min_r + 1);
|
||||
ppi->m_combined_track = trk;
|
||||
m_flux_per_combined_track_infos[trk].m_pixels[head].push_back(ppi);
|
||||
}
|
||||
ppi++;
|
||||
}
|
||||
|
||||
for(auto &t : m_flux_per_combined_track_infos) {
|
||||
std::sort(t.m_pixels[0].begin(), t.m_pixels[0].end(), [](const flux_per_pixel_info *a, const flux_per_pixel_info *b) -> bool { return a->m_position < b->m_position; });
|
||||
if(heads == 2)
|
||||
std::sort(t.m_pixels[1].begin(), t.m_pixels[1].end(), [](const flux_per_pixel_info *a, const flux_per_pixel_info *b) -> bool { return a->m_position < b->m_position; });
|
||||
}
|
||||
|
||||
for(int head = 0; head != heads; head++)
|
||||
for(int track = 0; track <= trackm; track++)
|
||||
flux_image_compute_for_track(track, head);
|
||||
}
|
||||
|
||||
void floppy_image_device::flux_image_compute_for_track(int track, int head)
|
||||
{
|
||||
auto *pcti = m_flux_per_combined_track_infos.data() + track;
|
||||
const std::vector<uint32_t> &buffer = image->get_buffer(pcti->m_track, head, pcti->m_subtrack);
|
||||
int sz = buffer.size();
|
||||
if(!sz) {
|
||||
for(flux_per_pixel_info *p : m_flux_per_combined_track_infos[track].m_pixels[head])
|
||||
p->m_color = 255;
|
||||
return;
|
||||
}
|
||||
|
||||
int spos = pcti->m_pixels[head][0]->m_position - pcti->m_span + 200000000;
|
||||
int bpos = sz;
|
||||
while(bpos && (buffer[bpos-1] & floppy_image::TIME_MASK) < spos)
|
||||
bpos --;
|
||||
if(bpos == sz)
|
||||
bpos = 0;
|
||||
|
||||
int pspos = spos;
|
||||
for(flux_per_pixel_info *p : m_flux_per_combined_track_infos[track].m_pixels[head]) {
|
||||
int spos = p->m_position - pcti->m_span;
|
||||
int epos = p->m_position + pcti->m_span;
|
||||
if(spos < 0)
|
||||
spos += 200000000;
|
||||
if(epos >= 200000000)
|
||||
epos -= 200000000;
|
||||
|
||||
if(spos < pspos)
|
||||
bpos = 0;
|
||||
while(bpos != sz-1 && (buffer[bpos+1] & floppy_image::TIME_MASK) < spos)
|
||||
bpos ++;
|
||||
|
||||
int bpos2 = spos < epos ? bpos : 0;
|
||||
while(bpos2 != sz-1 && (buffer[bpos2+1] & floppy_image::TIME_MASK) < epos)
|
||||
bpos2 ++;
|
||||
|
||||
int count;
|
||||
if(bpos <= bpos2)
|
||||
count = bpos2 - bpos;
|
||||
else {
|
||||
count = (sz - 1 - bpos) + bpos2;
|
||||
if((buffer[0] ^ buffer[sz-1]) & floppy_image::MG_MASK)
|
||||
count ++;
|
||||
}
|
||||
|
||||
count *= 5;
|
||||
if(count > 255)
|
||||
count = 255;
|
||||
p->m_color = 255 - count;
|
||||
pspos = spos;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t floppy_image_device::flux_screen_update(screen_device &device, bitmap_rgb32 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
if(image.get()) {
|
||||
int ctrack = ((cyl << 2) | subcyl) >> (2 - image->get_resolution());
|
||||
if(mon)
|
||||
ctrack = -1;
|
||||
for(int y = cliprect.min_y; y <= cliprect.max_y; y++) {
|
||||
int head = y >= flux_screen_sy / 2;
|
||||
flux_per_pixel_info *ppi = m_flux_per_pixel_infos.data() + y * flux_screen_sx + cliprect.min_x;
|
||||
uint32_t *p = &bitmap.pix(y, cliprect.min_x);
|
||||
for(int x = cliprect.min_x; x <= cliprect.max_x; x++) {
|
||||
if(ppi->m_position == 0xffffffff)
|
||||
*p++ = 0;
|
||||
else {
|
||||
u32 color = 0x010101 * ppi->m_color;
|
||||
if(ppi->m_combined_track == ctrack && head == ss)
|
||||
color &= 0x0000ff;
|
||||
*p++ = color;
|
||||
}
|
||||
ppi++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for(int y = cliprect.min_y; y <= cliprect.max_y; y++) {
|
||||
flux_per_pixel_info *ppi = m_flux_per_pixel_infos.data() + y * flux_screen_sx + cliprect.min_x;
|
||||
uint32_t *p = &bitmap.pix(y, cliprect.min_x);
|
||||
for(int x = cliprect.min_x; x <= cliprect.max_x; x++) {
|
||||
if(ppi->m_position == 0xffffffff)
|
||||
*p++ = 0;
|
||||
else
|
||||
*p++ = 0x404040;
|
||||
ppi++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void floppy_image_device::call_unload()
|
||||
{
|
||||
cache_clear();
|
||||
@ -650,6 +809,8 @@ image_init_result floppy_image_device::call_create(int format_type, util::option
|
||||
|
||||
init_floppy_load(true);
|
||||
|
||||
flux_image_prepare();
|
||||
|
||||
return image_init_result::PASS;
|
||||
}
|
||||
|
||||
@ -1207,6 +1368,8 @@ void floppy_image_device::write_flux(const attotime &start, const attotime &end,
|
||||
}
|
||||
|
||||
buf.resize(cells);
|
||||
|
||||
flux_image_compute_for_track(((cyl << 2) | subcyl) >> (2 - image->get_resolution()), ss);
|
||||
}
|
||||
|
||||
void floppy_image_device::write_zone(uint32_t *buf, int &cells, int &index, uint32_t spos, uint32_t epos, uint32_t mg)
|
||||
@ -1706,6 +1869,13 @@ void floppy_image_device::device_add_mconfig(machine_config &config)
|
||||
{
|
||||
SPEAKER(config, FLOPSPK).front_center();
|
||||
FLOPPYSOUND(config, FLOPSND_TAG, 44100).add_route(ALL_OUTPUTS, FLOPSPK, 0.5);
|
||||
|
||||
#if FLUX_SCREEN
|
||||
SCREEN(config, m_flux_screen, SCREEN_TYPE_RASTER);
|
||||
m_flux_screen->set_screen_update(FUNC(floppy_image_device::flux_screen_update));
|
||||
m_flux_screen->set_raw(30*(flux_screen_sx+1)*(flux_screen_sy+1), flux_screen_sx+1, 0, flux_screen_sx, flux_screen_sy+1, 0, flux_screen_sy);
|
||||
m_flux_screen->set_physical_aspect(1, 2);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -266,6 +266,35 @@ protected:
|
||||
// Sound
|
||||
bool m_make_sound;
|
||||
floppy_sound_device* m_sound_out;
|
||||
|
||||
// Flux visualization
|
||||
struct flux_per_pixel_info {
|
||||
uint32_t m_position; // 0-199999999 Angular position in the track, 0xffffffff if not in the floppy image
|
||||
uint16_t m_r; // Distance from the center
|
||||
uint8_t m_combined_track; // No need to store head, it's y >= flux_screen_sy/2
|
||||
uint8_t m_color; // Computed gray level from the flux counts
|
||||
};
|
||||
|
||||
struct flux_per_combined_track_info {
|
||||
std::vector<flux_per_pixel_info *> m_pixels[2];
|
||||
uint32_t m_span;
|
||||
uint8_t m_track;
|
||||
uint8_t m_subtrack;
|
||||
};
|
||||
|
||||
std::vector<flux_per_pixel_info> m_flux_per_pixel_infos;
|
||||
std::vector<flux_per_combined_track_info> m_flux_per_combined_track_infos;
|
||||
|
||||
optional_device<screen_device> m_flux_screen;
|
||||
|
||||
static constexpr int flux_screen_sx = 501;
|
||||
static constexpr int flux_screen_sy = 1002;
|
||||
static constexpr int flux_min_r = 100;
|
||||
static constexpr int flux_max_r = 245;
|
||||
|
||||
void flux_image_prepare();
|
||||
void flux_image_compute_for_track(int track, int head);
|
||||
uint32_t flux_screen_update(screen_device &device, bitmap_rgb32 &bitmap, const rectangle &cliprect);
|
||||
};
|
||||
|
||||
#define DECLARE_FLOPPY_IMAGE_DEVICE(Type, Name, Interface) \
|
||||
|
Loading…
Reference in New Issue
Block a user