mirror of
https://github.com/sarah-walker-pcem/pcem.git
synced 2025-07-23 11:43:03 +02:00
Add debug viewers (#277)
* Fix up global variable definitions in ibm.h This fixes multiple definition errors when including ibm.h in C++ code. * viewers: Add viewer infrastructure Viewers are windows showing the status of a particular component of the emulated machine; primarily for amusement, though may be useful for debugging in some situations. This commit adds the basic infrastructure for viewers. * viewers: Add (S)VGA palette viewers This adds two basic viewers for the (S)VGA palette; one for the 16-entry attribute controller palette, and one for the 256-entry RAMDAC palette. * viewers: Add (S)VGA font viewer Add a simple viewer to display the current (S)VGA font. * viewers: Add (S)VGA video memory viewer Add a viewer for (S)VGA video memory. This allows viewing of on and off screen video memory in the various supported bitmap formats. * viewers: Add 3DFX viewer Add a viewer for 3DFX state. This shows all triangles and textures involved in the most recent frame, and allows showing of framebuffer, depth buffer, and wireframes. It currently does not work properly in SLI configurations (only the first card will be viewed) and trilinear textures will not display correctly.
This commit is contained in:
committed by
GitHub
parent
dd1ef689f1
commit
a0db379ed7
@@ -134,7 +134,7 @@ find_package(OpenAL REQUIRED)
|
||||
include_directories(${OPENAL_INCLUDE_DIR})
|
||||
|
||||
if(${PCEM_DISPLAY_ENGINE} STREQUAL "wxWidgets")
|
||||
find_package(wxWidgets REQUIRED COMPONENTS core base xrc)
|
||||
find_package(wxWidgets REQUIRED COMPONENTS core base xrc adv)
|
||||
include(${wxWidgets_USE_FILE})
|
||||
set(DISPLAY_ENGINE_LIBRARIES ${wxWidgets_LIBRARIES})
|
||||
endif()
|
||||
|
@@ -55,7 +55,7 @@ typedef union MMX_REG {
|
||||
float f[2];
|
||||
} MMX_REG;
|
||||
|
||||
struct {
|
||||
typedef struct cpu_state_t {
|
||||
x86reg regs[8];
|
||||
|
||||
uint8_t tag[8];
|
||||
@@ -113,7 +113,9 @@ struct {
|
||||
uint16_t flags, eflags;
|
||||
|
||||
uint32_t smbase;
|
||||
} cpu_state;
|
||||
} cpu_state_t;
|
||||
|
||||
extern cpu_state_t cpu_state;
|
||||
|
||||
#define cpu_state_offset(MEMBER) ((uintptr_t)&cpu_state.MEMBER - (uintptr_t)&cpu_state - 128)
|
||||
|
||||
@@ -318,12 +320,14 @@ void cyrix_write_seg_descriptor(uint32_t addr, x86seg *seg);
|
||||
#define SMHR_VALID (1 << 0)
|
||||
#define SMHR_ADDR_MASK (0xfffffffc)
|
||||
|
||||
struct {
|
||||
typedef struct cyrix_t {
|
||||
struct {
|
||||
uint32_t base;
|
||||
uint64_t size;
|
||||
} arr[8];
|
||||
uint32_t smhr;
|
||||
} cyrix;
|
||||
} cyrix_t;
|
||||
|
||||
extern cyrix_t cyrix;
|
||||
|
||||
#endif /* _X86_H_ */
|
||||
|
@@ -23,16 +23,16 @@
|
||||
#define readflash_get(offset, drive) ((readflash & (1 << ((offset) + (drive)))) != 0)
|
||||
|
||||
/*Memory*/
|
||||
uint8_t *ram;
|
||||
extern uint8_t *ram;
|
||||
|
||||
uint32_t rammask;
|
||||
extern uint32_t rammask;
|
||||
|
||||
int readlookup[256], readlookupp[256];
|
||||
uintptr_t *readlookup2;
|
||||
int readlnext;
|
||||
int writelookup[256], writelookupp[256];
|
||||
uintptr_t *writelookup2;
|
||||
int writelnext;
|
||||
extern int readlookup[256], readlookupp[256];
|
||||
extern uintptr_t *readlookup2;
|
||||
extern int readlnext;
|
||||
extern int writelookup[256], writelookupp[256];
|
||||
extern uintptr_t *writelookup2;
|
||||
extern int writelnext;
|
||||
|
||||
extern int mmu_perm;
|
||||
|
||||
@@ -104,7 +104,7 @@ typedef struct PIT {
|
||||
void (*set_out_funcs[3])(int new_out, int old_out);
|
||||
} PIT;
|
||||
|
||||
PIT pit, pit2;
|
||||
extern PIT pit, pit2;
|
||||
void setpitclock(float clock);
|
||||
|
||||
float pit_timer0_freq();
|
||||
@@ -130,7 +130,7 @@ typedef struct dma_t {
|
||||
uint16_t io_addr;
|
||||
} dma_t;
|
||||
|
||||
dma_t dma[8];
|
||||
extern dma_t dma[8];
|
||||
|
||||
/*PPI*/
|
||||
typedef struct PPI {
|
||||
@@ -138,7 +138,7 @@ typedef struct PPI {
|
||||
uint8_t pa, pb;
|
||||
} PPI;
|
||||
|
||||
PPI ppi;
|
||||
extern PPI ppi;
|
||||
|
||||
/*PIC*/
|
||||
typedef struct PIC {
|
||||
@@ -149,15 +149,15 @@ typedef struct PIC {
|
||||
uint8_t level_sensitive;
|
||||
} PIC;
|
||||
|
||||
PIC pic, pic2;
|
||||
extern PIC pic, pic2;
|
||||
extern int pic_intpending;
|
||||
|
||||
char discfns[2][256];
|
||||
int driveempty[2];
|
||||
extern char discfns[2][256];
|
||||
extern int driveempty[2];
|
||||
|
||||
#define PCJR (romset == ROM_IBMPCJR)
|
||||
|
||||
int GAMEBLASTER, GUS, SSI2001, voodoo_enabled;
|
||||
extern int GAMEBLASTER, GUS, SSI2001, voodoo_enabled;
|
||||
extern int AMSTRAD, AT, is386, PCI, TANDY, MCA;
|
||||
|
||||
enum {
|
||||
@@ -268,8 +268,8 @@ enum {
|
||||
|
||||
extern int romspresent[ROM_MAX];
|
||||
|
||||
int hasfpu;
|
||||
int romset;
|
||||
extern int hasfpu;
|
||||
extern int romset;
|
||||
|
||||
enum {
|
||||
GFX_BUILTIN = -1,
|
||||
@@ -327,12 +327,12 @@ enum {
|
||||
|
||||
extern int gfx_present[GFX_MAX];
|
||||
|
||||
int gfxcard;
|
||||
extern int gfxcard;
|
||||
|
||||
int cpuspeed;
|
||||
extern int cpuspeed;
|
||||
|
||||
/*Video*/
|
||||
int readflash;
|
||||
extern int readflash;
|
||||
extern int egareads, egawrites;
|
||||
extern int vid_resize;
|
||||
extern int vid_api;
|
||||
@@ -341,12 +341,12 @@ extern int winsizex, winsizey;
|
||||
extern int changeframecount;
|
||||
|
||||
/*Sound*/
|
||||
int ppispeakon;
|
||||
extern int ppispeakon;
|
||||
extern uint64_t CGACONST;
|
||||
extern uint64_t MDACONST;
|
||||
extern uint64_t VGACONST1, VGACONST2;
|
||||
extern uint64_t RTCCONST;
|
||||
int gated, speakval, speakon;
|
||||
extern int gated, speakval, speakon;
|
||||
|
||||
/*Sound Blaster*/
|
||||
#define SADLIB 1 /*No DSP*/
|
||||
@@ -368,10 +368,10 @@ typedef struct {
|
||||
int tracks;
|
||||
} PcemHDC;
|
||||
|
||||
PcemHDC hdc[7];
|
||||
extern PcemHDC hdc[7];
|
||||
|
||||
/*Keyboard*/
|
||||
int keybsenddelay;
|
||||
extern int keybsenddelay;
|
||||
|
||||
/*CD-ROM*/
|
||||
extern int cdrom_drive;
|
||||
|
@@ -96,8 +96,8 @@ void mem_write_nulll(uint32_t addr, uint32_t val, void *p);
|
||||
|
||||
FILE *romfopen(char *fn, char *mode);
|
||||
|
||||
mem_mapping_t bios_mapping[8];
|
||||
mem_mapping_t bios_high_mapping[9];
|
||||
extern mem_mapping_t bios_mapping[8];
|
||||
extern mem_mapping_t bios_high_mapping[9];
|
||||
|
||||
extern mem_mapping_t ram_high_mapping;
|
||||
extern mem_mapping_t ram_remapped_mapping;
|
||||
|
@@ -294,6 +294,7 @@ typedef struct voodoo_t {
|
||||
unsigned int vertex_next_age;
|
||||
int num_verticies;
|
||||
int cull_pingpong;
|
||||
int in_strip;
|
||||
|
||||
int flush;
|
||||
|
||||
@@ -463,6 +464,8 @@ typedef struct voodoo_t {
|
||||
uint8_t *vram, *changedvram;
|
||||
|
||||
void *p;
|
||||
|
||||
int viewer_active;
|
||||
} voodoo_t;
|
||||
|
||||
typedef struct voodoo_set_t {
|
||||
|
64
includes/private/wx-ui/viewer.h
Normal file
64
includes/private/wx-ui/viewer.h
Normal file
@@ -0,0 +1,64 @@
|
||||
#ifndef _VIEWER_H_
|
||||
#define _VIEWER_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct viewer_t
|
||||
{
|
||||
void *(*open)(void *parent, void *p, const char *title);
|
||||
} viewer_t;
|
||||
|
||||
void viewer_reset();
|
||||
void viewer_add(char *title, viewer_t *viewer, void *p);
|
||||
void viewer_open(void *hwnd, int id);
|
||||
void viewer_remove(void *viewer);
|
||||
void viewer_update(viewer_t *viewer, void *p);
|
||||
void viewer_call(viewer_t *viewer, void *p, void (*func)(void *v, void *param), void *param);
|
||||
void viewer_close_all();
|
||||
void viewer_notify_pause();
|
||||
void viewer_notify_resume();
|
||||
void update_viewers_menu(void *menu);
|
||||
|
||||
extern viewer_t viewer_font;
|
||||
extern viewer_t viewer_palette;
|
||||
extern viewer_t viewer_palette_16;
|
||||
extern viewer_t viewer_voodoo;
|
||||
extern viewer_t viewer_vram;
|
||||
|
||||
#define IDM_VIEWER 1600
|
||||
#define IDM_VIEWER_MAX 1700
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
|
||||
class Viewer: public wxFrame
|
||||
{
|
||||
public:
|
||||
void *p;
|
||||
|
||||
Viewer(wxWindow *parent, wxString title, wxSize size, void *p)
|
||||
: wxFrame(parent, wxID_ANY, title, wxPoint(50, 50), size, wxDEFAULT_FRAME_STYLE),
|
||||
p(p)
|
||||
{
|
||||
SetClientSize(size);
|
||||
}
|
||||
|
||||
virtual ~Viewer()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void NotifyPause()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void NotifyResume()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
18
includes/private/wx-ui/viewer_voodoo.h
Normal file
18
includes/private/wx-ui/viewer_voodoo.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#ifndef _VIEWER_VOODOO_H_
|
||||
#define _VIEWER_VOODOO_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void voodoo_viewer_swap_buffer(void *v, void *param);
|
||||
void voodoo_viewer_queue_triangle(void *v, void *param);
|
||||
void voodoo_viewer_begin_strip(void *v, void *param);
|
||||
void voodoo_viewer_end_strip(void *v, void *param);
|
||||
void voodoo_viewer_use_texture(void *v, void *param);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@@ -51,6 +51,7 @@ include(${CMAKE_CURRENT_SOURCE_DIR}/video/video.cmake)
|
||||
|
||||
if(${PCEM_DISPLAY_ENGINE} STREQUAL "wxWidgets")
|
||||
include(${CMAKE_CURRENT_SOURCE_DIR}/wx-ui/wx-ui.cmake)
|
||||
include(${CMAKE_CURRENT_SOURCE_DIR}/wx-ui/viewers/viewers.cmake)
|
||||
endif()
|
||||
if(${PCEM_DISPLAY_ENGINE} STREQUAL "Qt")
|
||||
message(FATAL_ERROR "Qt Mode is not yet implemented.")
|
||||
|
@@ -4,6 +4,9 @@
|
||||
#include "x86_flags.h"
|
||||
#include "codegen.h"
|
||||
|
||||
cpu_state_t cpu_state;
|
||||
cyrix_t cyrix;
|
||||
|
||||
x86seg gdt, ldt, idt, tr;
|
||||
|
||||
uint32_t cr2, cr3, cr4;
|
||||
|
@@ -17,6 +17,8 @@ static int cpu_turbo = 1;
|
||||
int isa_cycles;
|
||||
int has_vlb;
|
||||
static uint8_t ccr0, ccr1, ccr2, ccr3, ccr4, ccr5, ccr6;
|
||||
int hasfpu;
|
||||
int cpuspeed;
|
||||
|
||||
OpFn *x86_dynarec_opcodes;
|
||||
OpFn *x86_dynarec_opcodes_0f;
|
||||
|
@@ -3,6 +3,8 @@
|
||||
#include "fdc.h"
|
||||
#include "fdd.h"
|
||||
|
||||
char discfns[2][256];
|
||||
|
||||
static struct {
|
||||
int type;
|
||||
|
||||
|
@@ -15,6 +15,8 @@
|
||||
#include <pcem/devices.h>
|
||||
#include <pcem/defines.h>
|
||||
|
||||
PcemHDC hdc[7];
|
||||
|
||||
extern HDD_CONTROLLER *hdd_controllers[HDDCONTROLLERS_MAX];
|
||||
char hdd_controller_name[16];
|
||||
|
||||
|
@@ -58,6 +58,15 @@ void (*smram_disable)(void);
|
||||
int mmuflush = 0;
|
||||
int mmu_perm = 4;
|
||||
|
||||
int readlookup[256], readlookupp[256];
|
||||
uintptr_t *readlookup2;
|
||||
int readlnext;
|
||||
int writelookup[256], writelookupp[256];
|
||||
uintptr_t *writelookup2;
|
||||
int writelnext;
|
||||
|
||||
uint32_t rammask;
|
||||
|
||||
int mem_addr_is_ram(uint32_t addr) {
|
||||
mem_mapping_t *mapping = read_mapping[addr >> 14];
|
||||
|
||||
@@ -1161,7 +1170,7 @@ void mem_mapping_remove(mem_mapping_t *mapping)
|
||||
dest = dest->next;
|
||||
}
|
||||
prev->next = mapping->next;
|
||||
|
||||
|
||||
mem_mapping_recalc(mapping->base, mapping->size);
|
||||
}
|
||||
|
||||
|
@@ -8,6 +8,8 @@
|
||||
#include "video.h"
|
||||
#include "x86.h"
|
||||
|
||||
dma_t dma[8];
|
||||
|
||||
static uint8_t dmaregs[16];
|
||||
static uint8_t dma16regs[16];
|
||||
static uint8_t dmapages[16];
|
||||
|
@@ -4,6 +4,8 @@
|
||||
#include "pit.h"
|
||||
#include "video.h"
|
||||
|
||||
PIC pic, pic2;
|
||||
|
||||
int intclear;
|
||||
int keywaiting = 0;
|
||||
int pic_intpending;
|
||||
|
@@ -16,6 +16,9 @@
|
||||
#include "timer.h"
|
||||
#include "video.h"
|
||||
#include "model.h"
|
||||
|
||||
PIT pit, pit2;
|
||||
|
||||
/*B0 to 40, two writes to 43, then two reads - value does not change!*/
|
||||
/*B4 to 40, two writes to 43, then two reads - value _does_ change!*/
|
||||
// Tyrian writes 4300 or 17512
|
||||
|
9
src/pc.c
9
src/pc.c
@@ -61,6 +61,7 @@
|
||||
#include "x86.h"
|
||||
#include "paths.h"
|
||||
#include "plugin.h"
|
||||
#include "viewer.h"
|
||||
|
||||
#ifdef USE_NETWORKING
|
||||
#include "nethandler.h"
|
||||
@@ -70,6 +71,11 @@ uint8_t ethif;
|
||||
int inum;
|
||||
#endif
|
||||
|
||||
int GAMEBLASTER, GUS, SSI2001, voodoo_enabled;
|
||||
int gfxcard;
|
||||
int readflash;
|
||||
int romset;
|
||||
|
||||
int window_w, window_h, window_x, window_y, window_remember;
|
||||
|
||||
int start_in_fullscreen = 0;
|
||||
@@ -248,6 +254,7 @@ void initpc(int argc, char *argv[]) {
|
||||
atfullspeed = 0;
|
||||
|
||||
device_init();
|
||||
viewer_reset();
|
||||
|
||||
initvideo();
|
||||
mem_init();
|
||||
@@ -344,7 +351,9 @@ void resetpc_cad() {
|
||||
void resetpchard() {
|
||||
device_close_all();
|
||||
mouse_emu_close();
|
||||
viewer_close_all();
|
||||
device_init();
|
||||
viewer_reset();
|
||||
|
||||
timer_reset();
|
||||
sound_reset();
|
||||
|
@@ -11,6 +11,8 @@
|
||||
#include "plat-keyboard.h"
|
||||
#include "plat-mouse.h"
|
||||
|
||||
PPI ppi;
|
||||
|
||||
void ppi_reset() {
|
||||
ppi.pa = 0x0; // 0x1D;
|
||||
ppi.pb = 0x40;
|
||||
|
@@ -2,6 +2,9 @@
|
||||
#include "sound.h"
|
||||
#include "sound_speaker.h"
|
||||
|
||||
int gated, speakval, speakon;
|
||||
int ppispeakon;
|
||||
|
||||
int speaker_mute = 0;
|
||||
|
||||
static int16_t speaker_buffer[MAXSOUNDBUFLEN];
|
||||
|
@@ -8,6 +8,7 @@
|
||||
#include "vid_svga_render.h"
|
||||
#include "io.h"
|
||||
#include "timer.h"
|
||||
#include "viewer.h"
|
||||
|
||||
#define svga_output 0
|
||||
|
||||
@@ -600,6 +601,8 @@ void svga_poll(void *p) {
|
||||
}
|
||||
}
|
||||
if (svga->vc == svga->dispend) {
|
||||
int changed = 0;
|
||||
|
||||
if (svga->vblank_start)
|
||||
svga->vblank_start(svga);
|
||||
// pclog("VC dispend\n");
|
||||
@@ -614,11 +617,21 @@ void svga_poll(void *p) {
|
||||
|
||||
for (x = 0; x < ((svga->vram_mask + 1) >> 12); x++) {
|
||||
if (svga->changedvram[x])
|
||||
{
|
||||
svga->changedvram[x]--;
|
||||
changed = 1;
|
||||
}
|
||||
}
|
||||
// memset(changedvram,0,2048);
|
||||
if (svga->fullchange)
|
||||
if (svga->fullchange) {
|
||||
svga->fullchange--;
|
||||
viewer_update(&viewer_palette, svga);
|
||||
viewer_update(&viewer_palette_16, svga);
|
||||
}
|
||||
if (changed) {
|
||||
viewer_update(&viewer_font, svga);
|
||||
viewer_update(&viewer_vram, svga);
|
||||
}
|
||||
}
|
||||
if (svga->vc == svga->vsyncstart) {
|
||||
int wx, wy;
|
||||
@@ -780,6 +793,11 @@ int svga_init(svga_t *svga, void *p, int memsize, void (*recalctimings_ex)(struc
|
||||
|
||||
svga->ramdac_type = RAMDAC_6BIT;
|
||||
|
||||
viewer_add("256-colour palette", &viewer_palette, svga);
|
||||
viewer_add("16-colour palette", &viewer_palette_16, svga);
|
||||
viewer_add("Font", &viewer_font, svga);
|
||||
viewer_add("Video memory", &viewer_vram, svga);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -20,6 +20,7 @@
|
||||
#include "vid_voodoo_regs.h"
|
||||
#include "vid_voodoo_render.h"
|
||||
#include "vid_voodoo_texture.h"
|
||||
#include "viewer.h"
|
||||
|
||||
rgba8_t rgb332[0x100], ai44[0x100], rgb565[0x10000], argb1555[0x10000], argb4444[0x10000], ai88[0x10000];
|
||||
|
||||
@@ -1156,6 +1157,8 @@ void *voodoo_2d3d_card_init(int type) {
|
||||
voodoo->disp_buffer = 0;
|
||||
voodoo->draw_buffer = 1;
|
||||
|
||||
viewer_add("3DFX Voodoo render", &viewer_voodoo, voodoo);
|
||||
|
||||
return voodoo;
|
||||
}
|
||||
|
||||
@@ -1209,6 +1212,8 @@ void *voodoo_init() {
|
||||
mem_mapping_add(&voodoo_set->snoop_mapping, 0, 0, NULL, voodoo_snoop_readw, voodoo_snoop_readl, NULL, voodoo_snoop_writew,
|
||||
voodoo_snoop_writel, NULL, MEM_MAPPING_EXTERNAL, voodoo_set);
|
||||
|
||||
viewer_add("3DFX Voodoo render", &viewer_voodoo, voodoo_set->voodoos[0]);
|
||||
|
||||
return voodoo_set;
|
||||
}
|
||||
|
||||
|
@@ -17,6 +17,8 @@
|
||||
#include "vid_voodoo_render.h"
|
||||
#include "vid_voodoo_setup.h"
|
||||
#include "vid_voodoo_texture.h"
|
||||
#include "viewer.h"
|
||||
#include "viewer_voodoo.h"
|
||||
|
||||
enum { CHIP_FBI = 0x1, CHIP_TREX0 = 0x2, CHIP_TREX1 = 0x4, CHIP_TREX2 = 0x8 };
|
||||
|
||||
@@ -43,6 +45,8 @@ void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) {
|
||||
// pclog("swapbufferCMD %08x %08x\n", val, voodoo->leftOverlayBuf);
|
||||
|
||||
voodoo_wait_for_render_thread_idle(voodoo);
|
||||
if (voodoo->viewer_active)
|
||||
viewer_call(&viewer_voodoo, voodoo, voodoo_viewer_swap_buffer, NULL);
|
||||
if (!(val & 1)) {
|
||||
banshee_set_overlay_addr(voodoo->p, voodoo->leftOverlayBuf);
|
||||
thread_lock_mutex(voodoo->swap_mutex);
|
||||
@@ -82,6 +86,8 @@ void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) {
|
||||
// pclog("Swap buffer %08x %d %p %i\n", val, voodoo->swap_count, &voodoo->swap_count, (voodoo ==
|
||||
// voodoo->set->voodoos[1]) ? 1 : 0); voodoo->front_offset = params->front_offset;
|
||||
voodoo_wait_for_render_thread_idle(voodoo);
|
||||
if (voodoo->viewer_active)
|
||||
viewer_call(&viewer_voodoo, voodoo, voodoo_viewer_swap_buffer, NULL);
|
||||
if (!(val & 1)) {
|
||||
memset(voodoo->dirty_line, 1, sizeof(voodoo->dirty_line));
|
||||
voodoo->front_offset = voodoo->params.front_offset;
|
||||
@@ -265,6 +271,11 @@ void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) {
|
||||
|
||||
case SST_triangleCMD:
|
||||
case SST_remap_triangleCMD:
|
||||
if (voodoo->in_strip) {
|
||||
voodoo->in_strip = 0;
|
||||
if (voodoo->viewer_active)
|
||||
viewer_call(&viewer_voodoo, voodoo, voodoo_viewer_end_strip, NULL);
|
||||
}
|
||||
voodoo->params.sign = val & (1 << 31);
|
||||
|
||||
if (voodoo->ncc_dirty[0])
|
||||
@@ -466,6 +477,11 @@ void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) {
|
||||
break;
|
||||
|
||||
case SST_ftriangleCMD:
|
||||
if (voodoo->in_strip) {
|
||||
voodoo->in_strip = 0;
|
||||
if (voodoo->viewer_active)
|
||||
viewer_call(&viewer_voodoo, voodoo, voodoo_viewer_end_strip, NULL);
|
||||
}
|
||||
voodoo->params.sign = val & (1 << 31);
|
||||
|
||||
if (voodoo->ncc_dirty[0])
|
||||
@@ -745,6 +761,9 @@ void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) {
|
||||
|
||||
voodoo->num_verticies = 1;
|
||||
voodoo->cull_pingpong = 0;
|
||||
if (voodoo->viewer_active)
|
||||
viewer_call(&viewer_voodoo, voodoo, voodoo_viewer_begin_strip, NULL);
|
||||
voodoo->in_strip = 1;
|
||||
break;
|
||||
case SST_sDrawTriCMD:
|
||||
// pclog("sDrawTriCMD %i %i\n", voodoo->num_verticies, voodoo->sSetupMode & SETUPMODE_STRIP_MODE);
|
||||
|
@@ -12,6 +12,8 @@
|
||||
#include "vid_voodoo_regs.h"
|
||||
#include "vid_voodoo_render.h"
|
||||
#include "vid_voodoo_texture.h"
|
||||
#include "viewer.h"
|
||||
#include "viewer_voodoo.h"
|
||||
|
||||
typedef struct voodoo_state_t {
|
||||
int xstart, xend, xdir;
|
||||
@@ -1504,6 +1506,9 @@ void voodoo_queue_triangle(voodoo_t *voodoo, voodoo_params_t *params) {
|
||||
if (voodoo->dual_tmus)
|
||||
voodoo_use_texture(voodoo, params, 1);
|
||||
|
||||
if (voodoo->viewer_active)
|
||||
viewer_call(&viewer_voodoo, voodoo, voodoo_viewer_queue_triangle, NULL);
|
||||
|
||||
memcpy(params_new, params, sizeof(voodoo_params_t));
|
||||
|
||||
voodoo->params_write_idx++;
|
||||
|
@@ -12,6 +12,8 @@
|
||||
#include "vid_voodoo_regs.h"
|
||||
#include "vid_voodoo_render.h"
|
||||
#include "vid_voodoo_texture.h"
|
||||
#include "viewer.h"
|
||||
#include "viewer_voodoo.h"
|
||||
|
||||
void voodoo_recalc_tex(voodoo_t *voodoo, int tmu) {
|
||||
int aspect = (voodoo->params.tLOD[tmu] >> 21) & 3;
|
||||
@@ -133,6 +135,7 @@ void voodoo_use_texture(voodoo_t *voodoo, voodoo_params_t *params, int tmu) {
|
||||
else
|
||||
addr = params->texBaseAddr[tmu];
|
||||
|
||||
|
||||
/*Try to find texture in cache*/
|
||||
for (c = 0; c < TEX_CACHE_MAX; c++) {
|
||||
if (voodoo->texture_cache[tmu][c].base == addr &&
|
||||
@@ -140,6 +143,8 @@ void voodoo_use_texture(voodoo_t *voodoo, voodoo_params_t *params, int tmu) {
|
||||
voodoo->texture_cache[tmu][c].palette_checksum == palette_checksum) {
|
||||
params->tex_entry[tmu] = c;
|
||||
voodoo->texture_cache[tmu][c].refcount++;
|
||||
if (voodoo->viewer_active)
|
||||
viewer_call(&viewer_voodoo, voodoo, voodoo_viewer_use_texture, (void *)(uintptr_t)tmu);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -428,6 +433,9 @@ void voodoo_use_texture(voodoo_t *voodoo, voodoo_params_t *params, int tmu) {
|
||||
|
||||
params->tex_entry[tmu] = c;
|
||||
voodoo->texture_cache[tmu][c].refcount++;
|
||||
|
||||
if (voodoo->viewer_active)
|
||||
viewer_call(&viewer_voodoo, voodoo, voodoo_viewer_use_texture, (void *)(uintptr_t)tmu);
|
||||
}
|
||||
|
||||
void flush_texture_cache(voodoo_t *voodoo, uint32_t dirty_addr, int tmu) {
|
||||
|
251
src/wx-ui/pc.xrc
251
src/wx-ui/pc.xrc
@@ -490,6 +490,9 @@
|
||||
<label>_Machine</label>
|
||||
</object>
|
||||
</object>
|
||||
<object class="wxMenu" name="IDM_VIEW">
|
||||
<label>_View</label>
|
||||
</object>
|
||||
</object>
|
||||
|
||||
<ids-range name="IDC_HDPANEL" start="10" />
|
||||
@@ -1600,7 +1603,7 @@
|
||||
<flag>wxEXPAND</flag>
|
||||
<border>5</border>
|
||||
<object class="wxBoxSizer">
|
||||
<orient>wxHORIZONTAL</orient>
|
||||
<orient>wxHORIZONTAL</orient>
|
||||
<object class="sizeritem">
|
||||
<option>0</option>
|
||||
<flag>wxALL</flag>
|
||||
@@ -1788,7 +1791,7 @@
|
||||
<flag>wxEXPAND</flag>
|
||||
<border>5</border>
|
||||
<object class="wxBoxSizer">
|
||||
<orient>wxHORIZONTAL</orient>
|
||||
<orient>wxHORIZONTAL</orient>
|
||||
<object class="sizeritem">
|
||||
<option>0</option>
|
||||
<flag>wxALL</flag>
|
||||
@@ -1976,7 +1979,7 @@
|
||||
<flag>wxEXPAND</flag>
|
||||
<border>5</border>
|
||||
<object class="wxBoxSizer">
|
||||
<orient>wxHORIZONTAL</orient>
|
||||
<orient>wxHORIZONTAL</orient>
|
||||
<object class="sizeritem">
|
||||
<option>0</option>
|
||||
<flag>wxALL</flag>
|
||||
@@ -2164,7 +2167,7 @@
|
||||
<flag>wxEXPAND</flag>
|
||||
<border>5</border>
|
||||
<object class="wxBoxSizer">
|
||||
<orient>wxHORIZONTAL</orient>
|
||||
<orient>wxHORIZONTAL</orient>
|
||||
<object class="sizeritem">
|
||||
<option>0</option>
|
||||
<flag>wxALL</flag>
|
||||
@@ -2352,7 +2355,7 @@
|
||||
<flag>wxEXPAND</flag>
|
||||
<border>5</border>
|
||||
<object class="wxBoxSizer">
|
||||
<orient>wxHORIZONTAL</orient>
|
||||
<orient>wxHORIZONTAL</orient>
|
||||
<object class="sizeritem">
|
||||
<option>0</option>
|
||||
<flag>wxALL</flag>
|
||||
@@ -2540,7 +2543,7 @@
|
||||
<flag>wxEXPAND</flag>
|
||||
<border>5</border>
|
||||
<object class="wxBoxSizer">
|
||||
<orient>wxHORIZONTAL</orient>
|
||||
<orient>wxHORIZONTAL</orient>
|
||||
<object class="sizeritem">
|
||||
<option>0</option>
|
||||
<flag>wxALL</flag>
|
||||
@@ -2728,7 +2731,7 @@
|
||||
<flag>wxEXPAND</flag>
|
||||
<border>5</border>
|
||||
<object class="wxBoxSizer">
|
||||
<orient>wxHORIZONTAL</orient>
|
||||
<orient>wxHORIZONTAL</orient>
|
||||
<object class="sizeritem">
|
||||
<option>0</option>
|
||||
<flag>wxALL</flag>
|
||||
@@ -2893,7 +2896,7 @@
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
|
||||
|
||||
<object class="wxDialog" name="HdNewDlg">
|
||||
<title>New Hard Disc</title>
|
||||
<centered>1</centered>
|
||||
@@ -3521,7 +3524,7 @@
|
||||
<border>0</border>
|
||||
<object class="wxBoxSizer">
|
||||
<orient>wxVERTICAL</orient>
|
||||
|
||||
|
||||
<object class="sizeritem">
|
||||
<flag>wxALL</flag>
|
||||
<border>0</border>
|
||||
@@ -3529,7 +3532,7 @@
|
||||
<label>Add</label>
|
||||
</object>
|
||||
</object>
|
||||
|
||||
|
||||
<object class="sizeritem">
|
||||
<flag>wxALL</flag>
|
||||
<border>0</border>
|
||||
@@ -3537,12 +3540,12 @@
|
||||
<label>Remove</label>
|
||||
</object>
|
||||
</object>
|
||||
|
||||
|
||||
<object class="spacer">
|
||||
<option>1</option>
|
||||
<flag>wxEXPAND</flag>
|
||||
</object>
|
||||
|
||||
|
||||
<object class="sizeritem">
|
||||
<flag>wxALL</flag>
|
||||
<border>0</border>
|
||||
@@ -3550,7 +3553,7 @@
|
||||
<label>Configure...</label>
|
||||
</object>
|
||||
</object>
|
||||
|
||||
|
||||
<object class="sizeritem">
|
||||
<flag>wxALL</flag>
|
||||
<border>0</border>
|
||||
@@ -3558,7 +3561,7 @@
|
||||
<label>Move up</label>
|
||||
</object>
|
||||
</object>
|
||||
|
||||
|
||||
<object class="sizeritem">
|
||||
<flag>wxALL</flag>
|
||||
<border>0</border>
|
||||
@@ -3566,7 +3569,7 @@
|
||||
<label>Move down</label>
|
||||
</object>
|
||||
</object>
|
||||
|
||||
|
||||
<object class="spacer">
|
||||
<option>1</option>
|
||||
<flag>wxEXPAND</flag>
|
||||
@@ -3668,7 +3671,7 @@
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
|
||||
|
||||
<object class="wxDialog" name="CustomResolutionDlg">
|
||||
<style>wxDEFAULT_DIALOG_STYLE|wxSTAY_ON_TOP</style>
|
||||
<title>Custom resolution</title>
|
||||
@@ -3748,7 +3751,221 @@
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
|
||||
|
||||
|
||||
<object class="wxPanel" name="ViewerVRAMPanel">
|
||||
<style>wxTAB_TRAVERSAL | wxVSCROLL | wxALWAYS_SHOW_SB</style>
|
||||
<object class="wxBoxSizer">
|
||||
<orient>wxVERTICAL</orient>
|
||||
<object class="sizeritem">
|
||||
<option>0</option>
|
||||
<flag>wxALL</flag>
|
||||
<border>5</border>
|
||||
<object class="wxStaticText">
|
||||
<label>Start address:</label>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<option>0</option>
|
||||
<flag>wxALL</flag>
|
||||
<object class="wxRadioButton" name="IDC_STARTADDR_CURRENT">
|
||||
<label>Current (xxxxxxx)</label>
|
||||
<style>wxRB_GROUP</style>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<option>0</option>
|
||||
<flag>wxALL</flag>
|
||||
<object class="wxBoxSizer">
|
||||
<orient>wxHORIZONTAL</orient>
|
||||
<object class="sizeritem">
|
||||
<option>0</option>
|
||||
<flag>wxALL</flag>
|
||||
<object class="wxRadioButton" name="IDC_STARTADDR_CUSTOM">
|
||||
<label>Custom</label>
|
||||
<value>1</value>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<option>0</option>
|
||||
<flag>wxALL</flag>
|
||||
<object class="wxTextCtrl" name="IDC_STARTADDR_TEXTCTRL">
|
||||
<value>0</value>
|
||||
<style>wxTE_PROCESS_ENTER</style>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<option>0</option>
|
||||
<flag>wxALL</flag>
|
||||
<border>5</border>
|
||||
<object class="wxStaticText">
|
||||
<label>Pitch:</label>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<option>0</option>
|
||||
<flag>wxALL</flag>
|
||||
<object class="wxRadioButton" name="IDC_PITCH_CURRENT">
|
||||
<label>Current (xxxxxxx)</label>
|
||||
<style>wxRB_GROUP</style>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<option>0</option>
|
||||
<flag>wxALL</flag>
|
||||
<object class="wxBoxSizer">
|
||||
<orient>wxHORIZONTAL</orient>
|
||||
<object class="sizeritem">
|
||||
<option>0</option>
|
||||
<flag>wxALL</flag>
|
||||
<object class="wxRadioButton" name="IDC_PITCH_CUSTOM">
|
||||
<label>Custom</label>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<option>0</option>
|
||||
<flag>wxALL</flag>
|
||||
<object class="wxTextCtrl" name="IDC_PITCH_TEXTCTRL">
|
||||
<value>80</value>
|
||||
<style>wxTE_PROCESS_ENTER</style>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<option>0</option>
|
||||
<flag>wxALL</flag>
|
||||
<border>5</border>
|
||||
<object class="wxStaticText">
|
||||
<label>Colour depth:</label>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<option>0</option>
|
||||
<flag>wxALL</flag>
|
||||
<object class="wxRadioButton" name="IDC_DEPTH_CURRENT">
|
||||
<label>Current (xxxxxxx)</label>
|
||||
<style>wxRB_GROUP</style>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<option>0</option>
|
||||
<flag>wxALL</flag>
|
||||
<object class="wxRadioButton" name="IDC_DEPTH_1BPP">
|
||||
<label>2 colours</label>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<option>0</option>
|
||||
<flag>wxALL</flag>
|
||||
<object class="wxRadioButton" name="IDC_DEPTH_2BPP">
|
||||
<label>4 colours</label>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<option>0</option>
|
||||
<flag>wxALL</flag>
|
||||
<object class="wxRadioButton" name="IDC_DEPTH_4BPP">
|
||||
<label>16 colours</label>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<option>0</option>
|
||||
<flag>wxALL</flag>
|
||||
<object class="wxRadioButton" name="IDC_DEPTH_8BPP">
|
||||
<label>256 colours</label>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<option>0</option>
|
||||
<flag>wxALL</flag>
|
||||
<object class="wxRadioButton" name="IDC_DEPTH_1555">
|
||||
<label>32k colours (555) </label>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<option>0</option>
|
||||
<flag>wxALL</flag>
|
||||
<object class="wxRadioButton" name="IDC_DEPTH_565">
|
||||
<label>64k colours (565)</label>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<option>0</option>
|
||||
<flag>wxALL</flag>
|
||||
<object class="wxRadioButton" name="IDC_DEPTH_888">
|
||||
<label>16M colours (888)</label>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<option>0</option>
|
||||
<flag>wxALL</flag>
|
||||
<object class="wxRadioButton" name="IDC_DEPTH_8888">
|
||||
<label>16M colours (8888)</label>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<option>0</option>
|
||||
<flag>wxALL</flag>
|
||||
<border>5</border>
|
||||
<object class="wxStaticText">
|
||||
<label>Address mode:</label>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<option>0</option>
|
||||
<flag>wxALL</flag>
|
||||
<object class="wxRadioButton" name="IDC_ADDRMODE_CURRENT">
|
||||
<label>Current</label>
|
||||
<style>wxRB_GROUP</style>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<option>0</option>
|
||||
<flag>wxALL</flag>
|
||||
<object class="wxRadioButton" name="IDC_ADDRMODE_NORMAL">
|
||||
<label>Normal</label>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<option>0</option>
|
||||
<flag>wxALL</flag>
|
||||
<object class="wxRadioButton" name="IDC_ADDRMODE_ODDEVEN">
|
||||
<label>Odd/even</label>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<option>0</option>
|
||||
<flag>wxALL</flag>
|
||||
<object class="wxRadioButton" name="IDC_ADDRMODE_CHAIN4">
|
||||
<label>Chain-4</label>
|
||||
</object>
|
||||
</object>
|
||||
|
||||
<object class="sizeritem">
|
||||
<option>0</option>
|
||||
<flag>wxALL</flag>
|
||||
<border>5</border>
|
||||
<object class="wxStaticText">
|
||||
<label>Scale factor:</label>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem">
|
||||
<option>0</option>
|
||||
<flag>wxALL</flag>
|
||||
<object class="wxSpinCtrl" name="IDC_SCALE">
|
||||
<style>wxSP_ARROW_KEYS</style>
|
||||
<value>1</value>
|
||||
<min>1</min>
|
||||
<max>16</max>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
|
||||
|
||||
<object class="wxDialog" name="AboutDlg">
|
||||
<style>wxDEFAULT_DIALOG_STYLE</style>
|
||||
<title></title>
|
||||
|
120
src/wx-ui/viewers/viewer.cc
Normal file
120
src/wx-ui/viewers/viewer.cc
Normal file
@@ -0,0 +1,120 @@
|
||||
#include <wx/wxprec.h>
|
||||
#ifndef WX_PRECOMP
|
||||
#include <wx/wx.h>
|
||||
#endif
|
||||
#include <wx/xrc/xmlres.h>
|
||||
|
||||
#include "viewer.h"
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
extern "C" void pclog(const char *format, ...);
|
||||
|
||||
class ViewerRout
|
||||
{
|
||||
public:
|
||||
const std::string title;
|
||||
viewer_t *viewer;
|
||||
void *p;
|
||||
|
||||
ViewerRout()
|
||||
{
|
||||
}
|
||||
ViewerRout(char *title, viewer_t *viewer, void *p) : title(title), viewer(viewer), p(p)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
std::vector<ViewerRout> viewer_routs;
|
||||
std::list<Viewer *> viewer_windows;
|
||||
|
||||
void viewer_reset()
|
||||
{
|
||||
viewer_routs.clear();
|
||||
viewer_windows.clear();
|
||||
}
|
||||
|
||||
void viewer_close_all()
|
||||
{
|
||||
std::list<Viewer *> viewer_windows_2 = viewer_windows;
|
||||
|
||||
for (std::list<Viewer *>::iterator it = viewer_windows_2.begin(); it != viewer_windows_2.end(); it++)
|
||||
(*it)->Close(true);
|
||||
}
|
||||
|
||||
void viewer_add(char *title, viewer_t *viewer, void *p)
|
||||
{
|
||||
viewer_routs.push_back(ViewerRout(title, viewer, p));
|
||||
}
|
||||
|
||||
void viewer_open(void *parent, int id)
|
||||
{
|
||||
Viewer *i = (Viewer *)viewer_routs[id].viewer->open(parent, viewer_routs[id].p, viewer_routs[id].title.c_str());
|
||||
if (i)
|
||||
viewer_windows.push_back(i);
|
||||
}
|
||||
|
||||
void viewer_remove(void *viewer)
|
||||
{
|
||||
viewer_windows.remove((Viewer *)viewer);
|
||||
}
|
||||
|
||||
void viewer_update(viewer_t *viewer, void *p)
|
||||
{
|
||||
for (std::list<Viewer *>::iterator it = viewer_windows.begin(); it != viewer_windows.end(); it++)
|
||||
{
|
||||
if ((*it)->p == p)
|
||||
{
|
||||
(*it)->Refresh();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void viewer_notify_pause()
|
||||
{
|
||||
for (std::list<Viewer *>::iterator it = viewer_windows.begin(); it != viewer_windows.end(); it++)
|
||||
{
|
||||
(*it)->NotifyPause();
|
||||
}
|
||||
}
|
||||
|
||||
void viewer_notify_resume()
|
||||
{
|
||||
for (std::list<Viewer *>::iterator it = viewer_windows.begin(); it != viewer_windows.end(); it++)
|
||||
{
|
||||
(*it)->NotifyResume();
|
||||
}
|
||||
}
|
||||
|
||||
void viewer_call(viewer_t *viewer, void *p, void (*func)(void *v, void *param), void *param)
|
||||
{
|
||||
for (std::list<Viewer *>::iterator it = viewer_windows.begin(); it != viewer_windows.end(); it++)
|
||||
{
|
||||
if ((*it)->p == p)
|
||||
{
|
||||
func(*it, param);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void update_viewers_menu(void *menu)
|
||||
{
|
||||
wxMenuItem *m = ((wxMenu *)menu)->FindItem(XRCID("IDM_VIEW"));
|
||||
wxMenu *wm = m->GetSubMenu();
|
||||
|
||||
for (int i = IDM_VIEWER; i < IDM_VIEWER_MAX; i++)
|
||||
{
|
||||
wxMenuItem *menu_item = wm->FindChildItem(i);
|
||||
|
||||
if (menu_item)
|
||||
wm->Delete(i);
|
||||
}
|
||||
|
||||
int id = IDM_VIEWER;
|
||||
|
||||
for (std::vector<ViewerRout>::iterator it = viewer_routs.begin(); it != viewer_routs.end(); it++)
|
||||
{
|
||||
wm->Append(id++, (*it).title, wxEmptyString, wxITEM_NORMAL);
|
||||
}
|
||||
}
|
99
src/wx-ui/viewers/viewer_font.cc
Normal file
99
src/wx-ui/viewers/viewer_font.cc
Normal file
@@ -0,0 +1,99 @@
|
||||
#include <wx/wxprec.h>
|
||||
#ifndef WX_PRECOMP
|
||||
#include <wx/wx.h>
|
||||
#endif
|
||||
#include <wx/rawbmp.h>
|
||||
#include "viewer.h"
|
||||
extern "C"
|
||||
{
|
||||
#include "ibm.h"
|
||||
#include "mem.h"
|
||||
#include "video.h"
|
||||
#include "vid_svga.h"
|
||||
}
|
||||
|
||||
class ViewerFont: public Viewer
|
||||
{
|
||||
private:
|
||||
svga_t *svga;
|
||||
wxImage buffer;
|
||||
|
||||
void OnPaint(wxPaintEvent &event)
|
||||
{
|
||||
wxPaintDC dc(this);
|
||||
wxCoord w, h;
|
||||
|
||||
dc.GetSize(&w, &h);
|
||||
|
||||
dc.SetBackground(*wxBLACK_BRUSH);
|
||||
dc.Clear();
|
||||
|
||||
unsigned char *buffer_data = buffer.GetData();
|
||||
int buffer_width = buffer.GetWidth();
|
||||
|
||||
for (int y = 0; y < 16; y++)
|
||||
{
|
||||
int font_base = ((y & 8) ? svga->charsetb : svga->charseta) + ((y & 7) * 32 * 128);
|
||||
|
||||
for (int x = 0; x < 32; x++)
|
||||
{
|
||||
int font_addr = font_base + x * 128;
|
||||
|
||||
for (int yy = 0; yy < 16; yy++)
|
||||
{
|
||||
unsigned char *data = buffer_data + (y * 16 + yy) * 3 * buffer_width + x * 8 * 3;
|
||||
|
||||
for (int xx = 0; xx < 8; xx++)
|
||||
{
|
||||
*data++ = (svga->vram[font_addr] & (0x80 >> xx)) ? 0xff : 0;
|
||||
*data++ = (svga->vram[font_addr] & (0x80 >> xx)) ? 0xff : 0;
|
||||
*data++ = (svga->vram[font_addr] & (0x80 >> xx)) ? 0xff : 0;
|
||||
}
|
||||
|
||||
font_addr += 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wxBitmap bitmap(buffer);
|
||||
|
||||
wxMemoryDC mdc(bitmap);
|
||||
|
||||
dc.StretchBlit(0, 0, w, h, &mdc, 0, 0, 256, 256);
|
||||
|
||||
}
|
||||
|
||||
void OnClose(wxCloseEvent &event)
|
||||
{
|
||||
viewer_remove(this);
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
public:
|
||||
ViewerFont(wxWindow *parent, wxString title, wxSize size, void *p)
|
||||
: Viewer(parent, title, size, p),
|
||||
svga((svga_t *)p),
|
||||
buffer(256, 256)
|
||||
{
|
||||
Bind(wxEVT_CLOSE_WINDOW, &ViewerFont::OnClose, this);
|
||||
Bind(wxEVT_PAINT, &ViewerFont::OnPaint, this);
|
||||
}
|
||||
|
||||
virtual ~ViewerFont()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
static void *viewer_font_open(void *parent, void *p, const char *title)
|
||||
{
|
||||
wxFrame *w = new ViewerFont((wxWindow *)parent, title, wxSize(256, 256), p);
|
||||
|
||||
w->Show(true);
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
viewer_t viewer_font =
|
||||
{
|
||||
.open = viewer_font_open
|
||||
};
|
159
src/wx-ui/viewers/viewer_palette.cc
Normal file
159
src/wx-ui/viewers/viewer_palette.cc
Normal file
@@ -0,0 +1,159 @@
|
||||
#include <wx/wxprec.h>
|
||||
#ifndef WX_PRECOMP
|
||||
#include <wx/wx.h>
|
||||
#endif
|
||||
#include <wx/rawbmp.h>
|
||||
#include "viewer.h"
|
||||
extern "C"
|
||||
{
|
||||
#include "ibm.h"
|
||||
#include "mem.h"
|
||||
#include "video.h"
|
||||
#include "vid_svga.h"
|
||||
}
|
||||
|
||||
class ViewerPalette: public Viewer
|
||||
{
|
||||
private:
|
||||
svga_t *svga;
|
||||
wxBitmap buffer;
|
||||
|
||||
void OnPaint(wxPaintEvent &event)
|
||||
{
|
||||
wxPaintDC dc(this);
|
||||
wxCoord w, h;
|
||||
|
||||
dc.GetSize(&w, &h);
|
||||
|
||||
dc.SetBackground(*wxBLACK_BRUSH);
|
||||
dc.Clear();
|
||||
|
||||
{
|
||||
wxNativePixelData data(buffer);
|
||||
wxNativePixelData::Iterator p(data);
|
||||
|
||||
for (int y = 0; y < 16; y++)
|
||||
{
|
||||
wxNativePixelData::Iterator rowStart = p;
|
||||
|
||||
for (int x = 0; x < 16; x++)
|
||||
{
|
||||
p.Red() = svga->vgapal[x + y*16].r * 4;
|
||||
p.Green() = svga->vgapal[x + y*16].g * 4;
|
||||
p.Blue() = svga->vgapal[x + y*16].b * 4;
|
||||
p++;
|
||||
}
|
||||
|
||||
p = rowStart;
|
||||
p.OffsetY(data, 1);
|
||||
}
|
||||
}
|
||||
|
||||
wxMemoryDC mdc(buffer);
|
||||
|
||||
dc.StretchBlit(0, 0, w, h, &mdc, 0, 0, 16, 16);
|
||||
}
|
||||
|
||||
void OnClose(wxCloseEvent &event)
|
||||
{
|
||||
viewer_remove(this);
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
public:
|
||||
ViewerPalette(wxWindow *parent, wxString title, wxSize size, void *p)
|
||||
: Viewer(parent, title, size, p),
|
||||
svga((svga_t *)p),
|
||||
buffer(16, 16, 24)
|
||||
{
|
||||
Bind(wxEVT_CLOSE_WINDOW, &ViewerPalette::OnClose, this);
|
||||
Bind(wxEVT_PAINT, &ViewerPalette::OnPaint, this);
|
||||
}
|
||||
|
||||
virtual ~ViewerPalette()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
static void *viewer_palette_open(void *parent, void *p, const char *title)
|
||||
{
|
||||
wxFrame *w = new ViewerPalette((wxWindow *)parent, title, wxSize(256, 256), p);
|
||||
|
||||
w->Show(true);
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
viewer_t viewer_palette =
|
||||
{
|
||||
.open = viewer_palette_open
|
||||
};
|
||||
|
||||
class ViewerPalette16: public Viewer
|
||||
{
|
||||
private:
|
||||
svga_t *svga;
|
||||
wxBitmap buffer;
|
||||
|
||||
void OnPaint(wxPaintEvent &event)
|
||||
{
|
||||
wxPaintDC dc(this);
|
||||
wxCoord w, h;
|
||||
|
||||
dc.GetSize(&w, &h);
|
||||
|
||||
dc.SetBackground(*wxBLACK_BRUSH);
|
||||
dc.Clear();
|
||||
|
||||
{
|
||||
wxNativePixelData data(buffer);
|
||||
wxNativePixelData::Iterator p(data);
|
||||
|
||||
for (int x = 0; x < 16; x++)
|
||||
{
|
||||
p.Red() = svga->vgapal[svga->egapal[x]].r * 4;
|
||||
p.Green() = svga->vgapal[svga->egapal[x]].g * 4;
|
||||
p.Blue() = svga->vgapal[svga->egapal[x]].b * 4;
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
wxMemoryDC mdc(buffer);
|
||||
|
||||
dc.StretchBlit(0, 0, w, h, &mdc, 0, 0, 16, 1);
|
||||
}
|
||||
|
||||
void OnClose(wxCloseEvent &event)
|
||||
{
|
||||
viewer_remove(this);
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
public:
|
||||
ViewerPalette16(wxWindow *parent, wxString title, wxSize size, void *p)
|
||||
: Viewer(parent, title, size, p),
|
||||
svga((svga_t *)p),
|
||||
buffer(16, 1, 24)
|
||||
{
|
||||
Bind(wxEVT_CLOSE_WINDOW, &ViewerPalette16::OnClose, this);
|
||||
Bind(wxEVT_PAINT, &ViewerPalette16::OnPaint, this);
|
||||
}
|
||||
|
||||
virtual ~ViewerPalette16()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
static void *viewer_palette_16_open(void *parent, void *p, const char *title)
|
||||
{
|
||||
wxFrame *w = new ViewerPalette16((wxWindow *)parent, title, wxSize(256, 20), p);
|
||||
|
||||
w->Show(true);
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
viewer_t viewer_palette_16 =
|
||||
{
|
||||
.open = viewer_palette_16_open
|
||||
};
|
1088
src/wx-ui/viewers/viewer_voodoo.cc
Normal file
1088
src/wx-ui/viewers/viewer_voodoo.cc
Normal file
File diff suppressed because it is too large
Load Diff
698
src/wx-ui/viewers/viewer_vram.cc
Normal file
698
src/wx-ui/viewers/viewer_vram.cc
Normal file
@@ -0,0 +1,698 @@
|
||||
#include <wx/wxprec.h>
|
||||
#ifndef WX_PRECOMP
|
||||
#include <wx/wx.h>
|
||||
#endif
|
||||
#include <wx/rawbmp.h>
|
||||
#include <wx/spinctrl.h>
|
||||
#include <wx/xrc/xmlres.h>
|
||||
#include <string>
|
||||
#include "viewer.h"
|
||||
extern "C"
|
||||
{
|
||||
#include "ibm.h"
|
||||
#include "mem.h"
|
||||
#include "video.h"
|
||||
#include "vid_svga.h"
|
||||
}
|
||||
|
||||
enum ColourDepth
|
||||
{
|
||||
CD_1BPP,
|
||||
CD_2BPP,
|
||||
CD_4BPP,
|
||||
CD_8BPP,
|
||||
CD_1555,
|
||||
CD_565,
|
||||
CD_888,
|
||||
CD_8888
|
||||
};
|
||||
|
||||
enum AddrMode
|
||||
{
|
||||
AM_NORMAL,
|
||||
AM_ODDEVEN,
|
||||
AM_CHAIN4
|
||||
};
|
||||
|
||||
class ViewerVRAM;
|
||||
|
||||
class ViewerVRAMCanvas: public wxWindow
|
||||
{
|
||||
private:
|
||||
class ViewerVRAM *vram_parent;
|
||||
svga_t *svga;
|
||||
wxImage buffer;
|
||||
wxSize window_size;
|
||||
bool size_changed;
|
||||
uint32_t custom_start_addr;
|
||||
uint32_t custom_pitch;
|
||||
ColourDepth custom_colour_depth;
|
||||
AddrMode custom_addr_mode;
|
||||
bool use_custom_start_addr;
|
||||
bool use_custom_pitch;
|
||||
bool use_custom_colour_depth;
|
||||
bool use_custom_addr_mode;
|
||||
|
||||
int scroll_x_size, scroll_x_range;
|
||||
int scroll_y_size, scroll_y_range;
|
||||
|
||||
uint32_t current_start_addr;
|
||||
uint32_t current_pitch;
|
||||
int current_bpp;
|
||||
|
||||
int scale_factor;
|
||||
|
||||
void update_scroll(int new_x_size, int new_x_range, int new_y_size, int new_y_range)
|
||||
{
|
||||
scroll_x_size = new_x_size;
|
||||
scroll_x_range = new_x_range;
|
||||
scroll_y_size = new_y_size;
|
||||
scroll_y_range = new_y_range;
|
||||
|
||||
SetScrollbar(wxHORIZONTAL, GetScrollPos(wxHORIZONTAL), new_x_size, new_x_range);
|
||||
SetScrollbar(wxVERTICAL, GetScrollPos(wxVERTICAL), new_y_size, new_y_range);
|
||||
}
|
||||
|
||||
void UpdateLabels();
|
||||
|
||||
void OnPaint(wxPaintEvent &event)
|
||||
{
|
||||
wxPaintDC dc(this);
|
||||
wxCoord w, h, disp_w, disp_h;
|
||||
|
||||
dc.GetSize(&disp_w, &disp_h);
|
||||
w = disp_w / scale_factor;
|
||||
h = disp_h / scale_factor;
|
||||
|
||||
dc.SetBackground(*wxWHITE_BRUSH);
|
||||
dc.Clear();
|
||||
|
||||
uint32_t addr = use_custom_start_addr ? custom_start_addr : svga->ma_latch * 4;
|
||||
uint32_t mask = (svga->vram_mask << 2) | 3;
|
||||
|
||||
ColourDepth depth = custom_colour_depth;
|
||||
|
||||
if (!use_custom_colour_depth) {
|
||||
switch (svga->video_bpp) {
|
||||
case 2:
|
||||
depth = CD_2BPP;
|
||||
break;
|
||||
case 4:
|
||||
depth = CD_4BPP;
|
||||
break;
|
||||
case 8:
|
||||
depth = CD_8BPP;
|
||||
break;
|
||||
case 15:
|
||||
depth = CD_1555;
|
||||
break;
|
||||
case 16:
|
||||
depth = CD_565;
|
||||
break;
|
||||
case 24:
|
||||
depth = CD_888;
|
||||
break;
|
||||
case 32:
|
||||
depth = CD_8888;
|
||||
break;
|
||||
default:
|
||||
depth = CD_8BPP;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t offset = use_custom_pitch ? custom_pitch * 8 : svga->rowoffset * 8;
|
||||
int plot_width = 0;
|
||||
int line_width = 0;
|
||||
|
||||
switch (depth)
|
||||
{
|
||||
case CD_1BPP:
|
||||
plot_width = std::min((int)(w & ~3), (int)offset*8);
|
||||
line_width = offset * 8;
|
||||
break;
|
||||
|
||||
case CD_2BPP:
|
||||
plot_width = std::min((int)(w & ~3), (int)offset*4);
|
||||
line_width = offset * 4;
|
||||
break;
|
||||
|
||||
case CD_4BPP:
|
||||
plot_width = std::min((int)(w & ~3), (int)offset*2);
|
||||
line_width = offset * 2;
|
||||
break;
|
||||
|
||||
case CD_8BPP:
|
||||
plot_width = std::min((int)(w & ~3), (int)offset);
|
||||
line_width = offset;
|
||||
break;
|
||||
|
||||
case CD_1555:
|
||||
case CD_565:
|
||||
plot_width = std::min((int)(w & ~3), (int)offset / 2);
|
||||
line_width = offset / 2;
|
||||
break;
|
||||
|
||||
case CD_888:
|
||||
plot_width = std::min((int)(w & ~3), (int)offset / 3);
|
||||
line_width = offset / 3;
|
||||
break;
|
||||
|
||||
case CD_8888:
|
||||
plot_width = std::min((int)(w & ~3), (int)offset / 4);
|
||||
line_width = offset / 4;
|
||||
break;
|
||||
}
|
||||
|
||||
AddrMode addr_mode = custom_addr_mode;
|
||||
|
||||
if (!use_custom_addr_mode)
|
||||
{
|
||||
if (svga->fb_only)
|
||||
addr_mode = AM_NORMAL;
|
||||
else if (svga->chain4 && !svga->packed_chain4)
|
||||
addr_mode = AM_CHAIN4;
|
||||
else if (svga->chain2_write || svga->chain2_read)
|
||||
addr_mode = AM_ODDEVEN;
|
||||
else
|
||||
addr_mode = AM_NORMAL;
|
||||
}
|
||||
|
||||
int vram_height = offset ? (svga->vram_max / offset) : 1;
|
||||
|
||||
if (scroll_x_size != w || scroll_x_range != line_width || scroll_y_size != h || scroll_y_range != vram_height)
|
||||
update_scroll(w, line_width, h, vram_height);
|
||||
|
||||
int x_offset = GetScrollPos(wxHORIZONTAL);
|
||||
int y_offset = GetScrollPos(wxVERTICAL);
|
||||
unsigned char *buffer_data = buffer.GetData();
|
||||
|
||||
for (int y = 0; y < h; y++)
|
||||
{
|
||||
unsigned char *data = buffer_data + y*3*buffer.GetWidth();
|
||||
uint old_addr = addr;
|
||||
|
||||
addr += y_offset * offset;
|
||||
|
||||
switch (depth)
|
||||
{
|
||||
case CD_1BPP:
|
||||
addr += (x_offset / 2) & ~3;
|
||||
for (int x = 0; x < plot_width; x += 8)
|
||||
{
|
||||
uint32_t use_addr = addr;
|
||||
|
||||
if (addr_mode == AM_CHAIN4)
|
||||
use_addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff);
|
||||
else if (addr_mode == AM_ODDEVEN)
|
||||
use_addr = ((addr << 1) & 0x1fff8) | ((addr >> 15) & 0x4) | (addr & ~0x1ffff);
|
||||
|
||||
for (int xx = 0; xx < 8; xx++)
|
||||
{
|
||||
uint8_t pixel = 0;
|
||||
|
||||
if (svga->vram[use_addr & svga->vram_mask] & (0x80 >> xx))
|
||||
pixel |= 1;
|
||||
|
||||
*data++ = svga->vgapal[svga->egapal[pixel]].r * 4;
|
||||
*data++ = svga->vgapal[svga->egapal[pixel]].g * 4;
|
||||
*data++ = svga->vgapal[svga->egapal[pixel]].b * 4;
|
||||
}
|
||||
|
||||
addr += 4;
|
||||
}
|
||||
break;
|
||||
|
||||
case CD_2BPP:
|
||||
for (int x = 0; x < plot_width; x+= 4)
|
||||
{
|
||||
uint32_t use_addr = addr;
|
||||
|
||||
if (addr_mode == AM_CHAIN4)
|
||||
use_addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff);
|
||||
else if (addr_mode == AM_ODDEVEN)
|
||||
use_addr = ((addr << 1) & 0x1fff8) | ((addr >> 15) & 0x4) | (addr & ~0x1ffff);
|
||||
|
||||
uint16_t pix_data = *(uint16_t *)&svga->vram[use_addr & svga->vram_mask];
|
||||
|
||||
for (int xx = 0; xx < 8; xx++)
|
||||
{
|
||||
uint8_t pixel = pix_data >> 14;
|
||||
|
||||
*data++ = svga->vgapal[pixel].r * 4;
|
||||
*data++ = svga->vgapal[pixel].g * 4;
|
||||
*data++ = svga->vgapal[pixel].b * 4;
|
||||
|
||||
pix_data <<= 2;
|
||||
}
|
||||
|
||||
addr += 4;
|
||||
}
|
||||
break;
|
||||
|
||||
case CD_4BPP:
|
||||
addr += (x_offset / 2) & ~3;
|
||||
for (int x = 0; x < plot_width; x += 8)
|
||||
{
|
||||
uint32_t use_addr = addr;
|
||||
|
||||
if (addr_mode == AM_CHAIN4)
|
||||
use_addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff);
|
||||
else if (addr_mode == AM_ODDEVEN)
|
||||
use_addr = ((addr << 1) & 0x1fff8) | ((addr >> 15) & 0x4) | (addr & ~0x1ffff);
|
||||
|
||||
for (int xx = 0; xx < 8; xx++)
|
||||
{
|
||||
uint8_t pixel = 0;
|
||||
|
||||
if (svga->vram[use_addr & svga->vram_mask] & (0x80 >> xx))
|
||||
pixel |= 1;
|
||||
if (svga->vram[(use_addr + 1) & svga->vram_mask] & (0x80 >> xx))
|
||||
pixel |= 2;
|
||||
if (svga->vram[(use_addr + 2) & svga->vram_mask] & (0x80 >> xx))
|
||||
pixel |= 4;
|
||||
if (svga->vram[(use_addr + 3) & svga->vram_mask] & (0x80 >> xx))
|
||||
pixel |= 8;
|
||||
|
||||
*data++ = svga->vgapal[svga->egapal[pixel]].r * 4;
|
||||
*data++ = svga->vgapal[svga->egapal[pixel]].g * 4;
|
||||
*data++ = svga->vgapal[svga->egapal[pixel]].b * 4;
|
||||
}
|
||||
|
||||
addr += 4;
|
||||
}
|
||||
break;
|
||||
|
||||
case CD_8BPP:
|
||||
addr += x_offset & ~3;
|
||||
for (int x = 0; x < plot_width; x += 4)
|
||||
{
|
||||
uint32_t use_addr = addr;
|
||||
|
||||
if (addr_mode == AM_CHAIN4)
|
||||
use_addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff);
|
||||
else if (addr_mode == AM_ODDEVEN)
|
||||
use_addr = ((addr << 1) & 0x1fff8) | ((addr >> 15) & 0x4) | (addr & ~0x1ffff);
|
||||
|
||||
for (int xx = 0; xx < 4; xx++)
|
||||
{
|
||||
uint8_t pixel = svga->vram[(use_addr + xx) & svga->vram_mask];
|
||||
|
||||
*data++ = svga->vgapal[pixel].r * 4;
|
||||
*data++ = svga->vgapal[pixel].g * 4;
|
||||
*data++ = svga->vgapal[pixel].b * 4;
|
||||
}
|
||||
|
||||
addr += 4;
|
||||
}
|
||||
break;
|
||||
|
||||
case CD_1555:
|
||||
addr += (x_offset * 2) & ~3;
|
||||
for (int x = 0; x < plot_width; x += 2)
|
||||
{
|
||||
uint32_t use_addr = addr;
|
||||
|
||||
if (addr_mode == AM_CHAIN4)
|
||||
use_addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff);
|
||||
else if (addr_mode == AM_ODDEVEN)
|
||||
use_addr = ((addr << 1) & 0x1fff8) | ((addr >> 15) & 0x4) | (addr & ~0x1ffff);
|
||||
|
||||
for (int xx = 0; xx < 2; xx++)
|
||||
{
|
||||
uint16_t pixel = *(uint16_t *)&svga->vram[(use_addr + xx*2) & svga->vram_mask];
|
||||
|
||||
*data++ = video_15to32[pixel] >> 16;
|
||||
*data++ = video_15to32[pixel] >> 8;
|
||||
*data++ = video_15to32[pixel] & 0xff;
|
||||
}
|
||||
|
||||
addr += 4;
|
||||
}
|
||||
break;
|
||||
|
||||
case CD_565:
|
||||
addr += (x_offset * 2) & ~3;
|
||||
for (int x = 0; x < plot_width; x += 2)
|
||||
{
|
||||
uint32_t use_addr = addr;
|
||||
|
||||
if (addr_mode == AM_CHAIN4)
|
||||
use_addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff);
|
||||
else if (addr_mode == AM_ODDEVEN)
|
||||
use_addr = ((addr << 1) & 0x1fff8) | ((addr >> 15) & 0x4) | (addr & ~0x1ffff);
|
||||
|
||||
for (int xx = 0; xx < 2; xx++)
|
||||
{
|
||||
uint16_t pixel = *(uint16_t *)&svga->vram[(use_addr + xx*2) & svga->vram_mask];
|
||||
|
||||
*data++ = video_16to32[pixel] >> 16;
|
||||
*data++ = video_16to32[pixel] >> 8;
|
||||
*data++ = video_16to32[pixel] & 0xff;
|
||||
}
|
||||
|
||||
addr += 4;
|
||||
}
|
||||
break;
|
||||
|
||||
case CD_888:
|
||||
addr += (x_offset & ~3) * 3;
|
||||
for (int x = 0; x < plot_width; x += 4)
|
||||
{
|
||||
uint32_t use_addr = addr;
|
||||
|
||||
if (addr_mode == AM_CHAIN4)
|
||||
use_addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff);
|
||||
else if (addr_mode == AM_ODDEVEN)
|
||||
use_addr = ((addr << 1) & 0x1fff8) | ((addr >> 15) & 0x4) | (addr & ~0x1ffff);
|
||||
|
||||
for (int xx = 0; xx < 4; xx++)
|
||||
{
|
||||
*data++ = svga->vram[(use_addr + xx*3 + 2) & svga->vram_mask];
|
||||
*data++ = svga->vram[(use_addr + xx*3 + 1) & svga->vram_mask];
|
||||
*data++ = svga->vram[(use_addr + xx*3) & svga->vram_mask];
|
||||
}
|
||||
|
||||
addr += 12;
|
||||
}
|
||||
break;
|
||||
|
||||
case CD_8888:
|
||||
addr += x_offset * 4;
|
||||
for (int x = 0; x < plot_width; x++)
|
||||
{
|
||||
uint32_t use_addr = addr;
|
||||
|
||||
if (addr_mode == AM_CHAIN4)
|
||||
use_addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff);
|
||||
else if (addr_mode == AM_ODDEVEN)
|
||||
use_addr = ((addr << 1) & 0x1fff8) | ((addr >> 15) & 0x4) | (addr & ~0x1ffff);
|
||||
|
||||
uint32_t pixel = *(uint32_t *)&svga->vram[use_addr & svga->vram_mask];
|
||||
|
||||
*data++ = pixel >> 16;
|
||||
*data++ = pixel >> 8;
|
||||
*data++ = pixel & 0xff;
|
||||
|
||||
addr += 4;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
addr = old_addr + offset;
|
||||
}
|
||||
|
||||
wxBitmap bitmap(buffer);
|
||||
|
||||
wxMemoryDC mdc(bitmap);
|
||||
|
||||
if (scale_factor == 1)
|
||||
dc.Blit(0, 0, plot_width, h, &mdc, 0, 0);
|
||||
else
|
||||
dc.StretchBlit(0, 0, plot_width * scale_factor, h * scale_factor, &mdc, 0, 0, plot_width, h);
|
||||
|
||||
if (current_start_addr != svga->ma_latch * 4 || current_pitch != svga->rowoffset || current_bpp != svga->video_bpp)
|
||||
UpdateLabels();
|
||||
}
|
||||
|
||||
void OnSize(wxSizeEvent &event)
|
||||
{
|
||||
window_size = event.GetSize();
|
||||
}
|
||||
|
||||
void OnScroll(wxScrollWinEvent &event)
|
||||
{
|
||||
Refresh();
|
||||
}
|
||||
|
||||
public:
|
||||
ViewerVRAMCanvas(wxWindow *parent, const wxString& title, const wxPoint& pos, const wxSize& size, svga_t *svga, class ViewerVRAM *vram_parent)
|
||||
: wxWindow(parent, wxID_ANY, pos, size, wxDEFAULT_FRAME_STYLE | wxVSCROLL | wxHSCROLL | wxALWAYS_SHOW_SB),
|
||||
svga(svga),
|
||||
buffer(4096, 4096),
|
||||
window_size(wxSize(1, 1)),
|
||||
size_changed(false),
|
||||
custom_pitch(10),
|
||||
use_custom_start_addr(true), /*Start with VRAM address fixed to 0*/
|
||||
use_custom_pitch(false),
|
||||
use_custom_colour_depth(false),
|
||||
use_custom_addr_mode(false),
|
||||
custom_start_addr(0),
|
||||
vram_parent(vram_parent),
|
||||
scale_factor(1)
|
||||
{
|
||||
Bind(wxEVT_PAINT, &ViewerVRAMCanvas::OnPaint, this);
|
||||
Bind(wxEVT_SIZE, &ViewerVRAMCanvas::OnSize, this);
|
||||
Bind(wxEVT_SCROLLWIN_TOP, &ViewerVRAMCanvas::OnScroll, this);
|
||||
Bind(wxEVT_SCROLLWIN_BOTTOM, &ViewerVRAMCanvas::OnScroll, this);
|
||||
Bind(wxEVT_SCROLLWIN_LINEUP, &ViewerVRAMCanvas::OnScroll, this);
|
||||
Bind(wxEVT_SCROLLWIN_LINEDOWN, &ViewerVRAMCanvas::OnScroll, this);
|
||||
Bind(wxEVT_SCROLLWIN_PAGEUP, &ViewerVRAMCanvas::OnScroll, this);
|
||||
Bind(wxEVT_SCROLLWIN_PAGEDOWN, &ViewerVRAMCanvas::OnScroll, this);
|
||||
Bind(wxEVT_SCROLLWIN_THUMBTRACK, &ViewerVRAMCanvas::OnScroll, this);
|
||||
Bind(wxEVT_SCROLLWIN_THUMBRELEASE, &ViewerVRAMCanvas::OnScroll, this);
|
||||
}
|
||||
|
||||
virtual ~ViewerVRAMCanvas()
|
||||
{
|
||||
}
|
||||
|
||||
void set_custom_start_addr(uint32_t addr)
|
||||
{
|
||||
custom_start_addr = addr;
|
||||
Refresh();
|
||||
}
|
||||
|
||||
void set_use_custom_start_addr(bool use)
|
||||
{
|
||||
use_custom_start_addr = use;
|
||||
Refresh();
|
||||
}
|
||||
|
||||
void set_custom_pitch(uint32_t pitch)
|
||||
{
|
||||
custom_pitch = pitch;
|
||||
Refresh();
|
||||
}
|
||||
|
||||
void set_use_custom_pitch(bool use)
|
||||
{
|
||||
use_custom_pitch = use;
|
||||
Refresh();
|
||||
}
|
||||
|
||||
void set_custom_colour_depth(ColourDepth depth)
|
||||
{
|
||||
custom_colour_depth = depth;
|
||||
Refresh();
|
||||
}
|
||||
|
||||
void set_use_custom_colour_depth(bool use)
|
||||
{
|
||||
use_custom_colour_depth = use;
|
||||
Refresh();
|
||||
}
|
||||
|
||||
void set_custom_addr_mode(AddrMode mode)
|
||||
{
|
||||
custom_addr_mode = mode;
|
||||
Refresh();
|
||||
}
|
||||
|
||||
void set_use_custom_addr_mode(bool use)
|
||||
{
|
||||
use_custom_addr_mode = use;
|
||||
Refresh();
|
||||
}
|
||||
|
||||
void set_scale_factor(int new_scale_factor)
|
||||
{
|
||||
scale_factor = new_scale_factor;
|
||||
Refresh();
|
||||
}
|
||||
};
|
||||
|
||||
class ViewerVRAM: public Viewer
|
||||
{
|
||||
private:
|
||||
ViewerVRAMCanvas *canvas;
|
||||
wxBoxSizer *sz;
|
||||
wxPanel *panel;
|
||||
wxFrame *temp_frame;
|
||||
|
||||
void OnClose(wxCloseEvent &event)
|
||||
{
|
||||
viewer_remove(this);
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
void OnRadioButton(wxCommandEvent &event)
|
||||
{
|
||||
wxWindowID id = event.GetId();
|
||||
|
||||
if (id == XRCID("IDC_STARTADDR_CURRENT")) {
|
||||
canvas->set_use_custom_start_addr(false);
|
||||
} else if (id == XRCID("IDC_STARTADDR_CUSTOM")) {
|
||||
canvas->set_use_custom_start_addr(true);
|
||||
} else if (id == XRCID("IDC_PITCH_CURRENT")) {
|
||||
canvas->set_use_custom_pitch(false);
|
||||
} else if (id == XRCID("IDC_PITCH_CUSTOM")) {
|
||||
canvas->set_use_custom_pitch(true);
|
||||
} else if (id == XRCID("IDC_DEPTH_CURRENT")) {
|
||||
canvas->set_use_custom_colour_depth(false);
|
||||
} else if (id == XRCID("IDC_DEPTH_1BPP")) {
|
||||
canvas->set_use_custom_colour_depth(true);
|
||||
canvas->set_custom_colour_depth(CD_1BPP);
|
||||
} else if (id == XRCID("IDC_DEPTH_2BPP")) {
|
||||
canvas->set_use_custom_colour_depth(true);
|
||||
canvas->set_custom_colour_depth(CD_2BPP);
|
||||
} else if (id == XRCID("IDC_DEPTH_4BPP")) {
|
||||
canvas->set_use_custom_colour_depth(true);
|
||||
canvas->set_custom_colour_depth(CD_4BPP);
|
||||
} else if (id == XRCID("IDC_DEPTH_8BPP")) {
|
||||
canvas->set_use_custom_colour_depth(true);
|
||||
canvas->set_custom_colour_depth(CD_8BPP);
|
||||
} else if (id == XRCID("IDC_DEPTH_1555")) {
|
||||
canvas->set_use_custom_colour_depth(true);
|
||||
canvas->set_custom_colour_depth(CD_1555);
|
||||
} else if (id == XRCID("IDC_DEPTH_565")) {
|
||||
canvas->set_use_custom_colour_depth(true);
|
||||
canvas->set_custom_colour_depth(CD_565);
|
||||
} else if (id == XRCID("IDC_DEPTH_888")) {
|
||||
canvas->set_use_custom_colour_depth(true);
|
||||
canvas->set_custom_colour_depth(CD_888);
|
||||
} else if (id == XRCID("IDC_DEPTH_8888")) {
|
||||
canvas->set_use_custom_colour_depth(true);
|
||||
canvas->set_custom_colour_depth(CD_8888);
|
||||
} else if (id == XRCID("IDC_ADDRMODE_CURRENT")) {
|
||||
canvas->set_use_custom_addr_mode(false);
|
||||
} else if (id == XRCID("IDC_ADDRMODE_NORMAL")) {
|
||||
canvas->set_use_custom_addr_mode(true);
|
||||
canvas->set_custom_addr_mode(AM_NORMAL);
|
||||
} else if (id == XRCID("IDC_ADDRMODE_ODDEVEN")) {
|
||||
canvas->set_use_custom_addr_mode(false);
|
||||
canvas->set_custom_addr_mode(AM_ODDEVEN);
|
||||
} else if (id == XRCID("IDC_ADDRMODE_CHAIN4")) {
|
||||
canvas->set_use_custom_addr_mode(false);
|
||||
canvas->set_custom_addr_mode(AM_CHAIN4);
|
||||
}
|
||||
}
|
||||
|
||||
void OnText(wxCommandEvent &event)
|
||||
{
|
||||
wxWindowID id = event.GetId();
|
||||
|
||||
if (id == XRCID("IDC_STARTADDR_TEXTCTRL")) {
|
||||
unsigned long addr = 0;
|
||||
wxTextCtrl *text_ctrl = static_cast<wxTextCtrl *>(event.GetEventObject());
|
||||
|
||||
text_ctrl->GetValue().ToULong(&addr, 16);
|
||||
canvas->set_custom_start_addr(addr);
|
||||
} else if (id == XRCID("IDC_PITCH_TEXTCTRL")) {
|
||||
unsigned long pitch = 0;
|
||||
wxTextCtrl *text_ctrl = static_cast<wxTextCtrl *>(event.GetEventObject());
|
||||
|
||||
text_ctrl->GetValue().ToULong(&pitch, 10);
|
||||
canvas->set_custom_pitch(pitch);
|
||||
}
|
||||
}
|
||||
|
||||
void OnSpinCtrl(wxSpinEvent &event)
|
||||
{
|
||||
wxWindowID id = event.GetId();
|
||||
|
||||
if (id == XRCID("IDC_SCALE")) {
|
||||
int scale_factor = event.GetPosition();
|
||||
|
||||
canvas->set_scale_factor(scale_factor);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
ViewerVRAM(wxWindow *parent, wxString title, wxSize size, void *p)
|
||||
: Viewer(parent, title, size, p)
|
||||
{
|
||||
panel = wxXmlResource::Get()->LoadPanel(this, "ViewerVRAMPanel");
|
||||
|
||||
sz = new wxBoxSizer(wxHORIZONTAL);
|
||||
sz->Add(panel, 0, wxEXPAND | wxALL, 0);
|
||||
|
||||
canvas = new ViewerVRAMCanvas(this, "vram", wxDefaultPosition, wxDefaultSize, (svga_t *)p, this);
|
||||
sz->Add(canvas, 1, wxEXPAND | wxALL, 0);
|
||||
SetSizer(sz);
|
||||
|
||||
Bind(wxEVT_CLOSE_WINDOW, &ViewerVRAM::OnClose, this);
|
||||
|
||||
panel->Bind(wxEVT_RADIOBUTTON, &ViewerVRAM::OnRadioButton, this);
|
||||
panel->Bind(wxEVT_TEXT_ENTER, &ViewerVRAM::OnText, this);
|
||||
panel->Bind(wxEVT_SPINCTRL, &ViewerVRAM::OnSpinCtrl, this);
|
||||
}
|
||||
|
||||
virtual ~ViewerVRAM()
|
||||
{
|
||||
delete canvas;
|
||||
}
|
||||
};
|
||||
|
||||
void ViewerVRAMCanvas::UpdateLabels()
|
||||
{
|
||||
current_start_addr = svga->ma_latch * 4;
|
||||
current_pitch = svga->rowoffset;
|
||||
current_bpp = svga->video_bpp;
|
||||
|
||||
char s[128];
|
||||
|
||||
wxRadioButton *rb = static_cast<wxRadioButton *>(vram_parent->FindWindow("IDC_STARTADDR_CURRENT"));
|
||||
sprintf(s, "Current (%x)", current_start_addr);
|
||||
rb->SetLabel(wxString(s));
|
||||
|
||||
rb = static_cast<wxRadioButton *>(vram_parent->FindWindow("IDC_PITCH_CURRENT"));
|
||||
sprintf(s, "Current (%u)", current_pitch);
|
||||
rb->SetLabel(wxString(s));
|
||||
|
||||
rb = static_cast<wxRadioButton *>(vram_parent->FindWindow("IDC_DEPTH_CURRENT"));
|
||||
switch (current_bpp)
|
||||
{
|
||||
case 1:
|
||||
rb->SetLabel("Current (2 cols)");
|
||||
break;
|
||||
case 2:
|
||||
rb->SetLabel("Current (4 cols)");
|
||||
break;
|
||||
case 4:
|
||||
rb->SetLabel("Current (16 cols)");
|
||||
break;
|
||||
case 8:
|
||||
rb->SetLabel("Current (256 cols)");
|
||||
break;
|
||||
case 15:
|
||||
rb->SetLabel("Current (1555)");
|
||||
break;
|
||||
case 16:
|
||||
rb->SetLabel("Current (555)");
|
||||
break;
|
||||
case 24:
|
||||
rb->SetLabel("Current (888)");
|
||||
break;
|
||||
case 32:
|
||||
rb->SetLabel("Current (8888)");
|
||||
break;
|
||||
default:
|
||||
rb->SetLabel("Current");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void *viewer_vram_open(void *parent, void *p, const char *title)
|
||||
{
|
||||
wxFrame *w = new ViewerVRAM((wxWindow *)parent, title, wxDefaultSize, p);
|
||||
|
||||
w->Show(true);
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
viewer_t viewer_vram =
|
||||
{
|
||||
.open = viewer_vram_open
|
||||
};
|
13
src/wx-ui/viewers/viewers.cmake
Normal file
13
src/wx-ui/viewers/viewers.cmake
Normal file
@@ -0,0 +1,13 @@
|
||||
set(PCEM_PRIVATE_API ${PCEM_PRIVATE_API}
|
||||
${CMAKE_SOURCE_DIR}/includes/private/wx-ui/viewer.h
|
||||
)
|
||||
|
||||
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/wx-ui/viewers)
|
||||
|
||||
set(PCEM_SRC ${PCEM_SRC}
|
||||
wx-ui/viewers/viewer.cc
|
||||
wx-ui/viewers/viewer_font.cc
|
||||
wx-ui/viewers/viewer_palette.cc
|
||||
wx-ui/viewers/viewer_voodoo.cc
|
||||
wx-ui/viewers/viewer_vram.cc
|
||||
)
|
@@ -49,6 +49,8 @@
|
||||
#include "plugin.h"
|
||||
#include "pic.h"
|
||||
|
||||
#include "viewer.h"
|
||||
|
||||
#if __APPLE__
|
||||
#define pause __pause
|
||||
#include <util.h>
|
||||
@@ -355,6 +357,7 @@ void wx_initmenu() {
|
||||
int wx_setupmenu(void *data) {
|
||||
int c;
|
||||
update_cdrom_menu(menu);
|
||||
update_viewers_menu(menu);
|
||||
sprintf(menuitem, "IDM_VID_RESOLUTION[%d]", vid_resize);
|
||||
wx_checkmenuitem(menu, WX_ID(menuitem), WX_MB_CHECKED);
|
||||
wx_enablemenuitem(menu, wx_xrcid("IDM_VID_SCALE_MENU"), !vid_resize);
|
||||
@@ -521,6 +524,7 @@ int resume_emulation() {
|
||||
if (emulation_state == EMULATION_PAUSED) {
|
||||
emulation_state = EMULATION_RUNNING;
|
||||
pause = 0;
|
||||
viewer_notify_resume();
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
@@ -588,6 +592,7 @@ int pause_emulation() {
|
||||
pclog("Emulation paused.\n");
|
||||
emulation_state = EMULATION_PAUSED;
|
||||
pause = 1;
|
||||
viewer_notify_pause();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -621,6 +626,7 @@ int stop_emulation() {
|
||||
|
||||
pclog("Emulation stopped.\n");
|
||||
|
||||
viewer_close_all();
|
||||
wx_close_status(ghwnd);
|
||||
|
||||
return TRUE;
|
||||
@@ -948,6 +954,8 @@ int wx_handle_command(void *hwnd, int wParam, int checked) {
|
||||
cdrom_drive = new_cdrom_drive;
|
||||
saveconfig(NULL);
|
||||
update_cdrom_menu(hmenu);
|
||||
} else if (wParam >= IDM_VIEWER && wParam < IDM_VIEWER_MAX) {
|
||||
viewer_open(hwnd, wParam - IDM_VIEWER);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
Reference in New Issue
Block a user