mirror of https://github.com/inolen/redream.git
don't cast callbacks
This commit is contained in:
parent
807cacdd96
commit
110d6d15c3
|
@ -2,18 +2,17 @@
|
||||||
#include "core/interval_tree.h"
|
#include "core/interval_tree.h"
|
||||||
#include "core/math.h"
|
#include "core/math.h"
|
||||||
|
|
||||||
static int interval_tree_cmp(const struct interval_node *lhs,
|
static int interval_tree_cmp(const struct rb_node *lhs,
|
||||||
const struct interval_node *rhs);
|
const struct rb_node *rhs);
|
||||||
static void interval_tree_augment_propagate(struct rb_tree *t,
|
static void interval_tree_augment_propagate(struct rb_tree *t,
|
||||||
struct interval_node *n);
|
struct rb_node *n);
|
||||||
static void interval_tree_augment_rotate(struct rb_tree *t,
|
static void interval_tree_augment_rotate(struct rb_tree *t,
|
||||||
struct interval_node *oldn,
|
struct rb_node *oldn,
|
||||||
struct interval_node *newn);
|
struct rb_node *newn);
|
||||||
|
|
||||||
struct rb_callbacks interval_tree_cb = {
|
struct rb_callbacks interval_tree_cb = {
|
||||||
(rb_cmp_cb)&interval_tree_cmp,
|
&interval_tree_cmp, &interval_tree_augment_propagate,
|
||||||
(rb_augment_propagate_cb)&interval_tree_augment_propagate,
|
&interval_tree_augment_rotate,
|
||||||
(rb_augment_rotate_cb)&interval_tree_augment_rotate,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static interval_type_t interval_tree_node_max(struct interval_node *n) {
|
static interval_type_t interval_tree_node_max(struct interval_node *n) {
|
||||||
|
@ -44,7 +43,9 @@ static void interval_tree_fix_counts(struct interval_node *n) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void interval_tree_augment_propagate(struct rb_tree *t,
|
static void interval_tree_augment_propagate(struct rb_tree *t,
|
||||||
struct interval_node *n) {
|
struct rb_node *rb_n) {
|
||||||
|
struct interval_node *n = rb_entry(rb_n, struct interval_node, base);
|
||||||
|
|
||||||
while (n) {
|
while (n) {
|
||||||
interval_tree_fix_counts(n);
|
interval_tree_fix_counts(n);
|
||||||
n = INTERVAL_NODE(n->base.parent);
|
n = INTERVAL_NODE(n->base.parent);
|
||||||
|
@ -52,20 +53,21 @@ static void interval_tree_augment_propagate(struct rb_tree *t,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void interval_tree_augment_rotate(struct rb_tree *t,
|
static void interval_tree_augment_rotate(struct rb_tree *t,
|
||||||
struct interval_node *oldn,
|
struct rb_node *rb_oldn,
|
||||||
struct interval_node *newn) {
|
struct rb_node *rb_newn) {
|
||||||
|
struct interval_node *oldn = rb_entry(rb_oldn, struct interval_node, base);
|
||||||
|
struct interval_node *newn = rb_entry(rb_newn, struct interval_node, base);
|
||||||
|
|
||||||
interval_tree_fix_counts(oldn);
|
interval_tree_fix_counts(oldn);
|
||||||
interval_tree_fix_counts(newn);
|
interval_tree_fix_counts(newn);
|
||||||
interval_tree_fix_counts(INTERVAL_NODE(newn->base.parent));
|
interval_tree_fix_counts(INTERVAL_NODE(newn->base.parent));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int interval_tree_intersects(const struct interval_node *n,
|
static int interval_tree_cmp(const struct rb_node *rb_lhs,
|
||||||
interval_type_t low, interval_type_t high) {
|
const struct rb_node *rb_rhs) {
|
||||||
return high >= n->low && n->high >= low;
|
struct interval_node *lhs = rb_entry(rb_lhs, struct interval_node, base);
|
||||||
}
|
struct interval_node *rhs = rb_entry(rb_rhs, struct interval_node, base);
|
||||||
|
|
||||||
static int interval_tree_cmp(const struct interval_node *lhs,
|
|
||||||
const struct interval_node *rhs) {
|
|
||||||
int cmp = lhs->low - rhs->low;
|
int cmp = lhs->low - rhs->low;
|
||||||
|
|
||||||
if (!cmp) {
|
if (!cmp) {
|
||||||
|
@ -75,6 +77,11 @@ static int interval_tree_cmp(const struct interval_node *lhs,
|
||||||
return cmp;
|
return cmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int interval_tree_intersects(const struct interval_node *n,
|
||||||
|
interval_type_t low, interval_type_t high) {
|
||||||
|
return high >= n->low && n->high >= low;
|
||||||
|
}
|
||||||
|
|
||||||
static struct interval_node *interval_tree_min_interval(struct interval_node *n,
|
static struct interval_node *interval_tree_min_interval(struct interval_node *n,
|
||||||
interval_type_t low,
|
interval_type_t low,
|
||||||
interval_type_t high) {
|
interval_type_t high) {
|
||||||
|
|
|
@ -21,15 +21,10 @@ struct rb_tree {
|
||||||
struct rb_node *root;
|
struct rb_node *root;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef int (*rb_cmp_cb)(const struct rb_node *, const struct rb_node *);
|
|
||||||
typedef void (*rb_augment_propagate_cb)(struct rb_tree *, struct rb_node *);
|
|
||||||
typedef void (*rb_augment_rotate_cb)(struct rb_tree *, struct rb_node *,
|
|
||||||
struct rb_node *);
|
|
||||||
|
|
||||||
struct rb_callbacks {
|
struct rb_callbacks {
|
||||||
rb_cmp_cb cmp;
|
int (*cmp)(const struct rb_node *, const struct rb_node *);
|
||||||
rb_augment_propagate_cb propagate;
|
void (*propagate)(struct rb_tree *, struct rb_node *);
|
||||||
rb_augment_rotate_cb rotate;
|
void (*rotate)(struct rb_tree *, struct rb_node *, struct rb_node *);
|
||||||
};
|
};
|
||||||
|
|
||||||
void rb_link(struct rb_tree *t, struct rb_node *n, struct rb_callbacks *cb);
|
void rb_link(struct rb_tree *t, struct rb_node *n, struct rb_callbacks *cb);
|
||||||
|
|
|
@ -123,11 +123,15 @@ static bool emu_launch_gdi(emu_t *emu, const char *path) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void emu_onpaint(emu_t *emu, bool show_main_menu) {
|
static void emu_onpaint(void *data, bool show_main_menu) {
|
||||||
|
emu_t *emu = data;
|
||||||
|
|
||||||
dc_paint(emu->dc, show_main_menu);
|
dc_paint(emu->dc, show_main_menu);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void emu_onkeydown(emu_t *emu, enum keycode code, int16_t value) {
|
static void emu_onkeydown(void *data, enum keycode code, int16_t value) {
|
||||||
|
emu_t *emu = data;
|
||||||
|
|
||||||
if (code == K_F1) {
|
if (code == K_F1) {
|
||||||
if (value) {
|
if (value) {
|
||||||
win_enable_main_menu(emu->window, !win_main_menu_enabled(emu->window));
|
win_enable_main_menu(emu->window, !win_main_menu_enabled(emu->window));
|
||||||
|
@ -138,7 +142,9 @@ static void emu_onkeydown(emu_t *emu, enum keycode code, int16_t value) {
|
||||||
dc_keydown(emu->dc, code, value);
|
dc_keydown(emu->dc, code, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void emu_onclose(emu_t *emu) {
|
static void emu_onclose(void *data) {
|
||||||
|
emu_t *emu = data;
|
||||||
|
|
||||||
emu->running = false;
|
emu->running = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,13 +207,7 @@ void emu_run(emu_t *emu, const char *path) {
|
||||||
|
|
||||||
emu_t *emu_create(struct window *window) {
|
emu_t *emu_create(struct window *window) {
|
||||||
static const struct window_callbacks callbacks = {
|
static const struct window_callbacks callbacks = {
|
||||||
NULL,
|
NULL, &emu_onpaint, NULL, &emu_onkeydown, NULL, NULL, &emu_onclose};
|
||||||
(window_paint_cb)&emu_onpaint,
|
|
||||||
NULL,
|
|
||||||
(window_keydown_cb)&emu_onkeydown,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
(window_close_cb)&emu_onclose};
|
|
||||||
|
|
||||||
emu_t *emu = calloc(1, sizeof(emu_t));
|
emu_t *emu = calloc(1, sizeof(emu_t));
|
||||||
|
|
||||||
|
|
|
@ -107,10 +107,10 @@ typedef struct tracer_s {
|
||||||
struct list free_textures;
|
struct list free_textures;
|
||||||
} tracer_t;
|
} tracer_t;
|
||||||
|
|
||||||
static int tracer_texture_cmp(const struct rb_node *lhs_it,
|
static int tracer_texture_cmp(const struct rb_node *rb_lhs,
|
||||||
const struct rb_node *rhs_it) {
|
const struct rb_node *rb_rhs) {
|
||||||
const texture_t *lhs = rb_entry(lhs_it, const texture_t, live_it);
|
const texture_t *lhs = rb_entry(rb_lhs, const texture_t, live_it);
|
||||||
const texture_t *rhs = rb_entry(rhs_it, const texture_t, live_it);
|
const texture_t *rhs = rb_entry(rb_rhs, const texture_t, live_it);
|
||||||
return tr_get_texture_key(lhs->tsp, lhs->tcw) -
|
return tr_get_texture_key(lhs->tsp, lhs->tcw) -
|
||||||
tr_get_texture_key(rhs->tsp, rhs->tcw);
|
tr_get_texture_key(rhs->tsp, rhs->tcw);
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,7 +86,8 @@ define_write_wave(w8, uint8_t);
|
||||||
define_write_wave(w16, uint16_t);
|
define_write_wave(w16, uint16_t);
|
||||||
define_write_wave(w32, uint32_t);
|
define_write_wave(w32, uint32_t);
|
||||||
|
|
||||||
static bool aica_init(struct aica *aica) {
|
static bool aica_init(struct device *dev) {
|
||||||
|
struct aica *aica = container_of(dev, struct aica, base);
|
||||||
struct dreamcast *dc = aica->base.dc;
|
struct dreamcast *dc = aica->base.dc;
|
||||||
|
|
||||||
aica->arm = dc->arm;
|
aica->arm = dc->arm;
|
||||||
|
@ -100,8 +101,8 @@ static bool aica_init(struct aica *aica) {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct aica *aica_create(struct dreamcast *dc) {
|
struct aica *aica_create(struct dreamcast *dc) {
|
||||||
struct aica *aica = dc_create_device(dc, sizeof(struct aica), "aica",
|
struct aica *aica =
|
||||||
(device_init_cb)&aica_init);
|
dc_create_device(dc, sizeof(struct aica), "aica", &aica_init);
|
||||||
return aica;
|
return aica;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,11 +6,14 @@ struct arm {
|
||||||
struct device base;
|
struct device base;
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool arm_init(struct arm *arm) {
|
static bool arm_init(struct device *dev) {
|
||||||
|
// struct arm *arm = container_of(dev, struct arm, base);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void arm_run(struct arm *arm, int64_t ns) {}
|
static void arm_run(struct device *dev, int64_t ns) {
|
||||||
|
// struct arm *arm = container_of(dev, struct arm, base);
|
||||||
|
}
|
||||||
|
|
||||||
void arm_suspend(struct arm *arm) {
|
void arm_suspend(struct arm *arm) {
|
||||||
arm->base.execute->suspended = true;
|
arm->base.execute->suspended = true;
|
||||||
|
@ -21,9 +24,8 @@ void arm_resume(struct arm *arm) {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct arm *arm_create(struct dreamcast *dc) {
|
struct arm *arm_create(struct dreamcast *dc) {
|
||||||
struct arm *arm = dc_create_device(dc, sizeof(struct arm), "arm",
|
struct arm *arm = dc_create_device(dc, sizeof(struct arm), "arm", &arm_init);
|
||||||
(device_init_cb)&arm_init);
|
arm->base.execute = execute_interface_create(&arm_run);
|
||||||
arm->base.execute = execute_interface_create((device_run_cb)&arm_run);
|
|
||||||
return arm;
|
return arm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -56,7 +56,7 @@ void device_run(struct device *dev, int64_t ns) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void *dc_create_device(struct dreamcast *dc, size_t size, const char *name,
|
void *dc_create_device(struct dreamcast *dc, size_t size, const char *name,
|
||||||
device_init_cb init) {
|
bool (*init)(struct device *dev)) {
|
||||||
struct device *dev = calloc(1, size);
|
struct device *dev = calloc(1, size);
|
||||||
|
|
||||||
dev->dc = dc;
|
dev->dc = dc;
|
||||||
|
|
|
@ -94,12 +94,11 @@ void window_interface_destroy(struct window_interface *window);
|
||||||
//
|
//
|
||||||
// device
|
// device
|
||||||
//
|
//
|
||||||
typedef bool (*device_init_cb)(struct device *);
|
|
||||||
|
|
||||||
struct device {
|
struct device {
|
||||||
struct dreamcast *dc;
|
struct dreamcast *dc;
|
||||||
const char *name;
|
const char *name;
|
||||||
device_init_cb init;
|
bool (*init)(struct device *dev);
|
||||||
struct debug_interface *debug;
|
struct debug_interface *debug;
|
||||||
struct execute_interface *execute;
|
struct execute_interface *execute;
|
||||||
struct memory_interface *memory;
|
struct memory_interface *memory;
|
||||||
|
@ -127,7 +126,7 @@ struct dreamcast {
|
||||||
};
|
};
|
||||||
|
|
||||||
void *dc_create_device(struct dreamcast *dc, size_t size, const char *name,
|
void *dc_create_device(struct dreamcast *dc, size_t size, const char *name,
|
||||||
device_init_cb init);
|
bool (*init)(struct device *dev));
|
||||||
struct device *dc_get_device(struct dreamcast *dc, const char *name);
|
struct device *dc_get_device(struct dreamcast *dc, const char *name);
|
||||||
void dc_destroy_device(struct device *dev);
|
void dc_destroy_device(struct device *dev);
|
||||||
|
|
||||||
|
|
|
@ -605,7 +605,8 @@ REG_W32(struct gdrom *gd, GD_STATUS_COMMAND) {
|
||||||
gdrom_ata_cmd(gd, (enum gd_ata_cmd) * new_value);
|
gdrom_ata_cmd(gd, (enum gd_ata_cmd) * new_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool gdrom_init(struct gdrom *gd) {
|
static bool gdrom_init(struct device *dev) {
|
||||||
|
struct gdrom *gd = container_of(dev, struct gdrom, base);
|
||||||
struct dreamcast *dc = gd->base.dc;
|
struct dreamcast *dc = gd->base.dc;
|
||||||
|
|
||||||
gd->holly = dc->holly;
|
gd->holly = dc->holly;
|
||||||
|
@ -681,8 +682,8 @@ void gdrom_dma_end(struct gdrom *gd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct gdrom *gdrom_create(struct dreamcast *dc) {
|
struct gdrom *gdrom_create(struct dreamcast *dc) {
|
||||||
struct gdrom *gd = dc_create_device(dc, sizeof(struct gdrom), "gdrom",
|
struct gdrom *gd =
|
||||||
(device_init_cb)&gdrom_init);
|
dc_create_device(dc, sizeof(struct gdrom), "gdrom", &gdrom_init);
|
||||||
return gd;
|
return gd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -288,7 +288,8 @@ REG_W32(struct holly *hl, SB_PDST) {
|
||||||
LOG_WARNING("Ignored pvr DMA request");
|
LOG_WARNING("Ignored pvr DMA request");
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool holly_init(struct holly *hl) {
|
static bool holly_init(struct device *dev) {
|
||||||
|
struct holly *hl = container_of(dev, struct holly, base);
|
||||||
struct dreamcast *dc = hl->base.dc;
|
struct dreamcast *dc = hl->base.dc;
|
||||||
|
|
||||||
hl->gdrom = dc->gdrom;
|
hl->gdrom = dc->gdrom;
|
||||||
|
@ -387,8 +388,8 @@ void holly_clear_interrupt(struct holly *hl, enum holly_interrupt intr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct holly *holly_create(struct dreamcast *dc) {
|
struct holly *holly_create(struct dreamcast *dc) {
|
||||||
struct holly *hl = dc_create_device(dc, sizeof(struct holly), "holly",
|
struct holly *hl =
|
||||||
(device_init_cb)&holly_init);
|
dc_create_device(dc, sizeof(struct holly), "holly", &holly_init);
|
||||||
|
|
||||||
return hl;
|
return hl;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,9 @@
|
||||||
#include "hw/sh4/sh4.h"
|
#include "hw/sh4/sh4.h"
|
||||||
#include "hw/dreamcast.h"
|
#include "hw/dreamcast.h"
|
||||||
|
|
||||||
static void pvr_next_scanline(struct pvr *pvr) {
|
static void pvr_next_scanline(void *data) {
|
||||||
|
struct pvr *pvr = data;
|
||||||
|
|
||||||
uint32_t num_scanlines = pvr->SPG_LOAD->vcount + 1;
|
uint32_t num_scanlines = pvr->SPG_LOAD->vcount + 1;
|
||||||
if (pvr->current_scanline > num_scanlines) {
|
if (pvr->current_scanline > num_scanlines) {
|
||||||
pvr->current_scanline = 0;
|
pvr->current_scanline = 0;
|
||||||
|
@ -37,9 +39,8 @@ static void pvr_next_scanline(struct pvr *pvr) {
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// reschedule
|
// reschedule
|
||||||
pvr->line_timer =
|
pvr->line_timer = scheduler_start_timer(pvr->scheduler, &pvr_next_scanline,
|
||||||
scheduler_start_timer(pvr->scheduler, (timer_cb)&pvr_next_scanline, pvr,
|
pvr, HZ_TO_NANO(pvr->line_clock));
|
||||||
HZ_TO_NANO(pvr->line_clock));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pvr_reconfigure_spg(struct pvr *pvr) {
|
static void pvr_reconfigure_spg(struct pvr *pvr) {
|
||||||
|
@ -67,9 +68,8 @@ static void pvr_reconfigure_spg(struct pvr *pvr) {
|
||||||
pvr->line_timer = NULL;
|
pvr->line_timer = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
pvr->line_timer =
|
pvr->line_timer = scheduler_start_timer(pvr->scheduler, &pvr_next_scanline,
|
||||||
scheduler_start_timer(pvr->scheduler, (timer_cb)&pvr_next_scanline, pvr,
|
pvr, HZ_TO_NANO(pvr->line_clock));
|
||||||
HZ_TO_NANO(pvr->line_clock));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t pvr_reg_r32(struct pvr *pvr, uint32_t addr) {
|
static uint32_t pvr_reg_r32(struct pvr *pvr, uint32_t addr) {
|
||||||
|
@ -153,7 +153,8 @@ REG_W32(struct pvr *pvr, FB_R_CTRL) {
|
||||||
pvr_reconfigure_spg(pvr);
|
pvr_reconfigure_spg(pvr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool pvr_init(struct pvr *pvr) {
|
static bool pvr_init(struct device *dev) {
|
||||||
|
struct pvr *pvr = container_of(dev, struct pvr, base);
|
||||||
struct dreamcast *dc = pvr->base.dc;
|
struct dreamcast *dc = pvr->base.dc;
|
||||||
|
|
||||||
pvr->scheduler = dc->scheduler;
|
pvr->scheduler = dc->scheduler;
|
||||||
|
@ -187,8 +188,7 @@ static bool pvr_init(struct pvr *pvr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct pvr *pvr_create(struct dreamcast *dc) {
|
struct pvr *pvr_create(struct dreamcast *dc) {
|
||||||
struct pvr *pvr = dc_create_device(dc, sizeof(struct pvr), "pvr",
|
struct pvr *pvr = dc_create_device(dc, sizeof(struct pvr), "pvr", &pvr_init);
|
||||||
(device_init_cb)&pvr_init);
|
|
||||||
|
|
||||||
return pvr;
|
return pvr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,19 +71,19 @@ static enum holly_interrupt list_interrupts[] = {
|
||||||
HOLLY_INTC_TAEPTIN // TA_LIST_PUNCH_THROUGH
|
HOLLY_INTC_TAEPTIN // TA_LIST_PUNCH_THROUGH
|
||||||
};
|
};
|
||||||
|
|
||||||
static int ta_entry_cmp(const struct rb_node *lhs_it,
|
static int ta_entry_cmp(const struct rb_node *rb_lhs,
|
||||||
const struct rb_node *rhs_it) {
|
const struct rb_node *rb_rhs) {
|
||||||
const struct texture_entry *lhs =
|
const struct texture_entry *lhs =
|
||||||
rb_entry(lhs_it, const struct texture_entry, live_it);
|
rb_entry(rb_lhs, const struct texture_entry, live_it);
|
||||||
const struct texture_entry *rhs =
|
const struct texture_entry *rhs =
|
||||||
rb_entry(rhs_it, const struct texture_entry, live_it);
|
rb_entry(rb_rhs, const struct texture_entry, live_it);
|
||||||
return lhs->key - rhs->key;
|
return lhs->key - rhs->key;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ta_context_cmp(const struct rb_node *lhs_it,
|
static int ta_context_cmp(const struct rb_node *rb_lhs,
|
||||||
const struct rb_node *rhs_it) {
|
const struct rb_node *rb_rhs) {
|
||||||
const struct tile_ctx *lhs = rb_entry(lhs_it, const struct tile_ctx, live_it);
|
const struct tile_ctx *lhs = rb_entry(rb_lhs, const struct tile_ctx, live_it);
|
||||||
const struct tile_ctx *rhs = rb_entry(rhs_it, const struct tile_ctx, live_it);
|
const struct tile_ctx *rhs = rb_entry(rb_rhs, const struct tile_ctx, live_it);
|
||||||
return lhs->addr - rhs->addr;
|
return lhs->addr - rhs->addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -497,8 +497,8 @@ static void ta_clear_pending_textures(struct ta *ta) {
|
||||||
prof_count("Num invalidated textures", ta->num_invalidated);
|
prof_count("Num invalidated textures", ta->num_invalidated);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ta_texture_invalidated(const struct exception *ex,
|
static void ta_texture_invalidated(const struct exception *ex, void *data) {
|
||||||
struct texture_entry *entry) {
|
struct texture_entry *entry = data;
|
||||||
struct ta *ta = entry->ta;
|
struct ta *ta = entry->ta;
|
||||||
|
|
||||||
// don't double remove the watch during invalidation
|
// don't double remove the watch during invalidation
|
||||||
|
@ -511,8 +511,8 @@ static void ta_texture_invalidated(const struct exception *ex,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ta_palette_invalidated(const struct exception *ex,
|
static void ta_palette_invalidated(const struct exception *ex, void *data) {
|
||||||
struct texture_entry *entry) {
|
struct texture_entry *entry = data;
|
||||||
struct ta *ta = entry->ta;
|
struct ta *ta = entry->ta;
|
||||||
|
|
||||||
// don't double remove the watch during invalidation
|
// don't double remove the watch during invalidation
|
||||||
|
@ -525,11 +525,12 @@ static void ta_palette_invalidated(const struct exception *ex,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static texture_handle_t ta_get_texture(struct ta *ta,
|
static texture_handle_t ta_get_texture(void *data, const struct tile_ctx *ctx,
|
||||||
const struct tile_ctx *ctx,
|
|
||||||
union tsp tsp, union tcw tcw,
|
union tsp tsp, union tcw tcw,
|
||||||
void *register_data,
|
void *register_data,
|
||||||
register_texture_cb register_cb) {
|
register_texture_cb register_cb) {
|
||||||
|
struct ta *ta = data;
|
||||||
|
|
||||||
// clear any pending texture invalidations at this time
|
// clear any pending texture invalidations at this time
|
||||||
ta_clear_pending_textures(ta);
|
ta_clear_pending_textures(ta);
|
||||||
|
|
||||||
|
@ -601,12 +602,12 @@ static texture_handle_t ta_get_texture(struct ta *ta,
|
||||||
// add write callback in order to invalidate on future writes. the callback
|
// add write callback in order to invalidate on future writes. the callback
|
||||||
// address will be page aligned, therefore it will be triggered falsely in
|
// address will be page aligned, therefore it will be triggered falsely in
|
||||||
// some cases. over invalidate in these cases
|
// some cases. over invalidate in these cases
|
||||||
entry->texture_watch = add_single_write_watch(
|
entry->texture_watch = add_single_write_watch(texture, texture_size,
|
||||||
texture, texture_size, (memory_watch_cb)&ta_texture_invalidated, entry);
|
&ta_texture_invalidated, entry);
|
||||||
|
|
||||||
if (palette) {
|
if (palette) {
|
||||||
entry->palette_watch = add_single_write_watch(
|
entry->palette_watch = add_single_write_watch(
|
||||||
palette, palette_size, (memory_watch_cb)&ta_palette_invalidated, entry);
|
palette, palette_size, &ta_palette_invalidated, entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ta->trace_writer) {
|
if (ta->trace_writer) {
|
||||||
|
@ -659,7 +660,8 @@ REG_W32(struct ta *ta, STARTRENDER) {
|
||||||
ta_finish_context(ta, ta->pvr->PARAM_BASE->base_address);
|
ta_finish_context(ta, ta->pvr->PARAM_BASE->base_address);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool ta_init(struct ta *ta) {
|
static bool ta_init(struct device *dev) {
|
||||||
|
struct ta *ta = container_of(dev, struct ta, base);
|
||||||
struct dreamcast *dc = ta->base.dc;
|
struct dreamcast *dc = ta->base.dc;
|
||||||
|
|
||||||
ta->holly = dc->holly;
|
ta->holly = dc->holly;
|
||||||
|
@ -719,7 +721,9 @@ static void ta_toggle_tracing(struct ta *ta) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ta_paint(struct ta *ta, bool show_main_menu) {
|
static void ta_paint(struct device *dev, bool show_main_menu) {
|
||||||
|
struct ta *ta = container_of(dev, struct ta, base);
|
||||||
|
|
||||||
if (ta->pending_context) {
|
if (ta->pending_context) {
|
||||||
struct render_ctx rctx = {};
|
struct render_ctx rctx = {};
|
||||||
rctx.surfs = ta->surfs;
|
rctx.surfs = ta->surfs;
|
||||||
|
@ -800,12 +804,12 @@ void ta_build_tables() {
|
||||||
struct ta *ta_create(struct dreamcast *dc, struct rb *rb) {
|
struct ta *ta_create(struct dreamcast *dc, struct rb *rb) {
|
||||||
ta_build_tables();
|
ta_build_tables();
|
||||||
|
|
||||||
struct ta *ta = (struct ta *)dc_create_device(dc, sizeof(struct ta), "ta",
|
struct ta *ta =
|
||||||
(device_init_cb)&ta_init);
|
(struct ta *)dc_create_device(dc, sizeof(struct ta), "ta", &ta_init);
|
||||||
ta->base.window = window_interface_create((device_paint_cb)&ta_paint, NULL);
|
ta->base.window = window_interface_create(&ta_paint, NULL);
|
||||||
|
|
||||||
ta->rb = rb;
|
ta->rb = rb;
|
||||||
ta->tr = tr_create(ta->rb, ta, (get_texture_cb)&ta_get_texture);
|
ta->tr = tr_create(ta->rb, ta, &ta_get_texture);
|
||||||
|
|
||||||
return ta;
|
return ta;
|
||||||
}
|
}
|
||||||
|
|
|
@ -118,16 +118,17 @@ static inline uint32_t float_to_rgba(float r, float g, float b, float a) {
|
||||||
(float_to_u8(g) << 8) | float_to_u8(r);
|
(float_to_u8(g) << 8) | float_to_u8(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tr_register_texture(struct tr *tr, struct texture_reg *reg) {
|
static void tr_register_texture(void *data, struct texture_reg *reg) {
|
||||||
static uint8_t converted[1024 * 1024 * 4];
|
static uint8_t converted[1024 * 1024 * 4];
|
||||||
|
|
||||||
|
struct tr *tr = data;
|
||||||
const struct tile_ctx *ctx = reg->ctx;
|
const struct tile_ctx *ctx = reg->ctx;
|
||||||
union tsp tsp = reg->tsp;
|
union tsp tsp = reg->tsp;
|
||||||
union tcw tcw = reg->tcw;
|
union tcw tcw = reg->tcw;
|
||||||
const uint8_t *palette = reg->palette;
|
const uint8_t *palette_data = reg->palette;
|
||||||
const uint8_t *data = reg->data;
|
const uint8_t *texture_data = reg->data;
|
||||||
const uint8_t *input = data;
|
const uint8_t *input = texture_data;
|
||||||
const uint8_t *output = data;
|
const uint8_t *output = texture_data;
|
||||||
|
|
||||||
// textures are either twiddled and vq compressed, twiddled and uncompressed
|
// textures are either twiddled and vq compressed, twiddled and uncompressed
|
||||||
// or planar
|
// or planar
|
||||||
|
@ -166,7 +167,7 @@ static void tr_register_texture(struct tr *tr, struct texture_reg *reg) {
|
||||||
|
|
||||||
// used by vq compressed textures
|
// used by vq compressed textures
|
||||||
static const int codebook_size = 256 * 8;
|
static const int codebook_size = 256 * 8;
|
||||||
const uint8_t *codebook = data;
|
const uint8_t *codebook = texture_data;
|
||||||
const uint8_t *index = input + codebook_size;
|
const uint8_t *index = input + codebook_size;
|
||||||
|
|
||||||
enum pxl_format pixel_fmt = PXL_INVALID;
|
enum pxl_format pixel_fmt = PXL_INVALID;
|
||||||
|
@ -224,7 +225,7 @@ static void tr_register_texture(struct tr *tr, struct texture_reg *reg) {
|
||||||
case TA_PAL_ARGB4444:
|
case TA_PAL_ARGB4444:
|
||||||
pixel_fmt = PXL_RGBA4444;
|
pixel_fmt = PXL_RGBA4444;
|
||||||
convert_pal4_ARGB4444_RGBA4444(input, (uint16_t *)converted,
|
convert_pal4_ARGB4444_RGBA4444(input, (uint16_t *)converted,
|
||||||
(const uint32_t *)palette, width,
|
(const uint32_t *)palette_data, width,
|
||||||
height);
|
height);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -242,14 +243,14 @@ static void tr_register_texture(struct tr *tr, struct texture_reg *reg) {
|
||||||
case TA_PAL_ARGB4444:
|
case TA_PAL_ARGB4444:
|
||||||
pixel_fmt = PXL_RGBA4444;
|
pixel_fmt = PXL_RGBA4444;
|
||||||
convert_pal8_ARGB4444_RGBA4444(input, (uint16_t *)converted,
|
convert_pal8_ARGB4444_RGBA4444(input, (uint16_t *)converted,
|
||||||
(const uint32_t *)palette, width,
|
(const uint32_t *)palette_data, width,
|
||||||
height);
|
height);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TA_PAL_ARGB8888:
|
case TA_PAL_ARGB8888:
|
||||||
pixel_fmt = PXL_RGBA8888;
|
pixel_fmt = PXL_RGBA8888;
|
||||||
convert_pal8_ARGB8888_RGBA8888(input, (uint32_t *)converted,
|
convert_pal8_ARGB8888_RGBA8888(input, (uint32_t *)converted,
|
||||||
(const uint32_t *)palette, width,
|
(const uint32_t *)palette_data, width,
|
||||||
height);
|
height);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -564,8 +565,7 @@ static void tr_parse_poly_param(struct tr *tr, const struct tile_ctx *ctx,
|
||||||
|
|
||||||
if (param->type0.pcw.texture) {
|
if (param->type0.pcw.texture) {
|
||||||
surf->texture = tr->get_texture(tr->get_texture_data, ctx, param->type0.tsp,
|
surf->texture = tr->get_texture(tr->get_texture_data, ctx, param->type0.tsp,
|
||||||
param->type0.tcw, tr,
|
param->type0.tcw, tr, &tr_register_texture);
|
||||||
(register_texture_cb)&tr_register_texture);
|
|
||||||
} else {
|
} else {
|
||||||
surf->texture = 0;
|
surf->texture = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -119,12 +119,16 @@ static void controller_load_profile(struct controller *ctrl, const char *path) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void controller_destroy(struct controller *controller) {
|
static void controller_destroy(struct maple_device *dev) {
|
||||||
free(controller);
|
struct controller *ctrl = container_of(dev, struct controller, base);
|
||||||
|
|
||||||
|
free(ctrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool controller_input(struct controller *ctrl, enum keycode key,
|
static bool controller_input(struct maple_device *dev, enum keycode key,
|
||||||
int16_t value) {
|
int16_t value) {
|
||||||
|
struct controller *ctrl = container_of(dev, struct controller, base);
|
||||||
|
|
||||||
// map incoming key to dreamcast button
|
// map incoming key to dreamcast button
|
||||||
int button = ctrl->map[key];
|
int button = ctrl->map[key];
|
||||||
|
|
||||||
|
@ -155,9 +159,11 @@ static bool controller_input(struct controller *ctrl, enum keycode key,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool controller_frame(struct controller *ctrl,
|
static bool controller_frame(struct maple_device *dev,
|
||||||
const struct maple_frame *frame,
|
const struct maple_frame *frame,
|
||||||
struct maple_frame *res) {
|
struct maple_frame *res) {
|
||||||
|
struct controller *ctrl = container_of(dev, struct controller, base);
|
||||||
|
|
||||||
switch (frame->header.command) {
|
switch (frame->header.command) {
|
||||||
case CMD_REQDEVINFO:
|
case CMD_REQDEVINFO:
|
||||||
res->header.command = CMD_RESDEVINFO;
|
res->header.command = CMD_RESDEVINFO;
|
||||||
|
@ -181,9 +187,9 @@ static bool controller_frame(struct controller *ctrl,
|
||||||
|
|
||||||
struct maple_device *controller_create() {
|
struct maple_device *controller_create() {
|
||||||
struct controller *ctrl = calloc(1, sizeof(struct controller));
|
struct controller *ctrl = calloc(1, sizeof(struct controller));
|
||||||
ctrl->base.destroy = (maple_destroy_cb)&controller_destroy;
|
ctrl->base.destroy = &controller_destroy;
|
||||||
ctrl->base.input = (maple_input_cb)&controller_input;
|
ctrl->base.input = &controller_input;
|
||||||
ctrl->base.frame = (maple_frame_cb)&controller_frame;
|
ctrl->base.frame = &controller_frame;
|
||||||
ctrl->cnd.function = FN_CONTROLLER;
|
ctrl->cnd.function = FN_CONTROLLER;
|
||||||
|
|
||||||
// buttons bitfield contains 0s for pressed buttons and 1s for unpressed
|
// buttons bitfield contains 0s for pressed buttons and 1s for unpressed
|
||||||
|
|
|
@ -59,7 +59,8 @@ REG_W32(struct maple *mp, SB_MDST) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool maple_init(struct maple *mp) {
|
static bool maple_init(struct device *dev) {
|
||||||
|
struct maple *mp = container_of(dev, struct maple, base);
|
||||||
struct dreamcast *dc = mp->base.dc;
|
struct dreamcast *dc = mp->base.dc;
|
||||||
|
|
||||||
mp->holly = dc->holly;
|
mp->holly = dc->holly;
|
||||||
|
@ -79,14 +80,13 @@ static bool maple_init(struct maple *mp) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void maple_keydown(struct maple *mp, enum keycode key, int16_t value) {
|
static void maple_keydown(struct device *dev, enum keycode key, int16_t value) {
|
||||||
struct maple_device *dev = mp->devices[0];
|
struct maple *mp = container_of(dev, struct maple, base);
|
||||||
|
struct maple_device *mp_dev = mp->devices[0];
|
||||||
|
|
||||||
if (!dev) {
|
if (mp_dev) {
|
||||||
return;
|
mp_dev->input(mp_dev, key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
dev->input(dev, key, value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void maple_vblank(struct maple *mp) {
|
void maple_vblank(struct maple *mp) {
|
||||||
|
@ -105,10 +105,9 @@ void maple_vblank(struct maple *mp) {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct maple *maple_create(struct dreamcast *dc) {
|
struct maple *maple_create(struct dreamcast *dc) {
|
||||||
struct maple *mp = dc_create_device(dc, sizeof(struct maple), "maple",
|
struct maple *mp =
|
||||||
(device_init_cb)&maple_init);
|
dc_create_device(dc, sizeof(struct maple), "maple", &maple_init);
|
||||||
mp->base.window =
|
mp->base.window = window_interface_create(NULL, &maple_keydown);
|
||||||
window_interface_create(NULL, (device_keydown_cb)&maple_keydown);
|
|
||||||
|
|
||||||
mp->devices[0] = controller_create();
|
mp->devices[0] = controller_create();
|
||||||
|
|
||||||
|
|
|
@ -9,16 +9,11 @@ struct dreamcast;
|
||||||
struct maple;
|
struct maple;
|
||||||
struct maple_device;
|
struct maple_device;
|
||||||
|
|
||||||
typedef void (*maple_destroy_cb)(struct maple_device *);
|
|
||||||
typedef bool (*maple_input_cb)(struct maple_device *, enum keycode, int16_t);
|
|
||||||
typedef bool (*maple_frame_cb)(struct maple_device *,
|
|
||||||
const struct maple_frame *,
|
|
||||||
struct maple_frame *);
|
|
||||||
|
|
||||||
struct maple_device {
|
struct maple_device {
|
||||||
maple_destroy_cb destroy;
|
void (*destroy)(struct maple_device *);
|
||||||
maple_input_cb input;
|
bool (*input)(struct maple_device *, enum keycode, int16_t);
|
||||||
maple_frame_cb frame;
|
bool (*frame)(struct maple_device *, const struct maple_frame *,
|
||||||
|
struct maple_frame *);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct maple_device *controller_create();
|
struct maple_device *controller_create();
|
||||||
|
|
|
@ -93,16 +93,16 @@ static void sh4_tmu_expire(struct sh4 *sh4, int n) {
|
||||||
sh4_tmu_reschedule(sh4, n, *tcnt, *tcr);
|
sh4_tmu_reschedule(sh4, n, *tcnt, *tcr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sh4_tmu_expire_0(struct sh4 *sh4) {
|
static void sh4_tmu_expire_0(void *data) {
|
||||||
sh4_tmu_expire(sh4, 0);
|
sh4_tmu_expire(data, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sh4_tmu_expire_1(struct sh4 *sh4) {
|
static void sh4_tmu_expire_1(void *data) {
|
||||||
sh4_tmu_expire(sh4, 1);
|
sh4_tmu_expire(data, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sh4_tmu_expire_2(struct sh4 *sh4) {
|
static void sh4_tmu_expire_2(void *data) {
|
||||||
sh4_tmu_expire(sh4, 2);
|
sh4_tmu_expire(data, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sh4_tmu_reschedule(struct sh4 *sh4, int n, uint32_t tcnt,
|
static void sh4_tmu_reschedule(struct sh4 *sh4, int n, uint32_t tcnt,
|
||||||
|
@ -118,8 +118,7 @@ static void sh4_tmu_reschedule(struct sh4 *sh4, int n, uint32_t tcnt,
|
||||||
*timer = NULL;
|
*timer = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
timer_cb cb =
|
timer_cb cb = (n == 0 ? &sh4_tmu_expire_0 : n == 1 ? &sh4_tmu_expire_1
|
||||||
(timer_cb)(n == 0 ? &sh4_tmu_expire_0 : n == 1 ? &sh4_tmu_expire_1
|
|
||||||
: &sh4_tmu_expire_2);
|
: &sh4_tmu_expire_2);
|
||||||
*timer = scheduler_start_timer(sh4->scheduler, cb, sh4, remaining);
|
*timer = scheduler_start_timer(sh4->scheduler, cb, sh4, remaining);
|
||||||
}
|
}
|
||||||
|
@ -697,7 +696,8 @@ REG_W32(struct sh4 *sh4, TCNT2) {
|
||||||
sh4_tmu_update_tcnt(sh4, 2);
|
sh4_tmu_update_tcnt(sh4, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool sh4_init(struct sh4 *sh4) {
|
static bool sh4_init(struct device *dev) {
|
||||||
|
struct sh4 *sh4 = container_of(dev, struct sh4, base);
|
||||||
struct dreamcast *dc = sh4->base.dc;
|
struct dreamcast *dc = sh4->base.dc;
|
||||||
|
|
||||||
sh4->scheduler = dc->scheduler;
|
sh4->scheduler = dc->scheduler;
|
||||||
|
@ -771,7 +771,8 @@ static bool sh4_init(struct sh4 *sh4) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sh4_paint(struct sh4 *sh4, bool show_main_menu) {
|
static void sh4_paint(struct device *dev, bool show_main_menu) {
|
||||||
|
struct sh4 *sh4 = container_of(dev, struct sh4, base);
|
||||||
struct sh4_perf *perf = &sh4->perf;
|
struct sh4_perf *perf = &sh4->perf;
|
||||||
|
|
||||||
// if (show_main_menu && ImGui::BeginMainMenuBar()) {
|
// if (show_main_menu && ImGui::BeginMainMenuBar()) {
|
||||||
|
@ -814,7 +815,9 @@ void sh4_set_pc(struct sh4 *sh4, uint32_t pc) {
|
||||||
sh4->ctx.pc = pc;
|
sh4->ctx.pc = pc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sh4_run_inner(struct sh4 *sh4, int64_t ns) {
|
static void sh4_run_inner(struct device *dev, int64_t ns) {
|
||||||
|
struct sh4 *sh4 = container_of(dev, struct sh4, base);
|
||||||
|
|
||||||
// execute at least 1 cycle. the tests rely on this to step block by block
|
// execute at least 1 cycle. the tests rely on this to step block by block
|
||||||
int64_t cycles = MAX(NANO_TO_CYCLES(ns, SH4_CLOCK_FREQ), INT64_C(1));
|
int64_t cycles = MAX(NANO_TO_CYCLES(ns, SH4_CLOCK_FREQ), INT64_C(1));
|
||||||
|
|
||||||
|
@ -847,10 +850,10 @@ static void sh4_run_inner(struct sh4 *sh4, int64_t ns) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void sh4_run(struct sh4 *sh4, int64_t ns) {
|
void sh4_run(struct device *dev, int64_t ns) {
|
||||||
prof_enter("sh4_run");
|
prof_enter("sh4_run");
|
||||||
|
|
||||||
sh4_run_inner(sh4, ns);
|
sh4_run_inner(dev, ns);
|
||||||
|
|
||||||
prof_leave();
|
prof_leave();
|
||||||
}
|
}
|
||||||
|
@ -938,11 +941,10 @@ void sh4_ddt(struct sh4 *sh4, struct sh4_dtr *dtr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct sh4 *sh4_create(struct dreamcast *dc) {
|
struct sh4 *sh4_create(struct dreamcast *dc) {
|
||||||
struct sh4 *sh4 =
|
struct sh4 *sh4 = dc_create_device(dc, sizeof(struct sh4), "sh", &sh4_init);
|
||||||
dc_create_device(dc, sizeof(struct sh4), "sh", (device_init_cb)&sh4_init);
|
sh4->base.execute = execute_interface_create(&sh4_run);
|
||||||
sh4->base.execute = execute_interface_create((device_run_cb)&sh4_run);
|
|
||||||
sh4->base.memory = memory_interface_create(dc, &sh4_data_map);
|
sh4->base.memory = memory_interface_create(dc, &sh4_data_map);
|
||||||
sh4->base.window = window_interface_create((device_paint_cb)&sh4_paint, NULL);
|
sh4->base.window = window_interface_create(&sh4_paint, NULL);
|
||||||
|
|
||||||
g_sh4 = sh4;
|
g_sh4 = sh4;
|
||||||
|
|
||||||
|
|
|
@ -64,7 +64,6 @@ struct sh4 {
|
||||||
};
|
};
|
||||||
|
|
||||||
void sh4_set_pc(struct sh4 *sh4, uint32_t pc);
|
void sh4_set_pc(struct sh4 *sh4, uint32_t pc);
|
||||||
void sh4_run(struct sh4 *sh4, int64_t ns);
|
|
||||||
void sh4_raise_interrupt(struct sh4 *sh, enum sh4_interrupt intr);
|
void sh4_raise_interrupt(struct sh4 *sh, enum sh4_interrupt intr);
|
||||||
void sh4_clear_interrupt(struct sh4 *sh, enum sh4_interrupt intr);
|
void sh4_clear_interrupt(struct sh4 *sh, enum sh4_interrupt intr);
|
||||||
void sh4_ddt(struct sh4 *sh, struct sh4_dtr *dtr);
|
void sh4_ddt(struct sh4 *sh, struct sh4_dtr *dtr);
|
||||||
|
|
|
@ -15,22 +15,22 @@
|
||||||
#include "sys/exception_handler.h"
|
#include "sys/exception_handler.h"
|
||||||
#include "sys/filesystem.h"
|
#include "sys/filesystem.h"
|
||||||
|
|
||||||
static int block_map_cmp(const struct rb_node *lhs_it,
|
static int block_map_cmp(const struct rb_node *rb_lhs,
|
||||||
const struct rb_node *rhs_it) {
|
const struct rb_node *rb_rhs) {
|
||||||
const struct sh4_block *lhs =
|
const struct sh4_block *lhs =
|
||||||
container_of(lhs_it, const struct sh4_block, it);
|
container_of(rb_lhs, const struct sh4_block, it);
|
||||||
const struct sh4_block *rhs =
|
const struct sh4_block *rhs =
|
||||||
container_of(rhs_it, const struct sh4_block, it);
|
container_of(rb_rhs, const struct sh4_block, it);
|
||||||
|
|
||||||
return (int)((int64_t)lhs->guest_addr - (int64_t)rhs->guest_addr);
|
return (int)((int64_t)lhs->guest_addr - (int64_t)rhs->guest_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int reverse_block_map_cmp(const struct rb_node *lhs_it,
|
static int reverse_block_map_cmp(const struct rb_node *rb_lhs,
|
||||||
const struct rb_node *rhs_it) {
|
const struct rb_node *rb_rhs) {
|
||||||
const struct sh4_block *lhs =
|
const struct sh4_block *lhs =
|
||||||
container_of(lhs_it, const struct sh4_block, rit);
|
container_of(rb_lhs, const struct sh4_block, rit);
|
||||||
const struct sh4_block *rhs =
|
const struct sh4_block *rhs =
|
||||||
container_of(rhs_it, const struct sh4_block, rit);
|
container_of(rb_rhs, const struct sh4_block, rit);
|
||||||
|
|
||||||
return (int)(lhs->host_addr - rhs->host_addr);
|
return (int)(lhs->host_addr - rhs->host_addr);
|
||||||
}
|
}
|
||||||
|
@ -102,8 +102,9 @@ static struct sh4_block *sh4_cache_lookup_block_reverse(
|
||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool sh4_cache_handle_exception(struct sh4_cache *cache,
|
static bool sh4_cache_handle_exception(void *data, struct exception *ex) {
|
||||||
struct exception *ex) {
|
struct sh4_cache *cache = data;
|
||||||
|
|
||||||
// see if there is an assembled block corresponding to the current pc
|
// see if there is an assembled block corresponding to the current pc
|
||||||
struct sh4_block *block =
|
struct sh4_block *block =
|
||||||
sh4_cache_lookup_block_reverse(cache, (const uint8_t *)ex->pc);
|
sh4_cache_lookup_block_reverse(cache, (const uint8_t *)ex->pc);
|
||||||
|
@ -286,8 +287,8 @@ struct sh4_cache *sh4_cache_create(const struct mem_interface *memif,
|
||||||
|
|
||||||
// add exception handler to help recompile blocks when protected memory is
|
// add exception handler to help recompile blocks when protected memory is
|
||||||
// accessed
|
// accessed
|
||||||
cache->exc_handler = exception_handler_add(
|
cache->exc_handler =
|
||||||
cache, (exception_handler_cb)&sh4_cache_handle_exception);
|
exception_handler_add(cache, &sh4_cache_handle_exception);
|
||||||
|
|
||||||
// setup parser and emitter
|
// setup parser and emitter
|
||||||
cache->frontend = sh4_frontend_create();
|
cache->frontend = sh4_frontend_create();
|
||||||
|
|
|
@ -30,22 +30,16 @@ struct mem_interface {
|
||||||
|
|
||||||
struct jit_backend;
|
struct jit_backend;
|
||||||
|
|
||||||
typedef const struct register_def *(*registers_cb)();
|
|
||||||
typedef int (*num_registers_cb)();
|
|
||||||
typedef void (*reset_cb)(struct jit_backend *);
|
|
||||||
typedef const uint8_t *(*assemble_code_cb)(struct jit_backend *, struct ir *,
|
|
||||||
int *);
|
|
||||||
typedef void (*dump_code_cb)(struct jit_backend *, const uint8_t *, int);
|
|
||||||
typedef bool (*handle_exception_cb)(struct jit_backend *, struct exception *);
|
|
||||||
|
|
||||||
struct jit_backend {
|
struct jit_backend {
|
||||||
const struct register_def *registers;
|
const struct register_def *registers;
|
||||||
int num_registers;
|
int num_registers;
|
||||||
|
|
||||||
reset_cb reset;
|
void (*reset)(struct jit_backend *base);
|
||||||
assemble_code_cb assemble_code;
|
const uint8_t *(*assemble_code)(struct jit_backend *, struct ir *ir,
|
||||||
dump_code_cb dump_code;
|
int *size);
|
||||||
handle_exception_cb handle_exception;
|
void (*dump_code)(struct jit_backend *base, const uint8_t *host_addr,
|
||||||
|
int size);
|
||||||
|
bool (*handle_exception)(struct jit_backend *base, struct exception *ex);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -457,15 +457,19 @@ static void x64_backend_emit_constants(struct x64_backend *backend) {
|
||||||
e.dq(INT64_C(0x8000000000000000));
|
e.dq(INT64_C(0x8000000000000000));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void x64_backend_reset(struct x64_backend *backend) {
|
static void x64_backend_reset(struct jit_backend *base) {
|
||||||
|
struct x64_backend *backend = container_of(base, struct x64_backend, base);
|
||||||
|
|
||||||
backend->codegen->reset();
|
backend->codegen->reset();
|
||||||
|
|
||||||
x64_backend_emit_thunks(backend);
|
x64_backend_emit_thunks(backend);
|
||||||
x64_backend_emit_constants(backend);
|
x64_backend_emit_constants(backend);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const uint8_t *x64_backend_assemble_code(struct x64_backend *backend,
|
static const uint8_t *x64_backend_assemble_code(struct jit_backend *base,
|
||||||
struct ir *ir, int *size) {
|
struct ir *ir, int *size) {
|
||||||
|
struct x64_backend *backend = container_of(base, struct x64_backend, base);
|
||||||
|
|
||||||
// try to generate the x64 code. if the code buffer overflows let the backend
|
// try to generate the x64 code. if the code buffer overflows let the backend
|
||||||
// know so it can reset the cache and try again
|
// know so it can reset the cache and try again
|
||||||
const uint8_t *fn = nullptr;
|
const uint8_t *fn = nullptr;
|
||||||
|
@ -481,8 +485,10 @@ static const uint8_t *x64_backend_assemble_code(struct x64_backend *backend,
|
||||||
return fn;
|
return fn;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void x64_backend_dump_code(struct x64_backend *backend,
|
static void x64_backend_dump_code(struct jit_backend *base,
|
||||||
const uint8_t *host_addr, int size) {
|
const uint8_t *host_addr, int size) {
|
||||||
|
struct x64_backend *backend = container_of(base, struct x64_backend, base);
|
||||||
|
|
||||||
cs_insn *insns;
|
cs_insn *insns;
|
||||||
size_t count =
|
size_t count =
|
||||||
cs_disasm(backend->capstone_handle, host_addr, size, 0, 0, &insns);
|
cs_disasm(backend->capstone_handle, host_addr, size, 0, 0, &insns);
|
||||||
|
@ -497,8 +503,10 @@ static void x64_backend_dump_code(struct x64_backend *backend,
|
||||||
cs_free(insns, count);
|
cs_free(insns, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool x64_backend_handle_exception(struct x64_backend *backend,
|
static bool x64_backend_handle_exception(struct jit_backend *base,
|
||||||
struct exception *ex) {
|
struct exception *ex) {
|
||||||
|
struct x64_backend *backend = container_of(base, struct x64_backend, base);
|
||||||
|
|
||||||
const uint8_t *data = reinterpret_cast<const uint8_t *>(ex->thread_state.rip);
|
const uint8_t *data = reinterpret_cast<const uint8_t *>(ex->thread_state.rip);
|
||||||
|
|
||||||
// it's assumed a mov has triggered the exception
|
// it's assumed a mov has triggered the exception
|
||||||
|
@ -1646,13 +1654,11 @@ struct jit_backend *x64_backend_create(const struct mem_interface *memif) {
|
||||||
calloc(1, sizeof(struct x64_backend)));
|
calloc(1, sizeof(struct x64_backend)));
|
||||||
|
|
||||||
backend->base.registers = x64_registers;
|
backend->base.registers = x64_registers;
|
||||||
backend->base.num_registers =
|
backend->base.num_registers = array_size(x64_registers);
|
||||||
sizeof(x64_registers) / sizeof(struct register_def);
|
backend->base.reset = &x64_backend_reset;
|
||||||
backend->base.reset = (reset_cb)&x64_backend_reset;
|
backend->base.assemble_code = &x64_backend_assemble_code;
|
||||||
backend->base.assemble_code = (assemble_code_cb)&x64_backend_assemble_code;
|
backend->base.dump_code = &x64_backend_dump_code;
|
||||||
backend->base.dump_code = (dump_code_cb)&x64_backend_dump_code;
|
backend->base.handle_exception = &x64_backend_handle_exception;
|
||||||
backend->base.handle_exception =
|
|
||||||
(handle_exception_cb)&x64_backend_handle_exception;
|
|
||||||
|
|
||||||
backend->memif = *memif;
|
backend->memif = *memif;
|
||||||
|
|
||||||
|
@ -1661,9 +1667,7 @@ struct jit_backend *x64_backend_create(const struct mem_interface *memif) {
|
||||||
int res = cs_open(CS_ARCH_X86, CS_MODE_64, &backend->capstone_handle);
|
int res = cs_open(CS_ARCH_X86, CS_MODE_64, &backend->capstone_handle);
|
||||||
CHECK_EQ(res, CS_ERR_OK);
|
CHECK_EQ(res, CS_ERR_OK);
|
||||||
|
|
||||||
x64_backend_reset(backend);
|
// make the code buffer executable
|
||||||
|
|
||||||
// protect the code buffer
|
|
||||||
int page_size = get_page_size();
|
int page_size = get_page_size();
|
||||||
void *aligned_code = (void *)align_down((intptr_t)x64_code, page_size);
|
void *aligned_code = (void *)align_down((intptr_t)x64_code, page_size);
|
||||||
int aligned_code_size = align_up(x64_code_size, page_size);
|
int aligned_code_size = align_up(x64_code_size, page_size);
|
||||||
|
@ -1671,6 +1675,9 @@ struct jit_backend *x64_backend_create(const struct mem_interface *memif) {
|
||||||
protect_pages(aligned_code, aligned_code_size, ACC_READWRITEEXEC);
|
protect_pages(aligned_code, aligned_code_size, ACC_READWRITEEXEC);
|
||||||
CHECK(success);
|
CHECK(success);
|
||||||
|
|
||||||
|
// do an initial reset to emit constants and thinks
|
||||||
|
x64_backend_reset((jit_backend *)backend);
|
||||||
|
|
||||||
return (struct jit_backend *)backend;
|
return (struct jit_backend *)backend;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,17 +4,12 @@
|
||||||
struct ir;
|
struct ir;
|
||||||
struct jit_frontend;
|
struct jit_frontend;
|
||||||
|
|
||||||
typedef void (*jit_frontend_translate_code)(struct jit_frontend *frontend,
|
|
||||||
uint32_t guest_addr,
|
|
||||||
uint8_t *guest_ptr, int flags,
|
|
||||||
int *size, struct ir *ir);
|
|
||||||
typedef void (*jit_frontend_dump_code)(struct jit_frontend *frontend,
|
|
||||||
uint32_t guest_addr, uint8_t *guest_ptr,
|
|
||||||
int size);
|
|
||||||
|
|
||||||
struct jit_frontend {
|
struct jit_frontend {
|
||||||
jit_frontend_translate_code translate_code;
|
void (*translate_code)(struct jit_frontend *base, uint32_t guest_addr,
|
||||||
jit_frontend_dump_code dump_code;
|
uint8_t *guest_ptr, int flags, int *size,
|
||||||
|
struct ir *ir);
|
||||||
|
void (*dump_code)(struct jit_frontend *base, uint32_t guest_addr,
|
||||||
|
uint8_t *guest_ptr, int size);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -9,9 +9,11 @@ struct sh4_frontend {
|
||||||
struct jit_frontend base;
|
struct jit_frontend base;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void sh4_frontend_translate_code(struct sh4_frontend *frontend,
|
static void sh4_frontend_translate_code(struct jit_frontend *base,
|
||||||
uint32_t guest_addr, uint8_t *guest_ptr,
|
uint32_t guest_addr, uint8_t *guest_ptr,
|
||||||
int flags, int *size, struct ir *ir) {
|
int flags, int *size, struct ir *ir) {
|
||||||
|
struct sh4_frontend *frontend = container_of(base, struct sh4_frontend, base);
|
||||||
|
|
||||||
// get the block size
|
// get the block size
|
||||||
sh4_analyze_block(guest_addr, guest_ptr, flags, size);
|
sh4_analyze_block(guest_addr, guest_ptr, flags, size);
|
||||||
|
|
||||||
|
@ -19,9 +21,11 @@ static void sh4_frontend_translate_code(struct sh4_frontend *frontend,
|
||||||
sh4_translate(guest_addr, guest_ptr, *size, flags, ir);
|
sh4_translate(guest_addr, guest_ptr, *size, flags, ir);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sh4_frontend_dump_code(struct sh4_frontend *frontend,
|
static void sh4_frontend_dump_code(struct jit_frontend *base,
|
||||||
uint32_t guest_addr, uint8_t *guest_ptr,
|
uint32_t guest_addr, uint8_t *guest_ptr,
|
||||||
int size) {
|
int size) {
|
||||||
|
struct sh4_frontend *frontend = container_of(base, struct sh4_frontend, base);
|
||||||
|
|
||||||
char buffer[128];
|
char buffer[128];
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
@ -54,9 +58,8 @@ static void sh4_frontend_dump_code(struct sh4_frontend *frontend,
|
||||||
struct jit_frontend *sh4_frontend_create() {
|
struct jit_frontend *sh4_frontend_create() {
|
||||||
struct sh4_frontend *frontend = calloc(1, sizeof(struct sh4_frontend));
|
struct sh4_frontend *frontend = calloc(1, sizeof(struct sh4_frontend));
|
||||||
|
|
||||||
frontend->base.translate_code =
|
frontend->base.translate_code = &sh4_frontend_translate_code;
|
||||||
(jit_frontend_translate_code)&sh4_frontend_translate_code;
|
frontend->base.dump_code = &sh4_frontend_dump_code;
|
||||||
frontend->base.dump_code = (jit_frontend_dump_code)&sh4_frontend_dump_code;
|
|
||||||
|
|
||||||
return (struct jit_frontend *)frontend;
|
return (struct jit_frontend *)frontend;
|
||||||
}
|
}
|
||||||
|
|
|
@ -488,7 +488,9 @@ static void rb_set_initial_state(struct rb *rb) {
|
||||||
rb_set_blend_func(rb, BLEND_NONE, BLEND_NONE);
|
rb_set_blend_func(rb, BLEND_NONE, BLEND_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rb_onpaint(struct rb *rb, bool show_main_menu) {
|
static void rb_onpaint(void *data, bool show_main_menu) {
|
||||||
|
// struct rb *rb = data;
|
||||||
|
|
||||||
// if (show_main_menu && ImGui::BeginMainMenuBar()) {
|
// if (show_main_menu && ImGui::BeginMainMenuBar()) {
|
||||||
// if (ImGui::BeginMenu("Render")) {
|
// if (ImGui::BeginMenu("Render")) {
|
||||||
// ImGui::MenuItem("Wireframe", "", &rb->debug_wireframe);
|
// ImGui::MenuItem("Wireframe", "", &rb->debug_wireframe);
|
||||||
|
@ -703,7 +705,7 @@ void rb_free_texture(struct rb *rb, texture_handle_t handle) {
|
||||||
|
|
||||||
struct rb *rb_create(struct window *window) {
|
struct rb *rb_create(struct window *window) {
|
||||||
static const struct window_callbacks callbacks = {
|
static const struct window_callbacks callbacks = {
|
||||||
NULL, (window_paint_cb)&rb_onpaint, NULL, NULL, NULL, NULL, NULL};
|
NULL, rb_onpaint, NULL, NULL, NULL, NULL, NULL};
|
||||||
|
|
||||||
struct rb *rb = (struct rb *)calloc(1, sizeof(struct rb));
|
struct rb *rb = (struct rb *)calloc(1, sizeof(struct rb));
|
||||||
rb->window = window;
|
rb->window = window;
|
||||||
|
|
|
@ -14,7 +14,8 @@ struct imgui {
|
||||||
bool shift[2];
|
bool shift[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
static void imgui_onprepaint(struct imgui *imgui) {
|
static void imgui_onprepaint(void *data) {
|
||||||
|
struct imgui *imgui = reinterpret_cast<struct imgui *>(data);
|
||||||
ImGuiIO &io = ImGui::GetIO();
|
ImGuiIO &io = ImGui::GetIO();
|
||||||
|
|
||||||
int width = win_width(imgui->window);
|
int width = win_width(imgui->window);
|
||||||
|
@ -28,7 +29,8 @@ static void imgui_onprepaint(struct imgui *imgui) {
|
||||||
io.MouseWheel = 0.0;
|
io.MouseWheel = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void imgui_onpostpaint(struct imgui *imgui) {
|
static void imgui_onpostpaint(void *data) {
|
||||||
|
struct imgui *imgui = reinterpret_cast<struct imgui *>(data);
|
||||||
ImGuiIO &io = ImGui::GetIO();
|
ImGuiIO &io = ImGui::GetIO();
|
||||||
struct rb *rb = win_render_backend(imgui->window);
|
struct rb *rb = win_render_backend(imgui->window);
|
||||||
|
|
||||||
|
@ -40,12 +42,12 @@ static void imgui_onpostpaint(struct imgui *imgui) {
|
||||||
ImGui::Render();
|
ImGui::Render();
|
||||||
|
|
||||||
// get the latest draw batches, and pass them off out the render backend
|
// get the latest draw batches, and pass them off out the render backend
|
||||||
ImDrawData *data = ImGui::GetDrawData();
|
ImDrawData *draw_data = ImGui::GetDrawData();
|
||||||
|
|
||||||
rb_begin2d(rb);
|
rb_begin2d(rb);
|
||||||
|
|
||||||
for (int i = 0; i < data->CmdListsCount; ++i) {
|
for (int i = 0; i < draw_data->CmdListsCount; ++i) {
|
||||||
const auto cmd_list = data->CmdLists[i];
|
const auto cmd_list = draw_data->CmdLists[i];
|
||||||
|
|
||||||
struct vertex2d *verts =
|
struct vertex2d *verts =
|
||||||
reinterpret_cast<struct vertex2d *>(cmd_list->VtxBuffer.Data);
|
reinterpret_cast<struct vertex2d *>(cmd_list->VtxBuffer.Data);
|
||||||
|
@ -86,8 +88,8 @@ static void imgui_onpostpaint(struct imgui *imgui) {
|
||||||
rb_end2d(rb);
|
rb_end2d(rb);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void imgui_onkeydown(struct imgui *imgui, enum keycode code,
|
static void imgui_onkeydown(void *data, enum keycode code, int16_t value) {
|
||||||
int16_t value) {
|
struct imgui *imgui = reinterpret_cast<struct imgui *>(data);
|
||||||
ImGuiIO &io = ImGui::GetIO();
|
ImGuiIO &io = ImGui::GetIO();
|
||||||
|
|
||||||
if (code == K_MWHEELUP) {
|
if (code == K_MWHEELUP) {
|
||||||
|
@ -114,27 +116,28 @@ static void imgui_onkeydown(struct imgui *imgui, enum keycode code,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void imgui_ontextinput(struct imgui *imgui, const char *text) {
|
static void imgui_ontextinput(void *data, const char *text) {
|
||||||
|
struct imgui *imgui = reinterpret_cast<struct imgui *>(data);
|
||||||
ImGuiIO &io = ImGui::GetIO();
|
ImGuiIO &io = ImGui::GetIO();
|
||||||
|
|
||||||
io.AddInputCharactersUTF8(text);
|
io.AddInputCharactersUTF8(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void imgui_onmousemove(struct imgui *imgui, int x, int y) {
|
static void imgui_onmousemove(void *data, int x, int y) {
|
||||||
|
struct imgui *imgui = reinterpret_cast<struct imgui *>(data);
|
||||||
ImGuiIO &io = ImGui::GetIO();
|
ImGuiIO &io = ImGui::GetIO();
|
||||||
|
|
||||||
io.MousePos = ImVec2((float)x, (float)y);
|
io.MousePos = ImVec2((float)x, (float)y);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct imgui *imgui_create(struct window *window) {
|
struct imgui *imgui_create(struct window *window) {
|
||||||
static const struct window_callbacks callbacks = {
|
static const struct window_callbacks callbacks = {&imgui_onprepaint,
|
||||||
(window_prepaint_cb)&imgui_onprepaint,
|
NULL,
|
||||||
NULL,
|
&imgui_onpostpaint,
|
||||||
(window_postpaint_cb)&imgui_onpostpaint,
|
&imgui_onkeydown,
|
||||||
(window_keydown_cb)&imgui_onkeydown,
|
&imgui_ontextinput,
|
||||||
(window_textinput_cb)&imgui_ontextinput,
|
&imgui_onmousemove,
|
||||||
(window_mousemove_cb)&imgui_onmousemove,
|
NULL};
|
||||||
NULL};
|
|
||||||
|
|
||||||
struct imgui *imgui =
|
struct imgui *imgui =
|
||||||
reinterpret_cast<struct imgui *>(calloc(1, sizeof(struct imgui)));
|
reinterpret_cast<struct imgui *>(calloc(1, sizeof(struct imgui)));
|
||||||
|
|
|
@ -45,7 +45,9 @@ static struct microprofile *s_mp;
|
||||||
d[2].member = v; \
|
d[2].member = v; \
|
||||||
d[5].member = v
|
d[5].member = v
|
||||||
|
|
||||||
static void mp_onpostpaint(struct microprofile *mp) {
|
static void mp_onpostpaint(void *data) {
|
||||||
|
struct microprofile *mp = reinterpret_cast<struct microprofile *>(data);
|
||||||
|
|
||||||
s_mp = mp;
|
s_mp = mp;
|
||||||
|
|
||||||
// update draw surfaces
|
// update draw surfaces
|
||||||
|
@ -71,8 +73,7 @@ static void mp_onpostpaint(struct microprofile *mp) {
|
||||||
mp->num_verts = 0;
|
mp->num_verts = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mp_onkeydown(struct microprofile *mp, enum keycode code,
|
static void mp_onkeydown(void *data, enum keycode code, int16_t value) {
|
||||||
int16_t value) {
|
|
||||||
if (code == K_F2) {
|
if (code == K_F2) {
|
||||||
if (value) {
|
if (value) {
|
||||||
MicroProfileToggleDisplayMode();
|
MicroProfileToggleDisplayMode();
|
||||||
|
@ -84,7 +85,7 @@ static void mp_onkeydown(struct microprofile *mp, enum keycode code,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mp_onmousemove(struct microprofile *mp, int x, int y) {
|
static void mp_onmousemove(void *data, int x, int y) {
|
||||||
MicroProfileMousePosition(x, y, 0);
|
MicroProfileMousePosition(x, y, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -259,13 +260,7 @@ static void mp_draw_line(struct microprofile *mp, float *verts, int num_verts,
|
||||||
|
|
||||||
struct microprofile *mp_create(struct window *window) {
|
struct microprofile *mp_create(struct window *window) {
|
||||||
static const struct window_callbacks callbacks = {
|
static const struct window_callbacks callbacks = {
|
||||||
NULL,
|
NULL, NULL, &mp_onpostpaint, &mp_onkeydown, NULL, &mp_onmousemove, NULL};
|
||||||
NULL,
|
|
||||||
(window_postpaint_cb)&mp_onpostpaint,
|
|
||||||
(window_keydown_cb)&mp_onkeydown,
|
|
||||||
NULL,
|
|
||||||
(window_mousemove_cb)&mp_onmousemove,
|
|
||||||
NULL};
|
|
||||||
|
|
||||||
struct microprofile *mp = reinterpret_cast<struct microprofile *>(
|
struct microprofile *mp = reinterpret_cast<struct microprofile *>(
|
||||||
calloc(1, sizeof(struct microprofile)));
|
calloc(1, sizeof(struct microprofile)));
|
||||||
|
|
|
@ -16,22 +16,14 @@ static const int NUM_JOYSTICK_KEYS = (K_JOY31 - K_JOY0) + 1;
|
||||||
static const int NUM_JOYSTICK_HATS =
|
static const int NUM_JOYSTICK_HATS =
|
||||||
((K_HAT15 - K_HAT0) + 1) / 4; // 4 keys per hat
|
((K_HAT15 - K_HAT0) + 1) / 4; // 4 keys per hat
|
||||||
|
|
||||||
typedef void (*window_prepaint_cb)(void *data);
|
|
||||||
typedef void (*window_paint_cb)(void *data, bool show_main_menu);
|
|
||||||
typedef void (*window_postpaint_cb)(void *data);
|
|
||||||
typedef void (*window_keydown_cb)(void *data, enum keycode code, int16_t value);
|
|
||||||
typedef void (*window_textinput_cb)(void *data, const char *text);
|
|
||||||
typedef void (*window_mousemove_cb)(void *data, int x, int y);
|
|
||||||
typedef void (*window_close_cb)(void *data);
|
|
||||||
|
|
||||||
struct window_callbacks {
|
struct window_callbacks {
|
||||||
window_prepaint_cb prepaint;
|
void (*prepaint)(void *data);
|
||||||
window_paint_cb paint;
|
void (*paint)(void *data, bool show_main_menu);
|
||||||
window_postpaint_cb postpaint;
|
void (*postpaint)(void *data);
|
||||||
window_keydown_cb keydown;
|
void (*keydown)(void *data, enum keycode code, int16_t value);
|
||||||
window_textinput_cb textinput;
|
void (*textinput)(void *data, const char *text);
|
||||||
window_mousemove_cb mousemove;
|
void (*mousemove)(void *data, int x, int y);
|
||||||
window_close_cb close;
|
void (*close)(void *data);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct window;
|
struct window;
|
||||||
|
|
|
@ -118,7 +118,7 @@ static void run_sh4_test(const struct sh4_test &test) {
|
||||||
|
|
||||||
// run until the function returns
|
// run until the function returns
|
||||||
while (dc->sh4->ctx.pc) {
|
while (dc->sh4->ctx.pc) {
|
||||||
sh4_run(dc->sh4, 1);
|
dc_tick(dc, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// validate out registers
|
// validate out registers
|
||||||
|
|
Loading…
Reference in New Issue