mirror of
https://github.com/86Box/86Box.git
synced 2026-02-23 18:08:20 -07:00
Merge branch 'master' of https://github.com/starfrost013/86box
This commit is contained in:
@@ -1595,7 +1595,7 @@ update_mouse_msg(void)
|
||||
plat_get_string(STRING_MOUSE_CAPTURE));
|
||||
swprintf(mouse_msg[1], sizeof_w(mouse_msg[1]), L"%%i.%%i%%%% - %ls",
|
||||
(mouse_get_buttons() > 2) ? plat_get_string(STRING_MOUSE_RELEASE) : plat_get_string(STRING_MOUSE_RELEASE_MMB));
|
||||
wcsncpy(mouse_msg[2], L"%i%%", sizeof_w(mouse_msg[2]));
|
||||
wcsncpy(mouse_msg[2], L"%i.%i%%", sizeof_w(mouse_msg[2]));
|
||||
#else
|
||||
swprintf(mouse_msg[0], sizeof_w(mouse_msg[0]), L"%ls v%ls - %%i.%%i%%%% - %ls - %ls/%ls - %ls",
|
||||
EMU_NAME_W, EMU_VERSION_FULL_W, wmachine, wcpufamily, wcpu,
|
||||
|
||||
@@ -746,8 +746,7 @@ codegen_skip:
|
||||
uop_MOV_PTR(ir, IREG_ea_seg, (void *) op_ea_seg);
|
||||
if (op_ssegs != last_op_ssegs)
|
||||
uop_MOV_IMM(ir, IREG_ssegs, op_ssegs);
|
||||
uop_LOAD_FUNC_ARG_IMM(ir, 0, fetchdat);
|
||||
uop_CALL_INSTRUCTION_FUNC(ir, op);
|
||||
uop_CALL_INSTRUCTION_FUNC(ir, op, fetchdat);
|
||||
codegen_flags_changed = 0;
|
||||
codegen_mark_code_present(block, cs + cpu_state.pc, 8);
|
||||
|
||||
|
||||
@@ -218,6 +218,7 @@ codegen_CALL_FUNC_RESULT(codeblock_t *block, uop_t *uop)
|
||||
static int
|
||||
codegen_CALL_INSTRUCTION_FUNC(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
host_arm64_mov_imm(block, REG_ARG0, uop->imm_data);
|
||||
host_arm64_call(block, uop->p);
|
||||
host_arm64_CBNZ(block, REG_X0, (uintptr_t) codegen_exit_rout);
|
||||
|
||||
|
||||
@@ -286,6 +286,7 @@ codegen_CALL_FUNC_RESULT(codeblock_t *block, uop_t *uop)
|
||||
static int
|
||||
codegen_CALL_INSTRUCTION_FUNC(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
host_arm_MOV_IMM(block, REG_ARG0, uop->imm_data);
|
||||
host_arm_call(block, uop->p);
|
||||
host_arm_TST_REG(block, REG_R0, REG_R0);
|
||||
host_arm_BNE(block, (uintptr_t) codegen_exit_rout);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -219,6 +219,11 @@ codegen_CALL_FUNC_RESULT(codeblock_t *block, uop_t *uop)
|
||||
static int
|
||||
codegen_CALL_INSTRUCTION_FUNC(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
# if _WIN64
|
||||
host_x86_MOV32_REG_IMM(block, REG_ECX, uop->imm_data);
|
||||
# else
|
||||
host_x86_MOV32_REG_IMM(block, REG_EDI, uop->imm_data);
|
||||
# endif
|
||||
host_x86_CALL(block, uop->p);
|
||||
host_x86_TEST32_REG(block, REG_EAX, REG_EAX);
|
||||
host_x86_JNZ(block, codegen_exit_rout);
|
||||
|
||||
@@ -221,6 +221,7 @@ codegen_CALL_FUNC_RESULT(codeblock_t *block, uop_t *uop)
|
||||
static int
|
||||
codegen_CALL_INSTRUCTION_FUNC(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
host_x86_MOV32_STACK_IMM(block, STACK_ARG0, uop->imm_data);
|
||||
host_x86_CALL(block, uop->p);
|
||||
host_x86_TEST32_REG(block, REG_EAX, REG_EAX);
|
||||
host_x86_JNZ(block, codegen_exit_rout);
|
||||
|
||||
@@ -38,7 +38,7 @@ codegen_ir_set_unroll(int count, int start, int first_instruction)
|
||||
static void
|
||||
duplicate_uop(ir_data_t *ir, uop_t *uop, int offset)
|
||||
{
|
||||
uop_t *new_uop = uop_alloc(ir, uop->type);
|
||||
uop_t *new_uop = uop_alloc_unroll(ir, uop->type);
|
||||
|
||||
if (!ir_reg_is_invalid(uop->src_reg_a))
|
||||
new_uop->src_reg_a = codegen_reg_read(uop->src_reg_a.reg);
|
||||
|
||||
@@ -41,8 +41,8 @@
|
||||
#define UOP_LOAD_FUNC_ARG_2_IMM (UOP_TYPE_PARAMS_IMM | 0x0a | UOP_TYPE_BARRIER)
|
||||
#define UOP_LOAD_FUNC_ARG_3_IMM (UOP_TYPE_PARAMS_IMM | 0x0b | UOP_TYPE_BARRIER)
|
||||
#define UOP_CALL_FUNC (UOP_TYPE_PARAMS_POINTER | 0x10 | UOP_TYPE_BARRIER)
|
||||
/*UOP_CALL_INSTRUCTION_FUNC - call instruction handler at p, check return value and exit block if non-zero*/
|
||||
#define UOP_CALL_INSTRUCTION_FUNC (UOP_TYPE_PARAMS_POINTER | 0x11 | UOP_TYPE_BARRIER)
|
||||
/*UOP_CALL_INSTRUCTION_FUNC - call instruction handler at p with fetchdat, check return value and exit block if non-zero*/
|
||||
#define UOP_CALL_INSTRUCTION_FUNC (UOP_TYPE_PARAMS_POINTER | UOP_TYPE_PARAMS_IMM | 0x11 | UOP_TYPE_BARRIER)
|
||||
#define UOP_STORE_P_IMM (UOP_TYPE_PARAMS_IMM | 0x12)
|
||||
#define UOP_STORE_P_IMM_8 (UOP_TYPE_PARAMS_IMM | 0x13)
|
||||
/*UOP_LOAD_SEG - load segment in src_reg_a to segment p via loadseg(), check return value and exit block if non-zero*/
|
||||
@@ -377,6 +377,34 @@ uop_alloc(ir_data_t *ir, uint32_t uop_type)
|
||||
uop->jump_dest_uop = -1;
|
||||
uop->jump_list_next = -1;
|
||||
|
||||
if (uop_type & (UOP_TYPE_BARRIER | UOP_TYPE_ORDER_BARRIER))
|
||||
dirty_ir_regs[0] = dirty_ir_regs[1] = ~0ULL;
|
||||
|
||||
return uop;
|
||||
}
|
||||
|
||||
static inline uop_t *
|
||||
uop_alloc_unroll(ir_data_t *ir, uint32_t uop_type)
|
||||
{
|
||||
uop_t *uop;
|
||||
|
||||
if (ir->wr_pos >= UOP_NR_MAX)
|
||||
fatal("Exceeded uOP max\n");
|
||||
|
||||
uop = &ir->uops[ir->wr_pos++];
|
||||
|
||||
uop->is_a16 = 0;
|
||||
|
||||
uop->dest_reg_a = invalid_ir_reg;
|
||||
uop->src_reg_a = invalid_ir_reg;
|
||||
uop->src_reg_b = invalid_ir_reg;
|
||||
uop->src_reg_c = invalid_ir_reg;
|
||||
|
||||
uop->pc = cpu_state.oldpc;
|
||||
|
||||
uop->jump_dest_uop = -1;
|
||||
uop->jump_list_next = -1;
|
||||
|
||||
if (uop_type & (UOP_TYPE_BARRIER | UOP_TYPE_ORDER_BARRIER))
|
||||
codegen_reg_mark_as_required();
|
||||
|
||||
@@ -662,7 +690,7 @@ uop_gen_reg_src2_pointer(uint32_t uop_type, ir_data_t *ir, int src_reg_a, int sr
|
||||
|
||||
#define uop_CALL_FUNC(ir, p) uop_gen_pointer(UOP_CALL_FUNC, ir, p)
|
||||
#define uop_CALL_FUNC_RESULT(ir, dst_reg, p) uop_gen_reg_dst_pointer(UOP_CALL_FUNC_RESULT, ir, dst_reg, p)
|
||||
#define uop_CALL_INSTRUCTION_FUNC(ir, p) uop_gen_pointer(UOP_CALL_INSTRUCTION_FUNC, ir, p)
|
||||
#define uop_CALL_INSTRUCTION_FUNC(ir, p, imm) uop_gen_pointer_imm(UOP_CALL_INSTRUCTION_FUNC, ir, p, imm)
|
||||
|
||||
#define uop_CMP_IMM_JZ(ir, src_reg, imm, p) uop_gen_reg_src_pointer_imm(UOP_CMP_IMM_JZ, ir, src_reg, p, imm)
|
||||
|
||||
|
||||
@@ -34,6 +34,8 @@ typedef struct host_reg_set_t {
|
||||
static host_reg_set_t host_reg_set;
|
||||
static host_reg_set_t host_fp_reg_set;
|
||||
|
||||
uint64_t dirty_ir_regs[2] = { 0, 0 };
|
||||
|
||||
enum {
|
||||
REG_BYTE,
|
||||
REG_WORD,
|
||||
@@ -184,15 +186,36 @@ struct
|
||||
[IREG_temp1d] = { REG_DOUBLE, (void *) 48, REG_FP, REG_VOLATILE },
|
||||
};
|
||||
|
||||
static const uint8_t native_requested_sizes[9][8] =
|
||||
{
|
||||
[REG_BYTE][IREG_SIZE_B >> IREG_SIZE_SHIFT] = 1,
|
||||
[REG_FPU_ST_BYTE][IREG_SIZE_B >> IREG_SIZE_SHIFT] = 1,
|
||||
[REG_WORD][IREG_SIZE_W >> IREG_SIZE_SHIFT] = 1,
|
||||
[REG_DWORD][IREG_SIZE_L >> IREG_SIZE_SHIFT] = 1,
|
||||
[REG_QWORD][IREG_SIZE_D >> IREG_SIZE_SHIFT] = 1,
|
||||
[REG_FPU_ST_QWORD][IREG_SIZE_D >> IREG_SIZE_SHIFT] = 1,
|
||||
[REG_DOUBLE][IREG_SIZE_D >> IREG_SIZE_SHIFT] = 1,
|
||||
[REG_FPU_ST_DOUBLE][IREG_SIZE_D >> IREG_SIZE_SHIFT] = 1,
|
||||
[REG_QWORD][IREG_SIZE_Q >> IREG_SIZE_SHIFT] = 1,
|
||||
[REG_FPU_ST_QWORD][IREG_SIZE_Q >> IREG_SIZE_SHIFT] = 1,
|
||||
[REG_DOUBLE][IREG_SIZE_Q >> IREG_SIZE_SHIFT] = 1,
|
||||
[REG_FPU_ST_DOUBLE][IREG_SIZE_Q >> IREG_SIZE_SHIFT] = 1,
|
||||
|
||||
[REG_POINTER][(sizeof(void *) == 4) ? (IREG_SIZE_L >> IREG_SIZE_SHIFT) : (IREG_SIZE_Q >> IREG_SIZE_SHIFT)] = 1
|
||||
};
|
||||
|
||||
void
|
||||
codegen_reg_mark_as_required(void)
|
||||
{
|
||||
for (uint8_t reg = 0; reg < IREG_COUNT; reg++) {
|
||||
/* This used to start from IREG_EAX, now only starts from IREG_ESP since the first 4 registers are never optimized out. */
|
||||
/* It also no longer iterates through volatile registers unnecessarily. */
|
||||
for (uint8_t reg = IREG_ESP; reg < IREG_temp0; reg++) {
|
||||
int last_version = reg_last_version[reg];
|
||||
|
||||
if (last_version > 0 && ireg_data[reg].is_volatile == REG_PERMANENT)
|
||||
if (last_version > 0)
|
||||
reg_version[reg][last_version].flags |= REG_FLAGS_REQUIRED;
|
||||
}
|
||||
dirty_ir_regs[0] = dirty_ir_regs[1] = 0;
|
||||
}
|
||||
|
||||
int
|
||||
@@ -201,29 +224,7 @@ reg_is_native_size(ir_reg_t ir_reg)
|
||||
int native_size = ireg_data[IREG_GET_REG(ir_reg.reg)].native_size;
|
||||
int requested_size = IREG_GET_SIZE(ir_reg.reg);
|
||||
|
||||
switch (native_size) {
|
||||
case REG_BYTE:
|
||||
case REG_FPU_ST_BYTE:
|
||||
return (requested_size == IREG_SIZE_B);
|
||||
case REG_WORD:
|
||||
return (requested_size == IREG_SIZE_W);
|
||||
case REG_DWORD:
|
||||
return (requested_size == IREG_SIZE_L);
|
||||
case REG_QWORD:
|
||||
case REG_FPU_ST_QWORD:
|
||||
case REG_DOUBLE:
|
||||
case REG_FPU_ST_DOUBLE:
|
||||
return ((requested_size == IREG_SIZE_D) || (requested_size == IREG_SIZE_Q));
|
||||
case REG_POINTER:
|
||||
if (sizeof(void *) == 4)
|
||||
return (requested_size == IREG_SIZE_L);
|
||||
return (requested_size == IREG_SIZE_Q);
|
||||
|
||||
default:
|
||||
fatal("get_reg_is_native_size: unknown native size %i\n", native_size);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return native_requested_sizes[native_size][requested_size >> IREG_SIZE_SHIFT];
|
||||
}
|
||||
|
||||
void
|
||||
@@ -256,6 +257,8 @@ codegen_reg_reset(void)
|
||||
host_fp_reg_set.locked = 0;
|
||||
host_fp_reg_set.nr_regs = CODEGEN_HOST_FP_REGS;
|
||||
|
||||
dirty_ir_regs[0] = dirty_ir_regs[1] = 0;
|
||||
|
||||
for (c = 0; c < IREG_COUNT; c++) {
|
||||
reg_last_version[c] = 0;
|
||||
reg_version[c][0].refcount = 0;
|
||||
|
||||
@@ -16,59 +16,45 @@
|
||||
#define IREG_SIZE_Q (5 << IREG_SIZE_SHIFT)
|
||||
|
||||
enum {
|
||||
IREG_EAX = 0,
|
||||
IREG_ECX = 1,
|
||||
IREG_EDX = 2,
|
||||
IREG_EBX = 3,
|
||||
IREG_ESP = 4,
|
||||
IREG_EBP = 5,
|
||||
IREG_ESI = 6,
|
||||
IREG_EDI = 7,
|
||||
IREG_EAX,
|
||||
IREG_ECX,
|
||||
IREG_EDX,
|
||||
IREG_EBX,
|
||||
IREG_ESP,
|
||||
IREG_EBP,
|
||||
IREG_ESI,
|
||||
IREG_EDI,
|
||||
|
||||
IREG_flags_op = 8,
|
||||
IREG_flags_res = 9,
|
||||
IREG_flags_op1 = 10,
|
||||
IREG_flags_op2 = 11,
|
||||
IREG_flags_op,
|
||||
IREG_flags_res,
|
||||
IREG_flags_op1,
|
||||
IREG_flags_op2,
|
||||
|
||||
IREG_pc = 12,
|
||||
IREG_oldpc = 13,
|
||||
IREG_pc,
|
||||
IREG_oldpc,
|
||||
|
||||
IREG_eaaddr = 14,
|
||||
IREG_ea_seg = 15,
|
||||
IREG_op32 = 16,
|
||||
IREG_ssegsx = 17,
|
||||
IREG_eaaddr,
|
||||
IREG_ea_seg,
|
||||
IREG_op32,
|
||||
IREG_ssegsx,
|
||||
|
||||
IREG_rm_mod_reg = 18,
|
||||
IREG_rm_mod_reg,
|
||||
|
||||
IREG_acycs = 19,
|
||||
IREG_cycles = 20,
|
||||
IREG_cycles,
|
||||
|
||||
IREG_CS_base = 21,
|
||||
IREG_DS_base = 22,
|
||||
IREG_ES_base = 23,
|
||||
IREG_FS_base = 24,
|
||||
IREG_GS_base = 25,
|
||||
IREG_SS_base = 26,
|
||||
IREG_CS_base,
|
||||
IREG_DS_base,
|
||||
IREG_ES_base,
|
||||
IREG_FS_base,
|
||||
IREG_GS_base,
|
||||
IREG_SS_base,
|
||||
|
||||
IREG_CS_seg = 27,
|
||||
IREG_DS_seg = 28,
|
||||
IREG_ES_seg = 29,
|
||||
IREG_FS_seg = 30,
|
||||
IREG_GS_seg = 31,
|
||||
IREG_SS_seg = 32,
|
||||
|
||||
/*Temporary registers are stored on the stack, and are not guaranteed to
|
||||
be preserved across uOPs. They will not be written back if they will
|
||||
not be read again.*/
|
||||
IREG_temp0 = 33,
|
||||
IREG_temp1 = 34,
|
||||
IREG_temp2 = 35,
|
||||
IREG_temp3 = 36,
|
||||
|
||||
IREG_FPU_TOP = 37,
|
||||
|
||||
IREG_temp0d = 38,
|
||||
IREG_temp1d = 39,
|
||||
IREG_CS_seg,
|
||||
IREG_DS_seg,
|
||||
IREG_ES_seg,
|
||||
IREG_FS_seg,
|
||||
IREG_GS_seg,
|
||||
IREG_SS_seg,
|
||||
|
||||
/*FPU stack registers are physical registers. Use IREG_ST() / IREG_tag()
|
||||
to access.
|
||||
@@ -76,66 +62,79 @@ enum {
|
||||
used directly to index the stack. When it is clear, the difference
|
||||
between the current value of TOP and the value when the block was
|
||||
first compiled will be added to adjust for any changes in TOP.*/
|
||||
IREG_ST0 = 40,
|
||||
IREG_ST1 = 41,
|
||||
IREG_ST2 = 42,
|
||||
IREG_ST3 = 43,
|
||||
IREG_ST4 = 44,
|
||||
IREG_ST5 = 45,
|
||||
IREG_ST6 = 46,
|
||||
IREG_ST7 = 47,
|
||||
IREG_ST0,
|
||||
IREG_ST1,
|
||||
IREG_ST2,
|
||||
IREG_ST3,
|
||||
IREG_ST4,
|
||||
IREG_ST5,
|
||||
IREG_ST6,
|
||||
IREG_ST7,
|
||||
|
||||
IREG_tag0 = 48,
|
||||
IREG_tag1 = 49,
|
||||
IREG_tag2 = 50,
|
||||
IREG_tag3 = 51,
|
||||
IREG_tag4 = 52,
|
||||
IREG_tag5 = 53,
|
||||
IREG_tag6 = 54,
|
||||
IREG_tag7 = 55,
|
||||
IREG_tag0,
|
||||
IREG_tag1,
|
||||
IREG_tag2,
|
||||
IREG_tag3,
|
||||
IREG_tag4,
|
||||
IREG_tag5,
|
||||
IREG_tag6,
|
||||
IREG_tag7,
|
||||
|
||||
IREG_ST0_i64 = 56,
|
||||
IREG_ST1_i64 = 57,
|
||||
IREG_ST2_i64 = 58,
|
||||
IREG_ST3_i64 = 59,
|
||||
IREG_ST4_i64 = 60,
|
||||
IREG_ST5_i64 = 61,
|
||||
IREG_ST6_i64 = 62,
|
||||
IREG_ST7_i64 = 63,
|
||||
IREG_ST0_i64,
|
||||
IREG_ST1_i64,
|
||||
IREG_ST2_i64,
|
||||
IREG_ST3_i64,
|
||||
IREG_ST4_i64,
|
||||
IREG_ST5_i64,
|
||||
IREG_ST6_i64,
|
||||
IREG_ST7_i64,
|
||||
|
||||
IREG_MM0x = 64,
|
||||
IREG_MM1x = 65,
|
||||
IREG_MM2x = 66,
|
||||
IREG_MM3x = 67,
|
||||
IREG_MM4x = 68,
|
||||
IREG_MM5x = 69,
|
||||
IREG_MM6x = 70,
|
||||
IREG_MM7x = 71,
|
||||
IREG_MM0x,
|
||||
IREG_MM1x,
|
||||
IREG_MM2x,
|
||||
IREG_MM3x,
|
||||
IREG_MM4x,
|
||||
IREG_MM5x,
|
||||
IREG_MM6x,
|
||||
IREG_MM7x,
|
||||
|
||||
IREG_NPXCx = 72,
|
||||
IREG_NPXSx = 73,
|
||||
IREG_NPXCx,
|
||||
IREG_NPXSx,
|
||||
|
||||
IREG_flagsx = 74,
|
||||
IREG_eflagsx = 75,
|
||||
IREG_flagsx,
|
||||
IREG_eflagsx,
|
||||
|
||||
IREG_CS_limit_low = 76,
|
||||
IREG_DS_limit_low = 77,
|
||||
IREG_ES_limit_low = 78,
|
||||
IREG_FS_limit_low = 79,
|
||||
IREG_GS_limit_low = 80,
|
||||
IREG_SS_limit_low = 81,
|
||||
IREG_CS_limit_low,
|
||||
IREG_DS_limit_low,
|
||||
IREG_ES_limit_low,
|
||||
IREG_FS_limit_low,
|
||||
IREG_GS_limit_low,
|
||||
IREG_SS_limit_low,
|
||||
|
||||
IREG_CS_limit_high = 82,
|
||||
IREG_DS_limit_high = 83,
|
||||
IREG_ES_limit_high = 84,
|
||||
IREG_FS_limit_high = 85,
|
||||
IREG_GS_limit_high = 86,
|
||||
IREG_SS_limit_high = 87,
|
||||
IREG_CS_limit_high,
|
||||
IREG_DS_limit_high,
|
||||
IREG_ES_limit_high,
|
||||
IREG_FS_limit_high,
|
||||
IREG_GS_limit_high,
|
||||
IREG_SS_limit_high,
|
||||
|
||||
IREG_eaa16 = 88,
|
||||
IREG_x87_op = 89,
|
||||
IREG_eaa16,
|
||||
IREG_x87_op,
|
||||
|
||||
IREG_COUNT = 90,
|
||||
IREG_FPU_TOP,
|
||||
|
||||
/*Temporary registers are stored on the stack, and are not guaranteed to
|
||||
be preserved across uOPs. They will not be written back if they will
|
||||
not be read again.*/
|
||||
IREG_temp0,
|
||||
IREG_temp1,
|
||||
IREG_temp2,
|
||||
IREG_temp3,
|
||||
|
||||
IREG_temp0d,
|
||||
IREG_temp1d,
|
||||
|
||||
IREG_COUNT,
|
||||
|
||||
IREG_INVALID = 255,
|
||||
|
||||
@@ -279,6 +278,7 @@ ireg_seg_limit_high(x86seg *seg)
|
||||
}
|
||||
|
||||
extern uint8_t reg_last_version[IREG_COUNT];
|
||||
extern uint64_t dirty_ir_regs[2];
|
||||
|
||||
/*This version of the register must be calculated, regardless of whether it is
|
||||
apparently required or not. Do not optimise out.*/
|
||||
@@ -363,10 +363,12 @@ codegen_reg_write(int reg, int uop_nr)
|
||||
int last_version = reg_last_version[IREG_GET_REG(reg)];
|
||||
reg_version_t *version;
|
||||
|
||||
#ifndef RELEASE_BUILD
|
||||
if (IREG_GET_REG(reg) == IREG_INVALID)
|
||||
fatal("codegen_reg_write - IREG_INVALID\n");
|
||||
#endif
|
||||
if (dirty_ir_regs[(IREG_GET_REG(reg) >> 6) & 3] & (1ull << ((uint64_t)IREG_GET_REG(reg) & 0x3full))) {
|
||||
dirty_ir_regs[(IREG_GET_REG(reg) >> 6) & 3] &= ~(1ull << ((uint64_t)IREG_GET_REG(reg) & 0x3full));
|
||||
if ((IREG_GET_REG(reg) > IREG_EBX && IREG_GET_REG(reg) < IREG_temp0) && last_version > 0) {
|
||||
reg_version[IREG_GET_REG(reg)][last_version].flags |= REG_FLAGS_REQUIRED;
|
||||
}
|
||||
}
|
||||
ireg.reg = reg;
|
||||
ireg.version = last_version + 1;
|
||||
|
||||
@@ -376,12 +378,8 @@ codegen_reg_write(int reg, int uop_nr)
|
||||
}
|
||||
|
||||
reg_last_version[IREG_GET_REG(reg)]++;
|
||||
#ifndef RELEASE_BUILD
|
||||
if (!reg_last_version[IREG_GET_REG(reg)])
|
||||
fatal("codegen_reg_write - version overflow\n");
|
||||
else
|
||||
#endif
|
||||
if (reg_last_version[IREG_GET_REG(reg)] > REG_VERSION_MAX)
|
||||
|
||||
if (reg_last_version[IREG_GET_REG(reg)] > REG_VERSION_MAX)
|
||||
CPU_BLOCK_END();
|
||||
if (reg_last_version[IREG_GET_REG(reg)] > max_version_refcount)
|
||||
max_version_refcount = reg_last_version[IREG_GET_REG(reg)];
|
||||
|
||||
@@ -469,7 +469,7 @@ static const device_config_t isarom_quad_config[] = {
|
||||
.type = CONFIG_FNAME,
|
||||
.default_string = NULL,
|
||||
.default_int = 0,
|
||||
.file_filter = "ROM files (*.bin *.rom)|*.bin,*.rom",
|
||||
.file_filter = BIOS_FILE_FILTER,
|
||||
.spinner = { 0 },
|
||||
.selection = { },
|
||||
.bios = { { 0 } }
|
||||
|
||||
@@ -1139,7 +1139,7 @@ static const device_config_t ltsermouse_config[] = {
|
||||
.description = "RTS toggle",
|
||||
.type = CONFIG_BINARY,
|
||||
.default_string = NULL,
|
||||
.default_int = 0,
|
||||
.default_int = 1,
|
||||
.file_filter = NULL,
|
||||
.spinner = { 0 },
|
||||
.selection = { { 0 } },
|
||||
|
||||
@@ -37,24 +37,29 @@ novell_cardkey_read(uint16_t port, void *priv)
|
||||
novell_cardkey_t* cardkey = (novell_cardkey_t*)priv;
|
||||
uint8_t val = 0x00;
|
||||
switch (port) {
|
||||
/* Byte 5 high nibble + byte 4 high nibble */
|
||||
case 0x23A:
|
||||
val = (((cardkey->serial_number_str[11] > 'A') ? ((cardkey->serial_number_str[11] - 'A') + 10) : (cardkey->serial_number_str[11] - '0')) << 4) | (((cardkey->serial_number_str[9] > 'A') ? ((cardkey->serial_number_str[9] - 'A') + 10) : (cardkey->serial_number_str[9] - '0')) << 4);
|
||||
break;
|
||||
case 0x23B:
|
||||
val = (((cardkey->serial_number_str[10] > 'A') ? ((cardkey->serial_number_str[10] - 'A') + 10) : (cardkey->serial_number_str[10] - '0')) << 4) | (((cardkey->serial_number_str[8] > 'A') ? ((cardkey->serial_number_str[8] - 'A') + 10) : (cardkey->serial_number_str[8] - '0')) << 4);
|
||||
break;
|
||||
|
||||
/* Byte 5 low nibble + byte 4 low nibble */
|
||||
case 0x23B:
|
||||
val = (((cardkey->serial_number_str[11] > 'A') ? ((cardkey->serial_number_str[11] - 'A') + 10) : (cardkey->serial_number_str[11] - '0')) << 4) | (((cardkey->serial_number_str[9] > 'A') ? ((cardkey->serial_number_str[9] - 'A') + 10) : (cardkey->serial_number_str[9] - '0')) << 4);
|
||||
break;
|
||||
/* Byte 2 low nibble + byte 1 low nibble */
|
||||
case 0x23C:
|
||||
val = ((cardkey->serial_number_str[4] - '0') << 4) | ((cardkey->serial_number_str[2] - '0'));
|
||||
val = ((cardkey->serial_number_str[5] - '0') << 4) | ((cardkey->serial_number_str[3] - '0'));
|
||||
break;
|
||||
/* Byte 0 high nibble + byte 3 low nibble*/
|
||||
case 0x23D:
|
||||
val = ((cardkey->serial_number_str[1] - '0') << 4) | ((cardkey->serial_number_str[6] - '0'));
|
||||
break;
|
||||
case 0x23E:
|
||||
val = ((cardkey->serial_number_str[0] - '0') << 4) | ((cardkey->serial_number_str[7] - '0'));
|
||||
break;
|
||||
/* Byte 0 low nibble + byte 3 high nibble */
|
||||
case 0x23E:
|
||||
val = ((cardkey->serial_number_str[1] - '0') << 4) | ((cardkey->serial_number_str[6] - '0'));
|
||||
break;
|
||||
/* Byte 1 high nibble + byte 2 high nibble*/
|
||||
case 0x23F:
|
||||
val = ((cardkey->serial_number_str[3] - '0') << 4) | ((cardkey->serial_number_str[5] - '0'));
|
||||
val = ((cardkey->serial_number_str[2] - '0') << 4) | ((cardkey->serial_number_str[4] - '0'));
|
||||
break;
|
||||
}
|
||||
return val ^ 0xFF;
|
||||
@@ -110,7 +115,7 @@ static const device_config_t keycard_config[] = {
|
||||
|
||||
const device_t novell_keycard_device = {
|
||||
.name = "Novell NetWare 2.x Key Card",
|
||||
.internal_name = "mssystems",
|
||||
.internal_name = "novellkeycard",
|
||||
.flags = DEVICE_ISA,
|
||||
.local = 0,
|
||||
.init = novell_cardkey_init,
|
||||
|
||||
@@ -214,7 +214,7 @@ static const device_config_t compaticard_ii_config[] = {
|
||||
},
|
||||
{
|
||||
.name = "dma",
|
||||
.description = "DMA channel",
|
||||
.description = "DMA",
|
||||
.type = CONFIG_SELECTION,
|
||||
.default_string = NULL,
|
||||
.default_int = 2,
|
||||
@@ -272,7 +272,7 @@ static const device_config_t compaticard_iv_config[] = {
|
||||
},
|
||||
{
|
||||
.name = "dma",
|
||||
.description = "DMA channel",
|
||||
.description = "DMA",
|
||||
.type = CONFIG_SELECTION,
|
||||
.default_string = NULL,
|
||||
.default_int = 2,
|
||||
|
||||
@@ -19,6 +19,9 @@
|
||||
|
||||
#include <86box/rom.h>
|
||||
|
||||
#define INT_START_BLKNK_ENAB (1 << 0)
|
||||
#define INT_MASK 0xf
|
||||
|
||||
typedef struct xga_hwcursor_t {
|
||||
int ena;
|
||||
int x;
|
||||
@@ -84,13 +87,13 @@ typedef struct xga_t {
|
||||
uint8_t border_color;
|
||||
uint8_t direct_color;
|
||||
uint8_t dma_channel;
|
||||
uint8_t instance_isa;
|
||||
uint8_t instance_num;
|
||||
uint8_t ext_mem_addr;
|
||||
uint8_t vga_post;
|
||||
uint8_t addr_test;
|
||||
uint8_t *vram;
|
||||
uint8_t *changedvram;
|
||||
uint8_t int_ena;
|
||||
uint8_t int_stat;
|
||||
|
||||
int16_t hwc_pos_x;
|
||||
int16_t hwc_pos_y;
|
||||
@@ -151,7 +154,8 @@ typedef struct xga_t {
|
||||
int a5_test;
|
||||
int type;
|
||||
int bus;
|
||||
int busy;
|
||||
int src_reverse_order;
|
||||
int dst_reverse_order;
|
||||
|
||||
uint32_t linear_base;
|
||||
uint32_t linear_size;
|
||||
@@ -205,6 +209,10 @@ typedef struct xga_t {
|
||||
uint16_t dst_map_y;
|
||||
uint16_t pat_map_x;
|
||||
uint16_t pat_map_y;
|
||||
uint16_t clip_l;
|
||||
uint16_t clip_r;
|
||||
uint16_t clip_t;
|
||||
uint16_t clip_b;
|
||||
|
||||
int ssv_state;
|
||||
int pat_src;
|
||||
@@ -218,13 +226,13 @@ typedef struct xga_t {
|
||||
int y;
|
||||
int sx;
|
||||
int sy;
|
||||
int dx;
|
||||
int dy;
|
||||
int px;
|
||||
int py;
|
||||
int pattern;
|
||||
int command_len;
|
||||
int filling;
|
||||
int y_len;
|
||||
int x_len;
|
||||
|
||||
uint32_t short_stroke;
|
||||
uint32_t color_cmp;
|
||||
@@ -234,6 +242,7 @@ typedef struct xga_t {
|
||||
uint32_t bkgd_color;
|
||||
uint32_t command;
|
||||
uint32_t dir_cmd;
|
||||
uint32_t pattern_data;
|
||||
|
||||
uint8_t px_map_format[4];
|
||||
uint16_t px_map_width[4];
|
||||
|
||||
@@ -180,9 +180,9 @@ static const device_config_t pbl300sx_config[] = {
|
||||
.file_filter = "",
|
||||
.spinner = { 0 },
|
||||
.bios = {
|
||||
{ .name = "1991", .internal_name = "pbl300sx_1991", .bios_type = BIOS_NORMAL,
|
||||
{ .name = "Phoenix ROM BIOS PLUS 1.10 - Revision 19910723091302", .internal_name = "pbl300sx_1991", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/pbl300sx/V1.10_1113_910723.bin", "" } },
|
||||
{ .name = "1992", .internal_name = "pbl300sx", .bios_type = BIOS_NORMAL,
|
||||
{ .name = "Phoenix ROM BIOS PLUS 1.10 - Revision 19920910", .internal_name = "pbl300sx", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/pbl300sx/pb_l300sx_1992.bin", "" } },
|
||||
{ .files_no = 0 }
|
||||
},
|
||||
@@ -859,9 +859,9 @@ static const device_config_t dells333sl_config[] = {
|
||||
.file_filter = "",
|
||||
.spinner = { 0 },
|
||||
.bios = {
|
||||
{ .name = "J01 (Jostens Learning Corporation OEM)", .internal_name = "dells333sl_j01", .bios_type = BIOS_NORMAL,
|
||||
{ .name = "Phoenix ROM BIOS PLUS 1.10 - Revision J01 (Jostens Learning Corporation OEM)", .internal_name = "dells333sl_j01", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/dells333sl/DELL386.BIN", "" } },
|
||||
{ .name = "A02", .internal_name = "dells333sl", .bios_type = BIOS_NORMAL,
|
||||
{ .name = "Phoenix ROM BIOS PLUS 1.10 - Revision A02", .internal_name = "dells333sl", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/dells333sl/Dell_386SX_30807_UBIOS_B400_VLSI_VL82C311_Cirrus_Logic_GD5420.bin", "" } },
|
||||
{ .files_no = 0 }
|
||||
},
|
||||
|
||||
@@ -860,11 +860,11 @@ static const device_config_t pb450_config[] = {
|
||||
.file_filter = "",
|
||||
.spinner = { 0 },
|
||||
.bios = {
|
||||
{ .name = "PCI 1.0A", .internal_name = "pb450a" /*"pci10a"*/, .bios_type = BIOS_NORMAL,
|
||||
{ .name = "PhoenixBIOS 4.03 - Revision PCI 1.0A", .internal_name = "pb450a_pci10a" /*"pci10a"*/, .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/pb450/OPTI802.bin", "" } },
|
||||
{ .name = "PNP 1.1A", .internal_name = "pnp11a", .bios_type = BIOS_NORMAL,
|
||||
{ .name = "PhoenixBIOS 4.03 - Revision PNP 1.1A", .internal_name = "pb450a", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/pb450/PNP11A.bin", "" } },
|
||||
{ .name = "P4HS20 (Micro Firmware/Phoenix 4.05)", .internal_name = "p4hs20", .bios_type = BIOS_NORMAL,
|
||||
{ .name = "PhoenixBIOS 4.05 - Revision P4HS20 (by Micro Firmware)", .internal_name = "pb450a_p4hs20", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/pb450/p4hs20.bin", "" } },
|
||||
{ .files_no = 0 }
|
||||
},
|
||||
@@ -1769,11 +1769,11 @@ static const device_config_t sb486pv_config[] = {
|
||||
.file_filter = "",
|
||||
.spinner = { 0 },
|
||||
.bios = {
|
||||
{ .name = "AMI 062594 (0108)", .internal_name = "sb486pv", .bios_type = BIOS_NORMAL,
|
||||
{ .name = "AMI WinBIOS (062594) - Revision 0108", .internal_name = "sb486pv_0108", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/sb486pv/41-0108-062594-SATURN2.rom", "" } },
|
||||
{ .name = "AMI 062594 (0301)", .internal_name = "sb486pv_94", .bios_type = BIOS_NORMAL,
|
||||
{ .name = "AMI WinBIOS (062594) - Revision 0301", .internal_name = "sb486pv_0301", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/sb486pv/0301-062594-SATURN2.rom", "" } },
|
||||
{ .name = "AMI 071595 (1301)", .internal_name = "sb486pv_95", .bios_type = BIOS_NORMAL,
|
||||
{ .name = "AMIBIOS 6 (071595) - Revision 1301", .internal_name = "sb486pv", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/sb486pv/amiboot.rom", "" } },
|
||||
{ .files_no = 0 }
|
||||
},
|
||||
@@ -2296,9 +2296,9 @@ static const device_config_t hot433a_config[] = {
|
||||
.file_filter = "",
|
||||
.spinner = { 0 },
|
||||
.bios = {
|
||||
{ .name = "AMI", .internal_name = "hot433a", .bios_type = BIOS_NORMAL,
|
||||
{ .name = "AMIBIOS 5 (101094) - Revision 433AUS33", .internal_name = "hot433a", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/hot433/433AUS33.ROM", "" } },
|
||||
{ .name = "Award (eSupport update)", .internal_name = "hot433a_award", .bios_type = BIOS_NORMAL,
|
||||
{ .name = "AwardBIOS v4.51PG - Revision 2.5 (by eSupport)", .internal_name = "hot433a_v451pg", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/hot433/2A4X5H21.BIN", "" } },
|
||||
{ .files_no = 0 }
|
||||
},
|
||||
|
||||
@@ -53,7 +53,7 @@ machine_at_v12p_init(const machine_t *model)
|
||||
return ret;
|
||||
|
||||
device_context(model->device);
|
||||
fn = device_get_bios_file(machine_get_device(machine), device_get_config_bios("bios_versions"), 0);
|
||||
fn = device_get_bios_file(machine_get_device(machine), device_get_config_bios("bios"), 0);
|
||||
ret = bios_load_linear(fn, 0x000e0000, 131072, 0);
|
||||
device_context_restore();
|
||||
|
||||
@@ -79,30 +79,28 @@ machine_at_v12p_init(const machine_t *model)
|
||||
static const device_config_t v12p_config[] = {
|
||||
// clang-format off
|
||||
{
|
||||
.name = "bios_versions",
|
||||
.description = "BIOS Versions",
|
||||
.name = "bios",
|
||||
.description = "BIOS Version",
|
||||
.type = CONFIG_BIOS,
|
||||
.default_string = "v12p_14",
|
||||
.default_string = "v12p",
|
||||
.default_int = 0,
|
||||
.file_filter = "",
|
||||
.spinner = { 0 }, /*W1*/
|
||||
.bios = {
|
||||
{ .name = "Core Version 1.2 Version R1.4", .internal_name = "v12p_14", .bios_type = BIOS_NORMAL,
|
||||
{ .name = "Acer BIOS V1.2 - Revision R1.4", .internal_name = "v12p_r14", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/v12p/v12p_14.bin", "" } },
|
||||
{ .name = "Core Version 1.2 Version R1.6", .internal_name = "v12p_16", .bios_type = BIOS_NORMAL,
|
||||
{ .name = "Acer BIOS V1.2 - Revision R1.6", .internal_name = "v12p", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/v12p/v12p_16.bin", "" } },
|
||||
|
||||
{ .files_no = 0 }
|
||||
},
|
||||
},
|
||||
{ .name = "", .description = "", .type = CONFIG_END }
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
|
||||
|
||||
const device_t v12p_device = {
|
||||
.name = "Acer V12P",
|
||||
.internal_name = "v12p",
|
||||
.internal_name = "v12p_device",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = NULL,
|
||||
@@ -111,7 +109,7 @@ const device_t v12p_device = {
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = &v12p_config[0]
|
||||
.config = v12p_config
|
||||
};
|
||||
|
||||
void
|
||||
|
||||
@@ -92,7 +92,7 @@ machine_at_d842_init(const machine_t *model)
|
||||
return ret;
|
||||
|
||||
device_context(model->device);
|
||||
fn = device_get_bios_file(machine_get_device(machine), device_get_config_bios("bios_versions"), 0);
|
||||
fn = device_get_bios_file(machine_get_device(machine), device_get_config_bios("bios"), 0);
|
||||
ret = bios_load_linear(fn, 0x000e0000, 131072, 0);
|
||||
device_context_restore();
|
||||
|
||||
@@ -118,37 +118,36 @@ machine_at_d842_init(const machine_t *model)
|
||||
static const device_config_t d842_config[] = {
|
||||
// clang-format off
|
||||
{
|
||||
.name = "bios_versions",
|
||||
.description = "BIOS Versions",
|
||||
.name = "bios",
|
||||
.description = "BIOS Version",
|
||||
.type = CONFIG_BIOS,
|
||||
.default_string = "d842",
|
||||
.default_int = 0,
|
||||
.file_filter = "",
|
||||
.spinner = { 0 }, /*W1*/
|
||||
.bios = {
|
||||
{ .name = "Version 1.03 Revision 1.03.842 (11/24/1994)", .internal_name = "d842", .bios_type = BIOS_NORMAL,
|
||||
{ .name = "PhoenixBIOS Pentium 1.03 - Revision 1.03.842", .internal_name = "d842_103", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/d842/d842.BIN", "" } },
|
||||
{ .name = "Version 4.04 Revision 1.05.842 (03/15/1996)", .internal_name = "d842_mar96", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/d842/d842_mar96.bin", "" } },
|
||||
{ .name = "Version 4.04 Revision 1.06.842 (04/03/1998)", .internal_name = "d842_apr98", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/d842/d842_apr98.bin", "" } },
|
||||
{ .name = "Version 4.04 Revision 1.07.842 (06/02/1998)", .internal_name = "d842_jun98", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/d842/d842_jun98.BIN", "" } },
|
||||
{ .name = "Version 1.03 Revision 1.09.842 (07/08/1996)", .internal_name = "d842_jul96", .bios_type = BIOS_NORMAL,
|
||||
{ .name = "PhoenixBIOS Pentium 1.03 - Revision 1.09.842", .internal_name = "d842_109", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/d842/d842_jul96.bin", "" } },
|
||||
{ .name = "Version 1.03 Revision 1.10.842 (06/04/1998)", .internal_name = "d842_jun98_1", .bios_type = BIOS_NORMAL,
|
||||
{ .name = "PhoenixBIOS Pentium 1.03 - Revision 1.10.842", .internal_name = "d842", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/d842/d842_jun98_1.bin", "" } },
|
||||
{ .name = "PhoenixBIOS 4.04 - Revision 1.05.842", .internal_name = "d842_105", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/d842/d842_mar96.bin", "" } },
|
||||
{ .name = "PhoenixBIOS 4.04 - Revision 1.06.842", .internal_name = "d842_106", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/d842/d842_apr98.bin", "" } },
|
||||
{ .name = "PhoenixBIOS 4.04 - Revision 1.07.842", .internal_name = "d842_107", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/d842/d842_jun98.BIN", "" } },
|
||||
{ .files_no = 0 }
|
||||
},
|
||||
},
|
||||
{ .name = "", .description = "", .type = CONFIG_END }
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
|
||||
|
||||
const device_t d842_device = {
|
||||
.name = "Siemens-Nixdorf D842",
|
||||
.internal_name = "d842",
|
||||
.internal_name = "d842_device",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = NULL,
|
||||
@@ -157,7 +156,7 @@ const device_t d842_device = {
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = &d842_config[0]
|
||||
.config = d842_config
|
||||
};
|
||||
|
||||
int
|
||||
|
||||
@@ -624,7 +624,7 @@ machine_at_d943_init(const machine_t *model)
|
||||
return ret;
|
||||
|
||||
device_context(model->device);
|
||||
fn = device_get_bios_file(machine_get_device(machine), device_get_config_bios("bios_versions"), 0);
|
||||
fn = device_get_bios_file(machine_get_device(machine), device_get_config_bios("bios"), 0);
|
||||
ret = bios_load_linear(fn, 0x000e0000, 131072, 0);
|
||||
device_context_restore();
|
||||
|
||||
@@ -657,22 +657,23 @@ machine_at_d943_init(const machine_t *model)
|
||||
static const device_config_t d943_config[] = {
|
||||
// clang-format off
|
||||
{
|
||||
.name = "bios_versions",
|
||||
.description = "BIOS Versions",
|
||||
.name = "bios",
|
||||
.description = "BIOS Version",
|
||||
.type = CONFIG_BIOS,
|
||||
.default_string = "d943_oct96",
|
||||
.default_string = "d943",
|
||||
.default_int = 0,
|
||||
.file_filter = "",
|
||||
.spinner = { 0 }, /*W1*/
|
||||
.bios = {
|
||||
{ .name = "Version 4.05 Revision 1.02.943 (10/28/1996)", .internal_name = "d943_oct96", .bios_type = BIOS_NORMAL,
|
||||
{ .name = "PhoenixBIOS 4.05 - Revision 1.02.943", .internal_name = "d943_oct96", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/d943/d943_oct96.bin", "" } },
|
||||
{ .name = "Version 4.05 Revision 1.03.943 (12/12/1996)", .internal_name = "d943_dec96", .bios_type = BIOS_NORMAL,
|
||||
{ .name = "PhoenixBIOS 4.05 - Revision 1.03.943", .internal_name = "d943_dec96", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/d943/d943_dec96.bin", "" } },
|
||||
{ .name = "Version 4.05 Revision 1.05.943 (09/04/1997)", .internal_name = "d943_sept97", .bios_type = BIOS_NORMAL,
|
||||
{ .name = "PhoenixBIOS 4.05 - Revision 1.05.943", .internal_name = "d943_sept97", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/d943/d943_sept97.bin", "" } },
|
||||
{ .name = "Version 4.05 Revision 1.06.943 (10/29/1997)", .internal_name = "d943_oct97", .bios_type = BIOS_NORMAL,
|
||||
{ .name = "PhoenixBIOS 4.05 - Revision 1.06.943", .internal_name = "d943", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/d943/d943_oct97.bin", "" } },
|
||||
{ .files_no = 0 }
|
||||
},
|
||||
},
|
||||
{ .name = "", .description = "", .type = CONFIG_END }
|
||||
@@ -683,7 +684,7 @@ static const device_config_t d943_config[] = {
|
||||
|
||||
const device_t d943_device = {
|
||||
.name = "Siemens-Nixdorf D943",
|
||||
.internal_name = "d943",
|
||||
.internal_name = "d943_device",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = NULL,
|
||||
@@ -692,7 +693,7 @@ const device_t d943_device = {
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = &d943_config[0]
|
||||
.config = d943_config
|
||||
};
|
||||
|
||||
int
|
||||
@@ -800,11 +801,11 @@ static const device_config_t ap5s_config[] = {
|
||||
.file_filter = "",
|
||||
.spinner = { 0 },
|
||||
.bios = {
|
||||
{ .name = "04/22/96 1.20 4.50PG", .internal_name = "ap5s_450pg", .bios_type = BIOS_NORMAL,
|
||||
{ .name = "AwardBIOS v4.50PG - Revision R1.20", .internal_name = "ap5s_450pg", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/ap5s/ap5s120.bin", "" } },
|
||||
{ .name = "11/13/96 1.50 4.51PG", .internal_name = "ap5s", .bios_type = BIOS_NORMAL,
|
||||
{ .name = "AwardBIOS v4.51PG - Revision R1.50", .internal_name = "ap5s_r150", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/ap5s/AP5S150.BIN", "" } },
|
||||
{ .name = "06/25/97 1.60 4.51PG", .internal_name = "ap5s_latest", .bios_type = BIOS_NORMAL,
|
||||
{ .name = "AwardBIOS v4.51PG - Revision R1.60", .internal_name = "ap5s", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/ap5s/ap5s160.bin", "" } },
|
||||
{ .files_no = 0 }
|
||||
},
|
||||
@@ -961,11 +962,11 @@ static const device_config_t c5sbm2_config[] = {
|
||||
.file_filter = "",
|
||||
.spinner = { 0 },
|
||||
.bios = {
|
||||
{ .name = "4.50GP (07/17/1995)", .internal_name = "5sbm2", .bios_type = BIOS_NORMAL,
|
||||
{ .name = "AwardBIOS v4.50GP - Revision 07/17/1995", .internal_name = "5sbm2_v450gp", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/5sbm2/5SBM0717.BIN", "" } },
|
||||
{ .name = "4.50PG (03/21/1996)", .internal_name = "5sbm2_450pg", .bios_type = BIOS_NORMAL,
|
||||
{ .name = "AwardBIOS v4.50PG - Revision 03/26/1996", .internal_name = "5sbm2", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/5sbm2/5SBM0326.BIN", "" } },
|
||||
{ .name = "4.51PG (03/15/2000 Unicore Upgrade)", .internal_name = "5sbm2_451pg", .bios_type = BIOS_NORMAL,
|
||||
{ .name = "AwardBIOS v4.51PG - Revision 2.2 (by Unicore Software)", .internal_name = "5sbm2_451pg", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/5sbm2/2A5ICC3A.BIN", "" } },
|
||||
{ .files_no = 0 }
|
||||
},
|
||||
|
||||
@@ -7441,7 +7441,7 @@ const machine_t machines[] = {
|
||||
.min_multi = 0,
|
||||
.max_multi = 0
|
||||
},
|
||||
.bus_flags = MACHINE_PS2_VLB,
|
||||
.bus_flags = MACHINE_VLB,
|
||||
.flags = MACHINE_IDE | MACHINE_APM,
|
||||
.ram = {
|
||||
.min = 2048,
|
||||
|
||||
@@ -463,6 +463,7 @@ endif()
|
||||
|
||||
if (UNIX AND NOT APPLE AND NOT HAIKU)
|
||||
target_sources(ui PRIVATE x11_util.c)
|
||||
target_link_libraries(plat PRIVATE ${CMAKE_DL_LIBS})
|
||||
|
||||
find_package(X11 REQUIRED)
|
||||
target_link_libraries(ui PRIVATE X11::X11 X11::Xi)
|
||||
|
||||
@@ -147,6 +147,9 @@ msgstr "&Cor RGB"
|
||||
msgid "&RGB Grayscale"
|
||||
msgstr "Tons de cinza &RGB"
|
||||
|
||||
msgid "Generic RGBI color monitor"
|
||||
msgstr "Monitor colorido RGBI genérico"
|
||||
|
||||
msgid "&Amber monitor"
|
||||
msgstr "Monitor &âmbar"
|
||||
|
||||
@@ -384,6 +387,15 @@ msgstr "Ativar (UTC)"
|
||||
msgid "Dynamic Recompiler"
|
||||
msgstr "Recompilador dinâmico"
|
||||
|
||||
msgid "CPU frame size"
|
||||
msgstr "Tamanho de quadro do CPU"
|
||||
|
||||
msgid "Larger frames (less smooth)"
|
||||
msgstr "Quadros largos (menos suave)"
|
||||
|
||||
msgid "Smaller frames (smoother)"
|
||||
msgstr "Quadros menores (mais suave)"
|
||||
|
||||
msgid "Video:"
|
||||
msgstr "Vídeo:"
|
||||
|
||||
@@ -600,6 +612,9 @@ msgstr "RTC ISA:"
|
||||
msgid "ISA Memory Expansion"
|
||||
msgstr "Expansão de memória ISA"
|
||||
|
||||
msgid "ISA ROM Cards"
|
||||
msgstr "Placas ROM ISA"
|
||||
|
||||
msgid "Card 1:"
|
||||
msgstr "Placa 1:"
|
||||
|
||||
@@ -612,6 +627,27 @@ msgstr "Placa 3:"
|
||||
msgid "Card 4:"
|
||||
msgstr "Placa 4:"
|
||||
|
||||
msgid "Board 1"
|
||||
msgstr "Placa 1"
|
||||
|
||||
msgid "Board 2"
|
||||
msgstr "Placa 2"
|
||||
|
||||
msgid "Board 3"
|
||||
msgstr "Placa 3"
|
||||
|
||||
msgid "Board 4"
|
||||
msgstr "Placa 4"
|
||||
|
||||
msgid "Generic ISA ROM Board"
|
||||
msgstr "Placa ROM ISA Genérica"
|
||||
|
||||
msgid "Generic Dual ISA ROM Board"
|
||||
msgstr "Placa Dual ROM ISA Genérica"
|
||||
|
||||
msgid "Generic Quad ISA ROM Board"
|
||||
msgstr "Placa Quad ROM ISA Genérica"
|
||||
|
||||
msgid "ISABugger device"
|
||||
msgstr "Dispositivo ISABugger"
|
||||
|
||||
@@ -777,12 +813,39 @@ msgstr "Joystick padrão de 4 eixos, 4 botões"
|
||||
msgid "CH Flightstick Pro"
|
||||
msgstr "CH Flightstick Pro"
|
||||
|
||||
msgid "CH Flightstick Pro + CH Pedals"
|
||||
msgstr "CH Flightstick Pro + CH Pedais"
|
||||
|
||||
msgid "Microsoft SideWinder Pad"
|
||||
msgstr "Microsoft SideWinder Pad"
|
||||
|
||||
msgid "Thrustmaster Flight Control System"
|
||||
msgstr "Sistema de Controle de Voo Thrustmaster"
|
||||
|
||||
msgid "Thrustmaster FCS + Rudder Control System"
|
||||
msgstr "Thrustmaster SCV + Sistema de Controle de Leme"
|
||||
|
||||
msgid "2-button gamepad(s)"
|
||||
msgstr "Gamepad(s) de 2 botões"
|
||||
|
||||
msgid "2-button flight yoke"
|
||||
msgstr "Manche de voo de 2 botões"
|
||||
|
||||
msgid "4-button gamepad"
|
||||
msgstr "Gamepad de 4 botões"
|
||||
|
||||
msgid "4-button flight yoke"
|
||||
msgstr "Manche de voo de 4 botões"
|
||||
|
||||
msgid "2-button flight yoke with throttle"
|
||||
msgstr "Manche de voo de 2 botões com acelerador"
|
||||
|
||||
msgid "4-button flight yoke with throttle"
|
||||
msgstr "Manche de voo de 4 botões com acelerador"
|
||||
|
||||
msgid "Win95 Steering Wheel (3-axis, 4-button)"
|
||||
msgstr "Volante Win95 (3 eixos, 4 botões)"
|
||||
|
||||
msgid "None"
|
||||
msgstr "Nenhum"
|
||||
|
||||
@@ -841,7 +904,7 @@ msgid "About 86Box"
|
||||
msgstr "Sobre o 86Box"
|
||||
|
||||
msgid "86Box v"
|
||||
msgstr "86Box versão"
|
||||
msgstr "86Box versão "
|
||||
|
||||
msgid "An emulator of old computers\n\nAuthors: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information."
|
||||
msgstr "Um emulador de computadores antigos\n\nAutores: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, e outros.\n\nCom contribuições anteriores de Sarah Walker, leilei, JohnElliott, greatpsycho, e outros.\n\nTraduzido por: Altieres Lima da Silva, Nelson K. Hennemann Filho\n\nLançado sob a Licença Pública Geral GNU, versão 2 ou posterior. Veja o arquivo LICENSE para mais informações."
|
||||
@@ -1377,6 +1440,9 @@ msgstr "Mouse de barramento Microsoft (InPort)"
|
||||
msgid "Mouse Systems Serial Mouse"
|
||||
msgstr "Mouse serial Mouse Systems"
|
||||
|
||||
msgid "Mouse Systems Bus Mouse"
|
||||
msgstr "Mouse de barramento Mouse Systems"
|
||||
|
||||
msgid "Microsoft Serial Mouse"
|
||||
msgstr "Mouse serial Microsoft"
|
||||
|
||||
@@ -1413,12 +1479,54 @@ msgstr "Sistema MIDI"
|
||||
msgid "MIDI Input Device"
|
||||
msgstr "Dispositivo de entrada MIDI"
|
||||
|
||||
msgid "BIOS file"
|
||||
msgstr "Arquivo do BIOS"
|
||||
|
||||
msgid "BIOS file (ROM #1)"
|
||||
msgstr "Arquivo do BIOS (ROM #1)"
|
||||
|
||||
msgid "BIOS file (ROM #2)"
|
||||
msgstr "Arquivo do BIOS (ROM #2)"
|
||||
|
||||
msgid "BIOS file (ROM #3)"
|
||||
msgstr "Arquivo do BIOS (ROM #3)"
|
||||
|
||||
msgid "BIOS file (ROM #4)"
|
||||
msgstr "Arquivo do BIOS (ROM #4)"
|
||||
|
||||
msgid "BIOS Address"
|
||||
msgstr "Endereço do BIOS"
|
||||
|
||||
msgid "BIOS address (ROM #1)"
|
||||
msgstr "Endereço do BIOS (ROM #1)"
|
||||
|
||||
msgid "BIOS address (ROM #2)"
|
||||
msgstr "Endereço do BIOS (ROM #2)"
|
||||
|
||||
msgid "BIOS address (ROM #3)"
|
||||
msgstr "Endereço do BIOS (ROM #3)"
|
||||
|
||||
msgid "BIOS address (ROM #4)"
|
||||
msgstr "Endereço do BIOS (ROM #4)"
|
||||
|
||||
msgid "Enable BIOS extension ROM Writes"
|
||||
msgstr "Habilitar gravações na ROM de extensão do BIOS"
|
||||
|
||||
msgid "Enable BIOS extension ROM Writes (ROM #1)"
|
||||
msgstr "Habilitar gravações na ROM de extensão do BIOS (ROM #1)"
|
||||
|
||||
msgid "Enable BIOS extension ROM Writes (ROM #2)"
|
||||
msgstr "Habilitar gravações na ROM de extensão do BIOS (ROM #2)"
|
||||
|
||||
msgid "Enable BIOS extension ROM Writes (ROM #3)"
|
||||
msgstr "Habilitar gravações na ROM de extensão do BIOS (ROM #3)"
|
||||
|
||||
msgid "Enable BIOS extension ROM Writes (ROM #4)"
|
||||
msgstr "Habilitar gravações na ROM de extensão do BIOS (ROM #4)"
|
||||
|
||||
msgid "Linear framebuffer base"
|
||||
msgstr "Base do framebuffer linear"
|
||||
|
||||
msgid "Address"
|
||||
msgstr "Endereço"
|
||||
|
||||
@@ -1428,6 +1536,21 @@ msgstr "IRQ"
|
||||
msgid "BIOS Revision"
|
||||
msgstr "Revisão do BIOS"
|
||||
|
||||
msgid "BIOS Version"
|
||||
msgstr "Versão do BIOS"
|
||||
|
||||
msgid "BIOS Versions"
|
||||
msgstr "Versões de BIOS"
|
||||
|
||||
msgid "BIOS Language"
|
||||
msgstr "Idioma do BIOS"
|
||||
|
||||
msgid "IBM 5161 Expansion Unit"
|
||||
msgstr "Unidade de Expansão IBM 5161"
|
||||
|
||||
msgid "IBM Cassette Basic"
|
||||
msgstr "Cassete BASIC IBM"
|
||||
|
||||
msgid "Translate 26 -> 17"
|
||||
msgstr "Traduzir 26 -> 17"
|
||||
|
||||
@@ -1443,6 +1566,18 @@ msgstr "Inverter cores"
|
||||
msgid "BIOS size"
|
||||
msgstr "Tamanho do BIOS"
|
||||
|
||||
msgid "BIOS size (ROM #1)"
|
||||
msgstr "Tamanho do BIOS (ROM #1)"
|
||||
|
||||
msgid "BIOS size (ROM #2)"
|
||||
msgstr "Tamanho do BIOS (ROM #2)"
|
||||
|
||||
msgid "BIOS size (ROM #3)"
|
||||
msgstr "Tamanho do BIOS (ROM #3)"
|
||||
|
||||
msgid "BIOS size (ROM #4)"
|
||||
msgstr "Tamanho do BIOS (ROM #4)"
|
||||
|
||||
msgid "Map C0000-C7FFF as UMB"
|
||||
msgstr "Mapear C0000-C7FFF como UMB"
|
||||
|
||||
@@ -1518,6 +1653,9 @@ msgstr "Nível de reverberação"
|
||||
msgid "Interpolation Method"
|
||||
msgstr "Método de interpolação"
|
||||
|
||||
msgid "Dynamic Sample Loading"
|
||||
msgstr "Carregamento dinâmico de amostra"
|
||||
|
||||
msgid "Reverb Output Gain"
|
||||
msgstr "Ganho da saída da reverberação"
|
||||
|
||||
@@ -1605,6 +1743,12 @@ msgstr "DMA baixo"
|
||||
msgid "Enable Game port"
|
||||
msgstr "Ativar a porta do jogo"
|
||||
|
||||
msgid "SID Model"
|
||||
msgstr "Modelo do SID"
|
||||
|
||||
msgid "SID Filter Strength"
|
||||
msgstr "Força do Filtro SID"
|
||||
|
||||
msgid "Surround module"
|
||||
msgstr "Módulo surround"
|
||||
|
||||
@@ -1617,6 +1761,9 @@ msgstr "Aumentar a interrupção do CODEC na configuração do CODEC (necessári
|
||||
msgid "SB Address"
|
||||
msgstr "Endereço do SB"
|
||||
|
||||
msgid "Use EEPROM setting"
|
||||
msgstr "Usar configuração da EEPROM"
|
||||
|
||||
msgid "WSS IRQ"
|
||||
msgstr "WSS IRQ"
|
||||
|
||||
@@ -1701,6 +1848,9 @@ msgstr "Tipo de RAMDAC"
|
||||
msgid "Blend"
|
||||
msgstr "Mistura"
|
||||
|
||||
msgid "Font"
|
||||
msgstr "Fonte"
|
||||
|
||||
msgid "Bilinear filtering"
|
||||
msgstr "Filtragem bilinear"
|
||||
|
||||
@@ -1746,6 +1896,33 @@ msgstr "Velocidade de transferência"
|
||||
msgid "EMS mode"
|
||||
msgstr "Modo EMS"
|
||||
|
||||
msgid "EMS Address"
|
||||
msgstr "Endereço EMS"
|
||||
|
||||
msgid "EMS 1 Address"
|
||||
msgstr "Endereço EMS 1"
|
||||
|
||||
msgid "EMS 2 Address"
|
||||
msgstr "Endereço EMS 2"
|
||||
|
||||
msgid "EMS Memory Size"
|
||||
msgstr "Tamanho de Memória EMS"
|
||||
|
||||
msgid "EMS 1 Memory Size"
|
||||
msgstr "Tamanho de Memória EMS 1"
|
||||
|
||||
msgid "EMS 2 Memory Size"
|
||||
msgstr "Tamanho de Memória EMS 2"
|
||||
|
||||
msgid "Enable EMS"
|
||||
msgstr "Habilitar EMS"
|
||||
|
||||
msgid "Enable EMS 1"
|
||||
msgstr "Habilitar EMS 1"
|
||||
|
||||
msgid "Enable EMS 2"
|
||||
msgstr "Habilitar EMS 2"
|
||||
|
||||
msgid "Address for > 2 MB"
|
||||
msgstr "Endereço para > 2 MB"
|
||||
|
||||
@@ -1902,6 +2079,15 @@ msgstr "Interpolação sRGB"
|
||||
msgid "Linear interpolation"
|
||||
msgstr "Interpolação linear"
|
||||
|
||||
msgid "Has secondary 8x8 character set"
|
||||
msgstr "Tem conjunto secundário de caracteres 8x8"
|
||||
|
||||
msgid "Has Quadcolor II daughter board"
|
||||
msgstr "Tem placa filha Quadcolor II"
|
||||
|
||||
msgid "Alternate monochrome contrast"
|
||||
msgstr "Contraste monocromático alternativo"
|
||||
|
||||
msgid "128 KB"
|
||||
msgstr "128 KB"
|
||||
|
||||
@@ -1935,6 +2121,9 @@ msgstr "Âmbar"
|
||||
msgid "Gray"
|
||||
msgstr "Cinza"
|
||||
|
||||
msgid "Grayscale"
|
||||
msgstr "Escala de cinza"
|
||||
|
||||
msgid "Color"
|
||||
msgstr "Colorido"
|
||||
|
||||
@@ -1950,6 +2139,12 @@ msgstr "Outros idiomas"
|
||||
msgid "Bochs latest"
|
||||
msgstr "Bochs mais recente"
|
||||
|
||||
msgid "Apply overscan deltas"
|
||||
msgstr "Aplicar deltas de overscan"
|
||||
|
||||
msgid "Mono Interlaced"
|
||||
msgstr "Monocromático entrelaçado"
|
||||
|
||||
msgid "Mono Non-Interlaced"
|
||||
msgstr "Monocromático não entrelaçado"
|
||||
|
||||
@@ -2076,6 +2271,12 @@ msgstr "Clone IBM 8514/A (ISA)"
|
||||
msgid "Vendor"
|
||||
msgstr "Fabricante"
|
||||
|
||||
msgid "30 Hz (JMP2 = 1)"
|
||||
msgstr "30 Hz (JMP2 = 1)"
|
||||
|
||||
msgid "60 Hz (JMP2 = 2)"
|
||||
msgstr "60 Hz (JMP2 = 2)"
|
||||
|
||||
msgid "Generic PC/XT Memory Expansion"
|
||||
msgstr "Expansão de memória genérica PC/XT"
|
||||
|
||||
@@ -2189,3 +2390,15 @@ msgstr "Alternar pausa"
|
||||
|
||||
msgid "Toggle mute"
|
||||
msgstr "Alternar mudo"
|
||||
|
||||
msgid "Text files"
|
||||
msgstr "Arquivos de texto"
|
||||
|
||||
msgid "ROM files (*.bin *.rom)|*.bin,*.rom"
|
||||
msgstr "Arquivos de ROM (*.bin *.rom)|*.bin,*.rom"
|
||||
|
||||
msgid "ROM files"
|
||||
msgstr "Arquivos de ROM"
|
||||
|
||||
msgid "SoundFont files"
|
||||
msgstr "Arquivos SoundFont"
|
||||
|
||||
@@ -390,6 +390,15 @@ msgstr "Включено (UTC)"
|
||||
msgid "Dynamic Recompiler"
|
||||
msgstr "Динамический рекомпилятор"
|
||||
|
||||
msgid "CPU frame size"
|
||||
msgstr "Размер кадра ЦП"
|
||||
|
||||
msgid "Larger frames (less smooth)"
|
||||
msgstr "Большие кадры (менее плавные)"
|
||||
|
||||
msgid "Smaller frames (smoother)"
|
||||
msgstr "Меньшие кадры (более плавные)"
|
||||
|
||||
msgid "Video:"
|
||||
msgstr "Видеокарта 1:"
|
||||
|
||||
@@ -765,9 +774,21 @@ msgstr "Неверное устройство PCap"
|
||||
msgid "2-axis, 2-button joystick(s)"
|
||||
msgstr "2-осевой, 2-кнопочный джойстик"
|
||||
|
||||
msgid "2-button gamepad(s)"
|
||||
msgstr "2-кнопочный геймпад"
|
||||
|
||||
msgid "2-button flight yoke"
|
||||
msgstr "2-кнопочный flight yoke"
|
||||
|
||||
msgid "2-axis, 4-button joystick"
|
||||
msgstr "2-осевой, 4-кнопочный джойстик"
|
||||
|
||||
msgid "4-button gamepad"
|
||||
msgstr "4-кнопочный геймпад"
|
||||
|
||||
msgid "4-button flight yoke"
|
||||
msgstr "4-кнопочный flight yoke"
|
||||
|
||||
msgid "2-axis, 6-button joystick"
|
||||
msgstr "2-осевой, 6-кнопочный джойстик"
|
||||
|
||||
@@ -777,21 +798,36 @@ msgstr "2-осевой, 8-кнопочный джойстик"
|
||||
msgid "3-axis, 2-button joystick"
|
||||
msgstr "3-осевой, 2-кнопочный джойстик"
|
||||
|
||||
msgid "2-button flight yoke with throttle"
|
||||
msgstr "2-кнопочный flight yoke с дросселем"
|
||||
|
||||
msgid "3-axis, 4-button joystick"
|
||||
msgstr "3-осевой, 4-кнопочный джойстик"
|
||||
|
||||
msgid "Win95 Steering Wheel (3-axis, 4-button)"
|
||||
msgstr "Руль Win95 (3-осевой, 4-кнопочный)"
|
||||
|
||||
msgid "4-button flight yoke with throttle"
|
||||
msgstr "4-кнопочный flight yoke с дросселем"
|
||||
|
||||
msgid "4-axis, 4-button joystick"
|
||||
msgstr "4-осевой, 4-кнопочный джойстик"
|
||||
|
||||
msgid "CH Flightstick Pro"
|
||||
msgstr "CH Flightstick Pro"
|
||||
|
||||
msgid "CH Flightstick Pro + CH Pedals"
|
||||
msgstr "CH Flightstick Pro + CH Педали"
|
||||
|
||||
msgid "Microsoft SideWinder Pad"
|
||||
msgstr "Microsoft SideWinder Pad"
|
||||
|
||||
msgid "Thrustmaster Flight Control System"
|
||||
msgstr "Система управления полётом Thrustmaster"
|
||||
|
||||
msgid "Thrustmaster FCS + Rudder Control System"
|
||||
msgstr "Thrustmaster FCS + Система управления рулем"
|
||||
|
||||
msgid "None"
|
||||
msgstr "Нет"
|
||||
|
||||
@@ -1386,6 +1422,9 @@ msgstr "Bus-мышь Microsoft (InPort)"
|
||||
msgid "Mouse Systems Serial Mouse"
|
||||
msgstr "COM-мышь Mouse Systems"
|
||||
|
||||
msgid "Mouse Systems Bus Mouse"
|
||||
msgstr "Bus-мышь Mouse Systems"
|
||||
|
||||
msgid "Microsoft Serial Mouse"
|
||||
msgstr "COM-мышь Microsoft"
|
||||
|
||||
@@ -1686,6 +1725,12 @@ msgstr "Низкий DMA"
|
||||
msgid "Enable Game port"
|
||||
msgstr "Включить игровой порт"
|
||||
|
||||
msgid "SID Model"
|
||||
msgstr "Модель SID"
|
||||
|
||||
msgid "SID Filter Strength"
|
||||
msgstr "Сила фильтра SID"
|
||||
|
||||
msgid "Surround module"
|
||||
msgstr "Модуль объёмного звучания"
|
||||
|
||||
@@ -1788,6 +1833,18 @@ msgstr "Смесь"
|
||||
msgid "Font"
|
||||
msgstr "Шрифт"
|
||||
|
||||
msgid "Has secondary 8x8 character set"
|
||||
msgstr "Вторичный набор символов 8x8"
|
||||
|
||||
msgid "Has Quadcolor II daughter board"
|
||||
msgstr "Дочерняя плата Quadcolor II"
|
||||
|
||||
msgid "Alternate monochrome contrast"
|
||||
msgstr "Альтернативный монохромный контраст"
|
||||
|
||||
msgid "Video chroma-keying"
|
||||
msgstr "Видео хромакеинг"
|
||||
|
||||
msgid "Bilinear filtering"
|
||||
msgstr "Билинейная фильтрация"
|
||||
|
||||
@@ -2154,6 +2211,9 @@ msgstr "Скорость передачи данных через канал"
|
||||
msgid "Named Pipe (Server)"
|
||||
msgstr "Именованный пайп (Сервер)"
|
||||
|
||||
msgid "Named Pipe (Client)"
|
||||
msgstr "Именованный пайп (Клиент)"
|
||||
|
||||
msgid "Host Serial Passthrough"
|
||||
msgstr "Последовательный порт хоста"
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -56,6 +56,10 @@ extern "C" {
|
||||
#include <86box/gdbstub.h>
|
||||
#include <86box/version.h>
|
||||
#include <86box/renderdefs.h>
|
||||
#ifdef Q_OS_LINUX
|
||||
#define GAMEMODE_AUTO
|
||||
#include "../unix/gamemode/gamemode_client.h"
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef Q_OS_WINDOWS
|
||||
@@ -803,6 +807,8 @@ main(int argc, char *argv[])
|
||||
});
|
||||
QObject::connect(main_window, &MainWindow::vmmRunningStateChanged, &manager_socket, &VMManagerClientSocket::clientRunningStateChanged);
|
||||
main_window->installEventFilter(&manager_socket);
|
||||
|
||||
manager_socket.sendWinIdMessage(main_window->winId());
|
||||
}
|
||||
|
||||
// pc_reset_hard_init();
|
||||
|
||||
@@ -1480,11 +1480,13 @@ MainWindow::eventFilter(QObject *receiver, QEvent *event)
|
||||
if (receiver == this) {
|
||||
static auto curdopause = dopause;
|
||||
if (event->type() == QEvent::WindowBlocked) {
|
||||
window_blocked = true;
|
||||
curdopause = dopause;
|
||||
plat_pause(isShowMessage ? 2 : 1);
|
||||
emit setMouseCapture(false);
|
||||
releaseKeyboard();
|
||||
} else if (event->type() == QEvent::WindowUnblocked) {
|
||||
window_blocked = false;
|
||||
plat_pause(curdopause);
|
||||
}
|
||||
}
|
||||
@@ -2138,7 +2140,7 @@ MainWindow::updateUiPauseState()
|
||||
QString(tr("Pause execution"));
|
||||
ui->actionPause->setIcon(pause_icon);
|
||||
ui->actionPause->setToolTip(tooltip_text);
|
||||
emit vmmRunningStateChanged(static_cast<VMManagerProtocol::RunningState>(dopause));
|
||||
emit vmmRunningStateChanged(static_cast<VMManagerProtocol::RunningState>(window_blocked ? (dopause ? VMManagerProtocol::RunningState::PausedWaiting : VMManagerProtocol::RunningState::RunningWaiting) : (VMManagerProtocol::RunningState)dopause));
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -212,6 +212,7 @@ private:
|
||||
QIcon caps_icon_off, scroll_icon_off, num_icon_off, kana_icon_off;
|
||||
|
||||
bool isShowMessage = false;
|
||||
bool window_blocked = false;
|
||||
};
|
||||
|
||||
#endif // QT_MAINWINDOW_HPP
|
||||
|
||||
@@ -166,6 +166,10 @@ int ignoreNextMouseEvent = 1;
|
||||
void
|
||||
RendererStack::mouseReleaseEvent(QMouseEvent *event)
|
||||
{
|
||||
#ifdef Q_OS_WINDOWS
|
||||
rw_hwnd = (HWND) this->winId();
|
||||
#endif
|
||||
|
||||
if (!dopause && this->geometry().contains(m_monitor_index >= 1 ? event->globalPos() : event->pos()) &&
|
||||
(event->button() == Qt::LeftButton) && !mouse_capture &&
|
||||
(isMouseDown & 1) && (kbd_req_capture || (mouse_get_buttons() != 0)) &&
|
||||
@@ -410,14 +414,8 @@ RendererStack::createRenderer(Renderer renderer)
|
||||
#endif
|
||||
}
|
||||
if (current.get() == nullptr) {
|
||||
#ifdef Q_OS_WINDOWS
|
||||
rw_hwnd = NULL;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
#ifdef Q_OS_WINDOWS
|
||||
rw_hwnd = (HWND) this->winId();
|
||||
#endif
|
||||
current->setFocusPolicy(Qt::NoFocus);
|
||||
current->setFocusProxy(this);
|
||||
current->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
|
||||
@@ -315,101 +315,69 @@
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QFrame" name="horizontalFrame">
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Time synchronization</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
<widget class="QRadioButton" name="radioButtonDisabled">
|
||||
<property name="text">
|
||||
<string>Disabled</string>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Time synchronization</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QRadioButton" name="radioButtonDisabled">
|
||||
<property name="text">
|
||||
<string>Disabled</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QRadioButton" name="radioButtonUTC">
|
||||
<property name="text">
|
||||
<string>Enabled (UTC)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QRadioButton" name="radioButtonLocalTime">
|
||||
<property name="text">
|
||||
<string>Enabled (local time)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
<item row="2" column="0">
|
||||
<widget class="QRadioButton" name="radioButtonUTC">
|
||||
<property name="text">
|
||||
<string>Enabled (UTC)</string>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>CPU frame size</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop</set>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QRadioButton" name="radioButtonLargerFrames">
|
||||
<property name="text">
|
||||
<string>Larger frames (less smooth)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="radioButtonSmallerFrames">
|
||||
<property name="text">
|
||||
<string>Smaller frames (smoother)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="3">
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Vertical</enum>
|
||||
<item row="1" column="0">
|
||||
<widget class="QRadioButton" name="radioButtonLocalTime">
|
||||
<property name="text">
|
||||
<string>Enabled (local time)</string>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>CPU frame size</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop</set>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QRadioButton" name="radioButtonLargerFrames">
|
||||
<property name="text">
|
||||
<string>Larger frames (less smooth)</string>
|
||||
</property>
|
||||
</spacer>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="radioButtonSmallerFrames">
|
||||
<property name="text">
|
||||
<string>Smaller frames (smoother)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
|
||||
@@ -59,7 +59,7 @@ VMManagerAddMachine(QWidget *parent) : QWizard(parent)
|
||||
|
||||
// Wizard wants to resize based on image. This keeps the size
|
||||
setMinimumSize(size());
|
||||
setOption(HaveHelpButton, true);
|
||||
setOption(HaveHelpButton, false);
|
||||
// setPixmap(LogoPixmap, QPixmap(":/settings/qt/icons/86Box-gray.ico"));
|
||||
|
||||
connect(this, &QWizard::helpRequested, this, &VMManagerAddMachine::showHelp);
|
||||
|
||||
@@ -218,7 +218,9 @@ VMManagerClientSocket::eventFilter(QObject *obj, QEvent *event)
|
||||
if (event->type() == QEvent::WindowBlocked) {
|
||||
running_state = dopause ? VMManagerProtocol::RunningState::PausedWaiting : VMManagerProtocol::RunningState::RunningWaiting;
|
||||
clientRunningStateChanged(running_state);
|
||||
window_blocked = true;
|
||||
} else if (event->type() == QEvent::WindowUnblocked) {
|
||||
window_blocked = false;
|
||||
running_state = dopause ? VMManagerProtocol::RunningState::Paused : VMManagerProtocol::RunningState::Running;
|
||||
clientRunningStateChanged(running_state);
|
||||
}
|
||||
@@ -226,11 +228,22 @@ VMManagerClientSocket::eventFilter(QObject *obj, QEvent *event)
|
||||
return QObject::eventFilter(obj, event);
|
||||
}
|
||||
|
||||
void
|
||||
VMManagerClientSocket::sendWinIdMessage(WId id)
|
||||
{
|
||||
QJsonObject extra_object;
|
||||
extra_object["params"] = static_cast<int>(id);
|
||||
sendMessageWithObject(VMManagerProtocol::ClientMessage::WinIdMessage, extra_object);
|
||||
}
|
||||
|
||||
void
|
||||
VMManagerClientSocket::clientRunningStateChanged(VMManagerProtocol::RunningState state) const
|
||||
{
|
||||
QJsonObject extra_object;
|
||||
if ((state == VMManagerProtocol::RunningState::Paused
|
||||
|| state == VMManagerProtocol::RunningState::Running) && window_blocked) {
|
||||
state = (state == VMManagerProtocol::RunningState::Paused) ? VMManagerProtocol::RunningState::PausedWaiting : VMManagerProtocol::RunningState::RunningWaiting;
|
||||
}
|
||||
extra_object["status"] = static_cast<int>(state);
|
||||
sendMessageWithObject(VMManagerProtocol::ClientMessage::RunningStateChanged, extra_object);
|
||||
|
||||
}
|
||||
|
||||
@@ -31,6 +31,8 @@ public:
|
||||
explicit VMManagerClientSocket(QObject* object = nullptr);
|
||||
bool IPCConnect(const QString &server);
|
||||
|
||||
void sendWinIdMessage(WId id);
|
||||
|
||||
signals:
|
||||
void pause();
|
||||
void ctrlaltdel();
|
||||
@@ -47,6 +49,7 @@ private:
|
||||
QString server_name;
|
||||
QLocalSocket *socket;
|
||||
bool server_connected;
|
||||
bool window_blocked = false;
|
||||
void connected() const;
|
||||
void disconnected() const;
|
||||
static void connectionError(QLocalSocket::LocalSocketError socketError);
|
||||
|
||||
@@ -336,6 +336,17 @@ VMManagerDetails::updateProcessStatus() {
|
||||
connect(startPauseButton, &QToolButton::clicked, sysconfig, &VMManagerSystem::startButtonPressed);
|
||||
startPauseButton->setToolTip(tr("Start"));
|
||||
}
|
||||
|
||||
if (sysconfig->window_obscured) {
|
||||
resetButton->setDisabled(true);
|
||||
stopButton->setDisabled(true);
|
||||
cadButton->setDisabled(true);
|
||||
startPauseButton->setDisabled(true);
|
||||
configureButton->setDisabled(true);
|
||||
} else {
|
||||
configureButton->setDisabled(false);
|
||||
startPauseButton->setDisabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -48,7 +48,7 @@ VMManagerMain::VMManagerMain(QWidget *parent) :
|
||||
|
||||
// Set up the context menu for the list view
|
||||
ui->listView->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
connect(ui->listView, &QListView::customContextMenuRequested, [this](const QPoint &pos) {
|
||||
connect(ui->listView, &QListView::customContextMenuRequested, [this, parent](const QPoint &pos) {
|
||||
const auto indexAt = ui->listView->indexAt(pos);
|
||||
if (indexAt.isValid()) {
|
||||
QMenu contextMenu(tr("Context Menu"), ui->listView);
|
||||
@@ -59,6 +59,7 @@ VMManagerMain::VMManagerMain(QWidget *parent) :
|
||||
connect(&nameChangeAction, &QAction::triggered, ui->listView, [this, indexAt] {
|
||||
updateDisplayName(indexAt);
|
||||
});
|
||||
nameChangeAction.setEnabled(!selected_sysconfig->window_obscured);
|
||||
|
||||
QAction openSystemFolderAction(tr("Open folder"));
|
||||
contextMenu.addAction(&openSystemFolderAction);
|
||||
@@ -82,6 +83,18 @@ VMManagerMain::VMManagerMain(QWidget *parent) :
|
||||
selected_sysconfig->setIcon(iconName);
|
||||
}
|
||||
});
|
||||
setSystemIcon.setEnabled(!selected_sysconfig->window_obscured);
|
||||
|
||||
QAction killIcon(tr("&Kill"));
|
||||
contextMenu.addAction(&killIcon);
|
||||
connect(&killIcon, &QAction::triggered, [this, parent] {
|
||||
QMessageBox msgbox(QMessageBox::Warning, tr("Warning"), tr("Killing a virtual machine can cause data loss. Only do this if 86Box.exe process gets stuck.\n\nDo you really wish to kill the virtual machine \"%1\"?").arg(selected_sysconfig->displayName), QMessageBox::StandardButton::Yes | QMessageBox::StandardButton::No, parent);
|
||||
msgbox.exec();
|
||||
if (msgbox.result() == QMessageBox::Yes) {
|
||||
selected_sysconfig->process->kill();
|
||||
}
|
||||
});
|
||||
killIcon.setEnabled(selected_sysconfig->process->state() == QProcess::Running);
|
||||
|
||||
contextMenu.addSeparator();
|
||||
|
||||
@@ -131,12 +144,14 @@ VMManagerMain::VMManagerMain(QWidget *parent) :
|
||||
emit updateStatusRight(totalCountString());
|
||||
});
|
||||
|
||||
#if EMU_BUILD_NUM != 0
|
||||
// Start update check after a slight delay
|
||||
QTimer::singleShot(1000, this, [this] {
|
||||
if(updateCheck) {
|
||||
backgroundUpdateCheckStart();
|
||||
}
|
||||
});
|
||||
#endif
|
||||
}
|
||||
|
||||
VMManagerMain::~VMManagerMain() {
|
||||
@@ -276,7 +291,9 @@ VMManagerMain::loadSettings()
|
||||
{
|
||||
const auto config = new VMManagerConfig(VMManagerConfig::ConfigType::General);
|
||||
const auto lastSelection = config->getStringValue("last_selection");
|
||||
#if EMU_BUILD_NUM != 0
|
||||
updateCheck = config->getStringValue("update_check").toInt();
|
||||
#endif
|
||||
regexSearch = config->getStringValue("regex_search").toInt();
|
||||
|
||||
const auto matches = ui->listView->model()->match(vm_model->index(0, 0), VMManagerModel::Roles::ConfigName, QVariant::fromValue(lastSelection));
|
||||
@@ -453,10 +470,10 @@ VMManagerMain::onPreferencesUpdated()
|
||||
}
|
||||
}
|
||||
|
||||
#if EMU_BUILD_NUM != 0
|
||||
void
|
||||
VMManagerMain::backgroundUpdateCheckStart() const
|
||||
{
|
||||
#if EMU_BUILD_NUM != 0
|
||||
auto updateChannel = UpdateCheck::UpdateChannel::CI;
|
||||
#ifdef RELEASE_BUILD
|
||||
updateChannel = UpdateCheck::UpdateChannel::Stable;
|
||||
@@ -465,7 +482,6 @@ VMManagerMain::backgroundUpdateCheckStart() const
|
||||
connect(updateCheck, &UpdateCheck::updateCheckComplete, this, &VMManagerMain::backgroundUpdateCheckComplete);
|
||||
connect(updateCheck, &UpdateCheck::updateCheckError, this, &VMManagerMain::backgroundUpdateCheckError);
|
||||
updateCheck->checkForUpdates();
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
@@ -483,6 +499,7 @@ VMManagerMain::backgroundUpdateCheckError(const QString &errorMsg)
|
||||
qDebug() << "Update check failed with the following error:" << errorMsg;
|
||||
// TODO: Update the status bar
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
VMManagerMain::showTextFileContents(const QString &title, const QString &path)
|
||||
|
||||
@@ -85,7 +85,9 @@ private:
|
||||
VMManagerSystem *selected_sysconfig;
|
||||
// VMManagerConfig *config;
|
||||
QSortFilterProxyModel *proxy_model;
|
||||
#if EMU_BUILD_NUM != 0
|
||||
bool updateCheck = false;
|
||||
#endif
|
||||
bool regexSearch = false;
|
||||
|
||||
// void updateSelection(const QItemSelection &selected,
|
||||
@@ -97,11 +99,15 @@ private:
|
||||
void loadSettings();
|
||||
[[nodiscard]] bool currentSelectionIsValid() const;
|
||||
[[nodiscard]] QString totalCountString() const;
|
||||
#if EMU_BUILD_NUM != 0
|
||||
void backgroundUpdateCheckStart() const;
|
||||
#endif
|
||||
void showTextFileContents(const QString &title, const QString &path);
|
||||
private slots:
|
||||
#if EMU_BUILD_NUM != 0
|
||||
void backgroundUpdateCheckComplete(const UpdateCheck::UpdateResult &result);
|
||||
void backgroundUpdateCheckError(const QString &errorMsg);
|
||||
#endif
|
||||
};
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
@@ -181,3 +181,9 @@ VMManagerMainWindow::checkForUpdatesTriggered()
|
||||
const auto updateCheck = new UpdateCheckDialog(updateChannel);
|
||||
updateCheck->exec();
|
||||
}
|
||||
|
||||
void VMManagerMainWindow::on_actionExit_triggered()
|
||||
{
|
||||
this->close();
|
||||
}
|
||||
|
||||
|
||||
@@ -52,6 +52,8 @@ private slots:
|
||||
void preferencesTriggered();
|
||||
static void checkForUpdatesTriggered();
|
||||
|
||||
void on_actionExit_triggered();
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *event) override;
|
||||
};
|
||||
|
||||
@@ -35,6 +35,8 @@
|
||||
<string>File</string>
|
||||
</property>
|
||||
<addaction name="actionNew_Machine"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionExit"/>
|
||||
</widget>
|
||||
<addaction name="menuFile"/>
|
||||
<addaction name="menuTools"/>
|
||||
@@ -204,6 +206,17 @@
|
||||
<string>Check for updates</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionExit">
|
||||
<property name="icon">
|
||||
<iconset theme="QIcon::ThemeIcon::ApplicationExit"/>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Exit</string>
|
||||
</property>
|
||||
<property name="menuRole">
|
||||
<enum>QAction::MenuRole::QuitRole</enum>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="../qt_resources.qrc"/>
|
||||
|
||||
@@ -44,8 +44,12 @@ VMManagerPreferences(QWidget *parent) : ui(new Ui::VMManagerPreferences)
|
||||
}
|
||||
|
||||
// TODO: Defaults
|
||||
#if EMU_BUILD_NUM != 0
|
||||
const auto configUpdateCheck = config->getStringValue("update_check").toInt();
|
||||
ui->updateCheckBox->setChecked(configUpdateCheck);
|
||||
#else
|
||||
ui->updateCheckBox->setVisible(false);
|
||||
#endif
|
||||
const auto useRegexSearch = config->getStringValue("regex_search").toInt();
|
||||
ui->regexSearchCheckBox->setChecked(useRegexSearch);
|
||||
|
||||
@@ -70,7 +74,9 @@ VMManagerPreferences::accept()
|
||||
{
|
||||
const auto config = new VMManagerConfig(VMManagerConfig::ConfigType::General);
|
||||
config->setStringValue("system_directory", ui->systemDirectory->text());
|
||||
#if EMU_BUILD_NUM != 0
|
||||
config->setStringValue("update_check", ui->updateCheckBox->isChecked() ? "1" : "0");
|
||||
#endif
|
||||
config->setStringValue("regex_search", ui->regexSearchCheckBox->isChecked() ? "1" : "0");
|
||||
QDialog::accept();
|
||||
}
|
||||
@@ -79,4 +85,4 @@ void
|
||||
VMManagerPreferences::reject()
|
||||
{
|
||||
QDialog::reject();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,6 +91,8 @@ VMManagerProtocol::getClientMessageType(const QJsonObject &json_document)
|
||||
return VMManagerProtocol::ClientMessage::WindowUnblocked;
|
||||
} else if (message_type == "RunningStateChanged") {
|
||||
return VMManagerProtocol::ClientMessage::RunningStateChanged;
|
||||
} else if (message_type == "WinIdMessage") {
|
||||
return VMManagerProtocol::ClientMessage::WinIdMessage;
|
||||
}
|
||||
return VMManagerProtocol::ClientMessage::UnknownMessage;
|
||||
}
|
||||
|
||||
@@ -54,6 +54,7 @@ public:
|
||||
WindowBlocked,
|
||||
WindowUnblocked,
|
||||
RunningStateChanged,
|
||||
WinIdMessage,
|
||||
UnknownMessage,
|
||||
};
|
||||
Q_ENUM(ClientMessage);
|
||||
@@ -82,6 +83,7 @@ public:
|
||||
|
||||
static bool hasRequiredFields(const QJsonObject &json_document);
|
||||
static QJsonObject getParams(const QJsonObject &json_document);
|
||||
static QJsonObject getStatus(const QJsonObject &json_document);
|
||||
static ClientMessage getClientMessageType(const QJsonObject &json_document);
|
||||
static ManagerMessage getManagerMessageType(const QJsonObject &json_document);
|
||||
|
||||
|
||||
@@ -153,6 +153,16 @@ VMManagerServerSocket::jsonReceived(const QJsonObject &json)
|
||||
|
||||
auto message_type = VMManagerProtocol::getClientMessageType(json);
|
||||
switch (message_type) {
|
||||
case VMManagerProtocol::ClientMessage::WinIdMessage:
|
||||
qDebug("WinId message received from client");
|
||||
params_object = VMManagerProtocol::getParams(json);
|
||||
if (!params_object.isEmpty()) {
|
||||
// valid object
|
||||
if(params_object.value("params").type() == QJsonValue::Double) {
|
||||
emit winIdReceived(params_object.value("params").toVariant().toULongLong());
|
||||
}
|
||||
}
|
||||
break;
|
||||
case VMManagerProtocol::ClientMessage::Status:
|
||||
qDebug("Status message received from client");
|
||||
break;
|
||||
|
||||
@@ -75,6 +75,7 @@ signals:
|
||||
void dataReceived();
|
||||
void windowStatusChanged(int status);
|
||||
void runningStatusChanged(VMManagerProtocol::RunningState state);
|
||||
void winIdReceived(WId id);
|
||||
|
||||
|
||||
};
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
* Copyright 2024 cold-brewed
|
||||
*/
|
||||
|
||||
|
||||
#include <QString>
|
||||
#include <QDirIterator>
|
||||
#include <QDebug>
|
||||
@@ -26,10 +27,15 @@
|
||||
#include <QtNetwork>
|
||||
#include <QElapsedTimer>
|
||||
#include <QProgressDialog>
|
||||
#include <QWindow>
|
||||
#include "qt_vmmanager_system.hpp"
|
||||
// #include "qt_vmmanager_details_section.hpp"
|
||||
#include "qt_vmmanager_detailsection.hpp"
|
||||
|
||||
#ifdef Q_OS_WINDOWS
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
|
||||
extern "C" {
|
||||
#include <86box/86box.h>
|
||||
@@ -427,12 +433,18 @@ VMManagerSystem::launchSettings() {
|
||||
|
||||
// If the system is already running, instruct it to show settings
|
||||
if (process->processId() != 0) {
|
||||
#ifdef Q_OS_WINDOWS
|
||||
if (this->id) {
|
||||
SetForegroundWindow((HWND)this->id);
|
||||
}
|
||||
#endif
|
||||
socket_server->serverSendMessage(VMManagerProtocol::ManagerMessage::ShowSettings);
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise, launch the system with the settings parameter
|
||||
setProcessEnvVars();
|
||||
window_obscured = true;
|
||||
QString program = main_binary.filePath();
|
||||
QStringList open_command_args;
|
||||
QStringList args;
|
||||
@@ -776,6 +788,7 @@ VMManagerSystem::startServer() {
|
||||
connect(socket_server, &VMManagerServerSocket::dataReceived, this, &VMManagerSystem::dataReceived);
|
||||
connect(socket_server, &VMManagerServerSocket::windowStatusChanged, this, &VMManagerSystem::windowStatusChangeReceived);
|
||||
connect(socket_server, &VMManagerServerSocket::runningStatusChanged, this, &VMManagerSystem::runningStatusChangeReceived);
|
||||
connect(socket_server, &VMManagerServerSocket::winIdReceived, this, [this] (WId id) { this->id = id; });
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
@@ -846,6 +859,7 @@ VMManagerSystem::processStatusChanged()
|
||||
}
|
||||
} else if (process->state() == QProcess::ProcessState::NotRunning) {
|
||||
process_status = VMManagerSystem::ProcessStatus::Stopped;
|
||||
window_obscured = false;
|
||||
}
|
||||
emit itemDataChanged();
|
||||
emit clientProcessStatusChanged();
|
||||
@@ -892,12 +906,20 @@ VMManagerSystem::runningStatusChangeReceived(VMManagerProtocol::RunningState sta
|
||||
{
|
||||
if(state == VMManagerProtocol::RunningState::Running) {
|
||||
process_status = VMManagerSystem::ProcessStatus::Running;
|
||||
window_obscured = false;
|
||||
windowStatusChanged();
|
||||
} else if(state == VMManagerProtocol::RunningState::Paused) {
|
||||
process_status = VMManagerSystem::ProcessStatus::Paused;
|
||||
window_obscured = false;
|
||||
windowStatusChanged();
|
||||
} else if(state == VMManagerProtocol::RunningState::RunningWaiting) {
|
||||
process_status = VMManagerSystem::ProcessStatus::RunningWaiting;
|
||||
window_obscured = true;
|
||||
windowStatusChanged();
|
||||
} else if(state == VMManagerProtocol::RunningState::PausedWaiting) {
|
||||
process_status = VMManagerSystem::ProcessStatus::PausedWaiting;
|
||||
window_obscured = true;
|
||||
windowStatusChanged();
|
||||
} else {
|
||||
process_status = VMManagerSystem::ProcessStatus::Unknown;
|
||||
}
|
||||
|
||||
@@ -174,6 +174,8 @@ private:
|
||||
// Configuration file settings
|
||||
VMManagerConfig *config_settings;
|
||||
|
||||
WId id;
|
||||
|
||||
bool serverIsRunning;
|
||||
bool startServer();
|
||||
|
||||
|
||||
@@ -1582,19 +1582,19 @@ sb_exec_command(sb_dsp_t *dsp)
|
||||
timer_set_delay_u64(&dsp->output_timer, (uint64_t) trunc(dsp->sblatcho));
|
||||
break;
|
||||
case 0x90: /* High speed 8-bit autoinit DMA output */
|
||||
if ((dsp->sb_type >= SB_DSP_201) && (dsp->sb_type < SB16_DSP_404)) // TODO docs need validated
|
||||
if (dsp->sb_type >= SB_DSP_201) // TODO docs need validated
|
||||
sb_start_dma(dsp, 1, 1, 0, dsp->sb_8_autolen);
|
||||
break;
|
||||
case 0x91: /* High speed 8-bit single cycle DMA output */
|
||||
if ((dsp->sb_type >= SB_DSP_201) && (dsp->sb_type < SB16_DSP_404)) // TODO docs need validated
|
||||
if (dsp->sb_type >= SB_DSP_201) // TODO docs need validated
|
||||
sb_start_dma(dsp, 1, 0, 0, dsp->sb_8_autolen);
|
||||
break;
|
||||
case 0x98: /* High speed 8-bit autoinit DMA input */
|
||||
if ((dsp->sb_type >= SB_DSP_201) && (dsp->sb_type < SB16_DSP_404)) // TODO docs need validated
|
||||
if (dsp->sb_type >= SB_DSP_201) // TODO docs need validated
|
||||
sb_start_dma_i(dsp, 1, 1, 0, dsp->sb_8_autolen);
|
||||
break;
|
||||
case 0x99: /* High speed 8-bit single cycle DMA input */
|
||||
if ((dsp->sb_type >= SB_DSP_201) && (dsp->sb_type < SB16_DSP_404)) // TODO docs need validated
|
||||
if (dsp->sb_type >= SB_DSP_201) // TODO docs need validated
|
||||
sb_start_dma_i(dsp, 1, 0, 0, dsp->sb_8_autolen);
|
||||
break;
|
||||
case 0xA0: /* Set input mode to mono */
|
||||
|
||||
376
src/unix/gamemode/gamemode_client.h
Normal file
376
src/unix/gamemode/gamemode_client.h
Normal file
@@ -0,0 +1,376 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2017-2025, Feral Interactive and the GameMode contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Feral Interactive nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
#ifndef CLIENT_GAMEMODE_H
|
||||
#define CLIENT_GAMEMODE_H
|
||||
/*
|
||||
* GameMode supports the following client functions
|
||||
* Requests are refcounted in the daemon
|
||||
*
|
||||
* int gamemode_request_start() - Request gamemode starts
|
||||
* 0 if the request was sent successfully
|
||||
* -1 if the request failed
|
||||
*
|
||||
* int gamemode_request_end() - Request gamemode ends
|
||||
* 0 if the request was sent successfully
|
||||
* -1 if the request failed
|
||||
*
|
||||
* GAMEMODE_AUTO can be defined to make the above two functions apply during static init and
|
||||
* destruction, as appropriate. In this configuration, errors will be printed to stderr
|
||||
*
|
||||
* int gamemode_query_status() - Query the current status of gamemode
|
||||
* 0 if gamemode is inactive
|
||||
* 1 if gamemode is active
|
||||
* 2 if gamemode is active and this client is registered
|
||||
* -1 if the query failed
|
||||
*
|
||||
* int gamemode_request_start_for(pid_t pid) - Request gamemode starts for another process
|
||||
* 0 if the request was sent successfully
|
||||
* -1 if the request failed
|
||||
* -2 if the request was rejected
|
||||
*
|
||||
* int gamemode_request_end_for(pid_t pid) - Request gamemode ends for another process
|
||||
* 0 if the request was sent successfully
|
||||
* -1 if the request failed
|
||||
* -2 if the request was rejected
|
||||
*
|
||||
* int gamemode_query_status_for(pid_t pid) - Query status of gamemode for another process
|
||||
* 0 if gamemode is inactive
|
||||
* 1 if gamemode is active
|
||||
* 2 if gamemode is active and this client is registered
|
||||
* -1 if the query failed
|
||||
*
|
||||
* const char* gamemode_error_string() - Get an error string
|
||||
* returns a string describing any of the above errors
|
||||
*
|
||||
* Note: All the above requests can be blocking - dbus requests can and will block while the daemon
|
||||
* handles the request. It is not recommended to make these calls in performance critical code
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
static char internal_gamemode_client_error_string[512] = { 0 };
|
||||
|
||||
/**
|
||||
* Load libgamemode dynamically to dislodge us from most dependencies.
|
||||
* This allows clients to link and/or use this regardless of runtime.
|
||||
* See SDL2 for an example of the reasoning behind this in terms of
|
||||
* dynamic versioning as well.
|
||||
*/
|
||||
static volatile int internal_libgamemode_loaded = 1;
|
||||
|
||||
/* Typedefs for the functions to load */
|
||||
typedef int (*api_call_return_int)(void);
|
||||
typedef const char *(*api_call_return_cstring)(void);
|
||||
typedef int (*api_call_pid_return_int)(pid_t);
|
||||
|
||||
/* Storage for functors */
|
||||
static api_call_return_int REAL_internal_gamemode_request_start = NULL;
|
||||
static api_call_return_int REAL_internal_gamemode_request_end = NULL;
|
||||
static api_call_return_int REAL_internal_gamemode_query_status = NULL;
|
||||
static api_call_return_cstring REAL_internal_gamemode_error_string = NULL;
|
||||
static api_call_pid_return_int REAL_internal_gamemode_request_start_for = NULL;
|
||||
static api_call_pid_return_int REAL_internal_gamemode_request_end_for = NULL;
|
||||
static api_call_pid_return_int REAL_internal_gamemode_query_status_for = NULL;
|
||||
|
||||
/**
|
||||
* Internal helper to perform the symbol binding safely.
|
||||
*
|
||||
* Returns 0 on success and -1 on failure
|
||||
*/
|
||||
__attribute__((always_inline)) static inline int internal_bind_libgamemode_symbol(
|
||||
void *handle, const char *name, void **out_func, size_t func_size, bool required)
|
||||
{
|
||||
void *symbol_lookup = NULL;
|
||||
char *dl_error = NULL;
|
||||
|
||||
/* Safely look up the symbol */
|
||||
symbol_lookup = dlsym(handle, name);
|
||||
dl_error = dlerror();
|
||||
if (required && (dl_error || !symbol_lookup)) {
|
||||
snprintf(internal_gamemode_client_error_string,
|
||||
sizeof(internal_gamemode_client_error_string),
|
||||
"dlsym failed - %s",
|
||||
dl_error);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Have the symbol correctly, copy it to make it usable */
|
||||
memcpy(out_func, &symbol_lookup, func_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads libgamemode and needed functions
|
||||
*
|
||||
* Returns 0 on success and -1 on failure
|
||||
*/
|
||||
__attribute__((always_inline)) static inline int internal_load_libgamemode(void)
|
||||
{
|
||||
/* We start at 1, 0 is a success and -1 is a fail */
|
||||
if (internal_libgamemode_loaded != 1) {
|
||||
return internal_libgamemode_loaded;
|
||||
}
|
||||
|
||||
/* Anonymous struct type to define our bindings */
|
||||
struct binding {
|
||||
const char *name;
|
||||
void **functor;
|
||||
size_t func_size;
|
||||
bool required;
|
||||
} bindings[] = {
|
||||
{ "real_gamemode_request_start",
|
||||
(void **)&REAL_internal_gamemode_request_start,
|
||||
sizeof(REAL_internal_gamemode_request_start),
|
||||
true },
|
||||
{ "real_gamemode_request_end",
|
||||
(void **)&REAL_internal_gamemode_request_end,
|
||||
sizeof(REAL_internal_gamemode_request_end),
|
||||
true },
|
||||
{ "real_gamemode_query_status",
|
||||
(void **)&REAL_internal_gamemode_query_status,
|
||||
sizeof(REAL_internal_gamemode_query_status),
|
||||
false },
|
||||
{ "real_gamemode_error_string",
|
||||
(void **)&REAL_internal_gamemode_error_string,
|
||||
sizeof(REAL_internal_gamemode_error_string),
|
||||
true },
|
||||
{ "real_gamemode_request_start_for",
|
||||
(void **)&REAL_internal_gamemode_request_start_for,
|
||||
sizeof(REAL_internal_gamemode_request_start_for),
|
||||
false },
|
||||
{ "real_gamemode_request_end_for",
|
||||
(void **)&REAL_internal_gamemode_request_end_for,
|
||||
sizeof(REAL_internal_gamemode_request_end_for),
|
||||
false },
|
||||
{ "real_gamemode_query_status_for",
|
||||
(void **)&REAL_internal_gamemode_query_status_for,
|
||||
sizeof(REAL_internal_gamemode_query_status_for),
|
||||
false },
|
||||
};
|
||||
|
||||
void *libgamemode = NULL;
|
||||
|
||||
/* Try and load libgamemode */
|
||||
libgamemode = dlopen("libgamemode.so.0", RTLD_NOW);
|
||||
if (!libgamemode) {
|
||||
/* Attempt to load unversioned library for compatibility with older
|
||||
* versions (as of writing, there are no ABI changes between the two -
|
||||
* this may need to change if ever ABI-breaking changes are made) */
|
||||
libgamemode = dlopen("libgamemode.so", RTLD_NOW);
|
||||
if (!libgamemode) {
|
||||
snprintf(internal_gamemode_client_error_string,
|
||||
sizeof(internal_gamemode_client_error_string),
|
||||
"dlopen failed - %s",
|
||||
dlerror());
|
||||
internal_libgamemode_loaded = -1;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Attempt to bind all symbols */
|
||||
for (size_t i = 0; i < sizeof(bindings) / sizeof(bindings[0]); i++) {
|
||||
struct binding *binder = &bindings[i];
|
||||
|
||||
if (internal_bind_libgamemode_symbol(libgamemode,
|
||||
binder->name,
|
||||
binder->functor,
|
||||
binder->func_size,
|
||||
binder->required)) {
|
||||
internal_libgamemode_loaded = -1;
|
||||
return -1;
|
||||
};
|
||||
}
|
||||
|
||||
/* Success */
|
||||
internal_libgamemode_loaded = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirect to the real libgamemode
|
||||
*/
|
||||
__attribute__((always_inline)) static inline const char *gamemode_error_string(void)
|
||||
{
|
||||
/* If we fail to load the system gamemode, or we have an error string already, return our error
|
||||
* string instead of diverting to the system version */
|
||||
if (internal_load_libgamemode() < 0 || internal_gamemode_client_error_string[0] != '\0') {
|
||||
return internal_gamemode_client_error_string;
|
||||
}
|
||||
|
||||
/* Assert for static analyser that the function is not NULL */
|
||||
assert(REAL_internal_gamemode_error_string != NULL);
|
||||
|
||||
return REAL_internal_gamemode_error_string();
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirect to the real libgamemode
|
||||
* Allow automatically requesting game mode
|
||||
* Also prints errors as they happen.
|
||||
*/
|
||||
#ifdef GAMEMODE_AUTO
|
||||
__attribute__((constructor))
|
||||
#else
|
||||
__attribute__((always_inline)) static inline
|
||||
#endif
|
||||
int gamemode_request_start(void)
|
||||
{
|
||||
/* Need to load gamemode */
|
||||
if (internal_load_libgamemode() < 0) {
|
||||
#ifdef GAMEMODE_AUTO
|
||||
fprintf(stderr, "gamemodeauto: %s\n", gamemode_error_string());
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Assert for static analyser that the function is not NULL */
|
||||
assert(REAL_internal_gamemode_request_start != NULL);
|
||||
|
||||
if (REAL_internal_gamemode_request_start() < 0) {
|
||||
#ifdef GAMEMODE_AUTO
|
||||
fprintf(stderr, "gamemodeauto: %s\n", gamemode_error_string());
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Redirect to the real libgamemode */
|
||||
#ifdef GAMEMODE_AUTO
|
||||
__attribute__((destructor))
|
||||
#else
|
||||
__attribute__((always_inline)) static inline
|
||||
#endif
|
||||
int gamemode_request_end(void)
|
||||
{
|
||||
/* Need to load gamemode */
|
||||
if (internal_load_libgamemode() < 0) {
|
||||
#ifdef GAMEMODE_AUTO
|
||||
fprintf(stderr, "gamemodeauto: %s\n", gamemode_error_string());
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Assert for static analyser that the function is not NULL */
|
||||
assert(REAL_internal_gamemode_request_end != NULL);
|
||||
|
||||
if (REAL_internal_gamemode_request_end() < 0) {
|
||||
#ifdef GAMEMODE_AUTO
|
||||
fprintf(stderr, "gamemodeauto: %s\n", gamemode_error_string());
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Redirect to the real libgamemode */
|
||||
__attribute__((always_inline)) static inline int gamemode_query_status(void)
|
||||
{
|
||||
/* Need to load gamemode */
|
||||
if (internal_load_libgamemode() < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (REAL_internal_gamemode_query_status == NULL) {
|
||||
snprintf(internal_gamemode_client_error_string,
|
||||
sizeof(internal_gamemode_client_error_string),
|
||||
"gamemode_query_status missing (older host?)");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return REAL_internal_gamemode_query_status();
|
||||
}
|
||||
|
||||
/* Redirect to the real libgamemode */
|
||||
__attribute__((always_inline)) static inline int gamemode_request_start_for(pid_t pid)
|
||||
{
|
||||
/* Need to load gamemode */
|
||||
if (internal_load_libgamemode() < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (REAL_internal_gamemode_request_start_for == NULL) {
|
||||
snprintf(internal_gamemode_client_error_string,
|
||||
sizeof(internal_gamemode_client_error_string),
|
||||
"gamemode_request_start_for missing (older host?)");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return REAL_internal_gamemode_request_start_for(pid);
|
||||
}
|
||||
|
||||
/* Redirect to the real libgamemode */
|
||||
__attribute__((always_inline)) static inline int gamemode_request_end_for(pid_t pid)
|
||||
{
|
||||
/* Need to load gamemode */
|
||||
if (internal_load_libgamemode() < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (REAL_internal_gamemode_request_end_for == NULL) {
|
||||
snprintf(internal_gamemode_client_error_string,
|
||||
sizeof(internal_gamemode_client_error_string),
|
||||
"gamemode_request_end_for missing (older host?)");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return REAL_internal_gamemode_request_end_for(pid);
|
||||
}
|
||||
|
||||
/* Redirect to the real libgamemode */
|
||||
__attribute__((always_inline)) static inline int gamemode_query_status_for(pid_t pid)
|
||||
{
|
||||
/* Need to load gamemode */
|
||||
if (internal_load_libgamemode() < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (REAL_internal_gamemode_query_status_for == NULL) {
|
||||
snprintf(internal_gamemode_client_error_string,
|
||||
sizeof(internal_gamemode_client_error_string),
|
||||
"gamemode_query_status_for missing (older host?)");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return REAL_internal_gamemode_query_status_for(pid);
|
||||
}
|
||||
|
||||
#endif // CLIENT_GAMEMODE_H
|
||||
@@ -576,7 +576,7 @@ main_thread(UNUSED(void *param))
|
||||
old_time = new_time;
|
||||
if (drawits > 0 && !dopause) {
|
||||
/* Yes, so do one frame now. */
|
||||
drawits -= 10;
|
||||
drawits -= force_10ms ? 10 : 1;
|
||||
if (drawits > 50)
|
||||
drawits = 0;
|
||||
|
||||
@@ -584,7 +584,7 @@ main_thread(UNUSED(void *param))
|
||||
pc_run();
|
||||
|
||||
/* Every 200 frames we save the machine status. */
|
||||
if (++frames >= 200 && nvr_dosave) {
|
||||
if (++frames >= (force_10ms ? 200 : 2000) && nvr_dosave) {
|
||||
nvr_save();
|
||||
nvr_dosave = 0;
|
||||
frames = 0;
|
||||
|
||||
@@ -33,6 +33,14 @@
|
||||
#include <86box/vid_svga.h>
|
||||
#include <86box/vid_svga_render.h>
|
||||
|
||||
#define VAR_BYTE_MODE (0 << 0)
|
||||
#define VAR_WORD_MODE_MA13 (1 << 0)
|
||||
#define VAR_WORD_MODE_MA15 (2 << 0)
|
||||
#define VAR_DWORD_MODE (3 << 0)
|
||||
#define VAR_MODE_MASK (3 << 0)
|
||||
#define VAR_ROW0_MA13 (1 << 2)
|
||||
#define VAR_ROW1_MA14 (1 << 3)
|
||||
|
||||
typedef struct paradise_t {
|
||||
svga_t svga;
|
||||
|
||||
@@ -212,6 +220,20 @@ paradise_out(uint16_t addr, uint8_t val, void *priv)
|
||||
else
|
||||
svga->gdcreg[0x0b] |= 0x40;
|
||||
|
||||
if (svga->crtc[0x2f] & 0x02)
|
||||
svga->decode_mask = 0x3ffff;
|
||||
else switch (svga->gdcreg[0x0b] & 0xc0) {
|
||||
case 0x00: case 0x40:
|
||||
svga->decode_mask = 0x3ffff;
|
||||
break;
|
||||
case 0x80:
|
||||
svga->decode_mask = 0x7ffff;
|
||||
break;
|
||||
case 0xc0:
|
||||
svga->decode_mask = 0xfffff;
|
||||
break;
|
||||
}
|
||||
|
||||
paradise_remap(paradise);
|
||||
return;
|
||||
case 0x0e:
|
||||
@@ -243,6 +265,21 @@ paradise_out(uint16_t addr, uint8_t val, void *priv)
|
||||
|
||||
if (old != val) {
|
||||
if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) {
|
||||
if (svga->crtcreg == 0x2f) {
|
||||
if (svga->crtc[0x2f] & 0x02)
|
||||
svga->decode_mask = 0x3ffff;
|
||||
else switch (svga->gdcreg[0x0b] & 0xc0) {
|
||||
case 0x00: case 0x40:
|
||||
svga->decode_mask = 0x3ffff;
|
||||
break;
|
||||
case 0x80:
|
||||
svga->decode_mask = 0x7ffff;
|
||||
break;
|
||||
case 0xc0:
|
||||
svga->decode_mask = 0xfffff;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) {
|
||||
svga->fullchange = 3;
|
||||
svga->memaddr_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5);
|
||||
@@ -267,30 +304,92 @@ paradise_remap(paradise_t *paradise)
|
||||
svga_t *svga = ¶dise->svga;
|
||||
|
||||
if (svga->seqregs[0x11] & 0x80) {
|
||||
paradise->read_bank[0] = paradise->read_bank[2] = svga->gdcreg[9] << 12;
|
||||
paradise->read_bank[1] = paradise->read_bank[3] = (svga->gdcreg[9] << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000);
|
||||
paradise->write_bank[0] = paradise->write_bank[2] = svga->gdcreg[0x0a] << 12;
|
||||
paradise->write_bank[1] = paradise->write_bank[3] = (svga->gdcreg[0x0a] << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000);
|
||||
} else if (svga->gdcreg[0x0b] & 0x08) {
|
||||
if (svga->gdcreg[6] & 0x0c) {
|
||||
paradise->read_bank[0] = paradise->read_bank[2] = svga->gdcreg[0x0a] << 12;
|
||||
paradise->write_bank[0] = paradise->write_bank[2] = svga->gdcreg[0x0a] << 12;
|
||||
paradise->read_bank[1] = paradise->read_bank[3] = (svga->gdcreg[9] << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000);
|
||||
paradise->write_bank[1] = paradise->write_bank[3] = (svga->gdcreg[9] << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000);
|
||||
} else {
|
||||
paradise->read_bank[0] = paradise->write_bank[0] = svga->gdcreg[0x0a] << 12;
|
||||
paradise->read_bank[1] = paradise->write_bank[1] = (svga->gdcreg[0xa] << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000);
|
||||
paradise->read_bank[2] = paradise->write_bank[2] = svga->gdcreg[9] << 12;
|
||||
paradise->read_bank[3] = paradise->write_bank[3] = (svga->gdcreg[9] << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000);
|
||||
}
|
||||
} else {
|
||||
paradise->read_bank[0] = paradise->read_bank[2] = svga->gdcreg[9] << 12;
|
||||
paradise->read_bank[1] = paradise->read_bank[3] = (svga->gdcreg[9] << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000);
|
||||
paradise->write_bank[0] = paradise->write_bank[2] = svga->gdcreg[9] << 12;
|
||||
paradise->write_bank[1] = paradise->write_bank[3] = (svga->gdcreg[9] << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000);
|
||||
}
|
||||
paradise->read_bank[0] = svga->gdcreg[9] << 12;
|
||||
paradise->read_bank[1] = paradise->read_bank[0] + 0x8000;
|
||||
|
||||
/*There are separate drivers for 1M and 512K/256K versions of the PVGA chips.*/
|
||||
paradise->write_bank[0] = svga->gdcreg[0x0a] << 12;
|
||||
paradise->write_bank[1] = paradise->write_bank[0] + 0x8000;
|
||||
|
||||
if ((svga->gdcreg[6] & 0x0c) == 0x00) {
|
||||
paradise->read_bank[2] = paradise->read_bank[1] + 0x8000;
|
||||
paradise->read_bank[3] = paradise->read_bank[2] + 0x8000;
|
||||
|
||||
paradise->write_bank[2] = paradise->write_bank[1] + 0x8000;
|
||||
paradise->write_bank[3] = paradise->write_bank[2] + 0x8000;
|
||||
} else {
|
||||
if (svga->gdcreg[6] & 0x08) {
|
||||
paradise->read_bank[1] = paradise->read_bank[0];
|
||||
|
||||
paradise->write_bank[1] = paradise->write_bank[0];
|
||||
}
|
||||
|
||||
paradise->read_bank[2] = paradise->read_bank[0];
|
||||
paradise->read_bank[3] = paradise->read_bank[1];
|
||||
|
||||
paradise->write_bank[2] = paradise->write_bank[0];
|
||||
paradise->write_bank[3] = paradise->write_bank[1];
|
||||
}
|
||||
} else if (svga->gdcreg[0x0b] & 0x08) {
|
||||
if ((svga->gdcreg[6] & 0x0c) == 0x00) {
|
||||
paradise->read_bank[0] = svga->gdcreg[0x0a] << 12;
|
||||
paradise->read_bank[1] = paradise->read_bank[0] + 0x8000;
|
||||
paradise->read_bank[2] = svga->gdcreg[9] << 12;
|
||||
paradise->read_bank[3] = paradise->read_bank[2] + 0x8000;
|
||||
|
||||
paradise->write_bank[0] = svga->gdcreg[0x0a] << 12;
|
||||
paradise->write_bank[1] = paradise->write_bank[0] + 0x8000;
|
||||
paradise->write_bank[2] = svga->gdcreg[9] << 12;
|
||||
paradise->write_bank[3] = paradise->write_bank[2] + 0x8000;
|
||||
} else if ((svga->gdcreg[6] & 0x0c) == 0x04) {
|
||||
paradise->read_bank[0] = svga->gdcreg[0x0a] << 12;
|
||||
paradise->read_bank[1] = svga->gdcreg[9] << 12;
|
||||
paradise->read_bank[2] = paradise->read_bank[0];
|
||||
paradise->read_bank[3] = paradise->read_bank[1];
|
||||
|
||||
paradise->write_bank[0] = svga->gdcreg[0x0a] << 12;
|
||||
paradise->write_bank[1] = svga->gdcreg[9] << 12;
|
||||
paradise->write_bank[2] = paradise->write_bank[0];
|
||||
paradise->write_bank[3] = paradise->write_bank[1];
|
||||
} else {
|
||||
paradise->read_bank[0] = svga->gdcreg[0x0a] << 12;
|
||||
paradise->read_bank[1] = paradise->read_bank[0];
|
||||
paradise->read_bank[2] = paradise->read_bank[0];
|
||||
paradise->read_bank[3] = paradise->read_bank[0];
|
||||
|
||||
paradise->write_bank[0] = svga->gdcreg[0x0a] << 12;
|
||||
paradise->write_bank[1] = paradise->write_bank[0];
|
||||
paradise->write_bank[2] = paradise->write_bank[0];
|
||||
paradise->write_bank[3] = paradise->write_bank[0];
|
||||
}
|
||||
} else {
|
||||
paradise->read_bank[0] = svga->gdcreg[9] << 12;
|
||||
paradise->read_bank[1] = paradise->read_bank[0] + 0x8000;
|
||||
|
||||
paradise->write_bank[0] = svga->gdcreg[9] << 12;
|
||||
paradise->write_bank[1] = paradise->write_bank[0] + 0x8000;
|
||||
|
||||
if ((svga->gdcreg[6] & 0x0c) == 0x00) {
|
||||
paradise->read_bank[2] = paradise->read_bank[1] + 0x8000;
|
||||
paradise->read_bank[3] = paradise->read_bank[2] + 0x8000;
|
||||
|
||||
paradise->write_bank[2] = paradise->write_bank[1] + 0x8000;
|
||||
paradise->write_bank[3] = paradise->write_bank[2] + 0x8000;
|
||||
} else {
|
||||
if (svga->gdcreg[6] & 0x08) {
|
||||
paradise->read_bank[1] = paradise->read_bank[0];
|
||||
|
||||
paradise->write_bank[1] = paradise->write_bank[0];
|
||||
}
|
||||
|
||||
paradise->read_bank[2] = paradise->read_bank[0];
|
||||
paradise->read_bank[3] = paradise->read_bank[1];
|
||||
|
||||
paradise->write_bank[2] = paradise->write_bank[0];
|
||||
paradise->write_bank[3] = paradise->write_bank[1];
|
||||
}
|
||||
}
|
||||
|
||||
/* There are separate drivers for 1M and 512K/256K versions of the PVGA chips. */
|
||||
if ((svga->gdcreg[0x0b] & 0xc0) < 0xc0) {
|
||||
paradise->read_bank[1] &= 0x7ffff;
|
||||
paradise->write_bank[1] &= 0x7ffff;
|
||||
@@ -300,6 +399,85 @@ paradise_remap(paradise_t *paradise)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
paradise_render_4bpp_word_highres(svga_t *svga)
|
||||
{
|
||||
int x;
|
||||
int oddeven;
|
||||
uint32_t addr;
|
||||
uint32_t *p;
|
||||
uint8_t edat[4];
|
||||
uint8_t dat;
|
||||
uint32_t changed_addr;
|
||||
|
||||
if ((svga->displine + svga->y_add) < 0)
|
||||
return;
|
||||
|
||||
changed_addr = ((svga->memaddr & 0x3fffc) << 1);
|
||||
|
||||
if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) {
|
||||
p = &svga->monitor->target_buffer->line[svga->displine + svga->y_add][svga->x_add];
|
||||
|
||||
if (svga->firstline_draw == 2000)
|
||||
svga->firstline_draw = svga->displine;
|
||||
svga->lastline_draw = svga->displine;
|
||||
|
||||
for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) {
|
||||
addr = ((svga->memaddr & 0x3fffc) << 1);
|
||||
oddeven = 0;
|
||||
|
||||
oddeven = (svga->memaddr & 2) ? 1 : 0;
|
||||
*(uint32_t *) (&edat[0]) = *(uint32_t *) (&svga->vram[addr | oddeven]) & 0x00ff00ff;
|
||||
svga->memaddr = (svga->memaddr + 2) & svga->vram_mask;
|
||||
|
||||
dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2);
|
||||
p[0] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
|
||||
p[1] = svga->pallook[svga->egapal[dat & svga->plane_mask]];
|
||||
dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] |
|
||||
(edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2);
|
||||
p[2] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
|
||||
p[3] = svga->pallook[svga->egapal[dat & svga->plane_mask]];
|
||||
dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] |
|
||||
(edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2);
|
||||
p[4] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
|
||||
p[5] = svga->pallook[svga->egapal[dat & svga->plane_mask]];
|
||||
dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2);
|
||||
p[6] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
|
||||
p[7] = svga->pallook[svga->egapal[dat & svga->plane_mask]];
|
||||
|
||||
p += 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
paradise_mode_is_word(svga_t *svga)
|
||||
{
|
||||
int func_nr;
|
||||
|
||||
if (svga->fb_only)
|
||||
func_nr = 0;
|
||||
else {
|
||||
if (svga->force_dword_mode)
|
||||
func_nr = VAR_DWORD_MODE;
|
||||
else if (svga->crtc[0x14] & 0x40)
|
||||
func_nr = svga->packed_chain4 ? VAR_BYTE_MODE : VAR_DWORD_MODE;
|
||||
else if (svga->crtc[0x17] & 0x40)
|
||||
func_nr = VAR_BYTE_MODE;
|
||||
else if (svga->crtc[0x17] & 0x20)
|
||||
func_nr = VAR_WORD_MODE_MA15;
|
||||
else
|
||||
func_nr = VAR_WORD_MODE_MA13;
|
||||
|
||||
if (!(svga->crtc[0x17] & 0x01))
|
||||
func_nr |= VAR_ROW0_MA13;
|
||||
if (!(svga->crtc[0x17] & 0x02))
|
||||
func_nr |= VAR_ROW1_MA14;
|
||||
}
|
||||
|
||||
return (func_nr == 2);
|
||||
}
|
||||
|
||||
void
|
||||
paradise_recalctimings(svga_t *svga)
|
||||
{
|
||||
@@ -318,17 +496,30 @@ paradise_recalctimings(svga_t *svga)
|
||||
svga->vblankstart |= 0x400;
|
||||
if (svga->crtc[0x3e] & 0x10)
|
||||
svga->split |= 0x400;
|
||||
|
||||
svga->interlace = !!(svga->crtc[0x2d] & 0x20);
|
||||
}
|
||||
|
||||
if (paradise->type >= WD90C11)
|
||||
svga->interlace = !!(svga->crtc[0x2d] & 0x20);
|
||||
|
||||
if (paradise->type < WD90C30) {
|
||||
if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) {
|
||||
if ((svga->bpp >= 8) && !svga->lowres) {
|
||||
svga->render = svga_render_8bpp_highres;
|
||||
svga->vram_display_mask = (svga->crtc[0x2f] & 0x02) ? 0x3ffff : paradise->vram_mask;
|
||||
if (paradise->type != WD90C11)
|
||||
svga->vram_display_mask = (svga->crtc[0x2f] & 0x02) ? 0x3ffff : paradise->vram_mask;
|
||||
}
|
||||
}
|
||||
if (paradise->type == WD90C11) switch (svga->crtc[0x2f] & 0x60) {
|
||||
case 0x60: case 0x40:
|
||||
svga->vram_display_mask = 0x3ffff;
|
||||
break;
|
||||
case 0x20:
|
||||
svga->vram_display_mask = 0x7ffff;
|
||||
break;
|
||||
case 0x00:
|
||||
svga->vram_display_mask = 0xfffff;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) {
|
||||
if ((svga->bpp >= 8) && !svga->lowres) {
|
||||
@@ -352,6 +543,52 @@ paradise_recalctimings(svga_t *svga)
|
||||
a windowed DOS box in Win3.x*/
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Yes, this is basically hack but I'm going to look at a proper rewrite in
|
||||
86Box 6.0.
|
||||
*/
|
||||
if ((paradise->type == WD90C11) && (svga->hdisp == 1024) &&
|
||||
(svga->render == svga_render_4bpp_highres) && paradise_mode_is_word(svga))
|
||||
svga->render = paradise_render_4bpp_word_highres;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
paradise_decode_addr(paradise_t *paradise, uint32_t addr, int write)
|
||||
{
|
||||
svga_t *svga = ¶dise->svga;
|
||||
int memory_map_mode = (svga->gdcreg[6] >> 2) & 3;
|
||||
|
||||
addr &= 0x1ffff;
|
||||
|
||||
switch (memory_map_mode) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
if (addr >= 0x10000)
|
||||
return 0xffffffff;
|
||||
break;
|
||||
case 2:
|
||||
addr -= 0x10000;
|
||||
if (addr >= 0x8000)
|
||||
return 0xffffffff;
|
||||
break;
|
||||
default:
|
||||
case 3:
|
||||
addr -= 0x18000;
|
||||
if (addr >= 0x8000)
|
||||
return 0xffffffff;
|
||||
break;
|
||||
}
|
||||
|
||||
if (memory_map_mode <= 1) {
|
||||
if (write)
|
||||
addr = (addr & 0x7fff) + paradise->write_bank[(addr >> 15) & 3];
|
||||
else
|
||||
addr = (addr & 0x7fff) + paradise->read_bank[(addr >> 15) & 3];
|
||||
}
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -362,7 +599,9 @@ paradise_write(uint32_t addr, uint8_t val, void *priv)
|
||||
uint32_t prev_addr;
|
||||
uint32_t prev_addr2;
|
||||
|
||||
addr = (addr & 0x7fff) + paradise->write_bank[(addr >> 15) & 3];
|
||||
addr = paradise_decode_addr(paradise, addr, 1);
|
||||
if (addr == 0xffffffff)
|
||||
return;
|
||||
|
||||
/*Could be done in a better way but it works.*/
|
||||
if (!svga->lowres || (svga->attrregs[0x10] & 0x40)) {
|
||||
@@ -395,7 +634,9 @@ paradise_writew(uint32_t addr, uint16_t val, void *priv)
|
||||
uint32_t prev_addr;
|
||||
uint32_t prev_addr2;
|
||||
|
||||
addr = (addr & 0x7fff) + paradise->write_bank[(addr >> 15) & 3];
|
||||
addr = paradise_decode_addr(paradise, addr, 1);
|
||||
if (addr == 0xffffffff)
|
||||
return;
|
||||
|
||||
/*Could be done in a better way but it works.*/
|
||||
if (!svga->lowres || (svga->attrregs[0x10] & 0x40)) {
|
||||
@@ -428,7 +669,9 @@ paradise_read(uint32_t addr, void *priv)
|
||||
uint32_t prev_addr;
|
||||
uint32_t prev_addr2;
|
||||
|
||||
addr = (addr & 0x7fff) + paradise->read_bank[(addr >> 15) & 3];
|
||||
addr = paradise_decode_addr(paradise, addr, 1);
|
||||
if (addr == 0xffffffff)
|
||||
return 0xff;
|
||||
|
||||
/*Could be done in a better way but it works.*/
|
||||
if (!svga->lowres || (svga->attrregs[0x10] & 0x40)) {
|
||||
@@ -461,7 +704,9 @@ paradise_readw(uint32_t addr, void *priv)
|
||||
uint32_t prev_addr;
|
||||
uint32_t prev_addr2;
|
||||
|
||||
addr = (addr & 0x7fff) + paradise->read_bank[(addr >> 15) & 3];
|
||||
addr = paradise_decode_addr(paradise, addr, 1);
|
||||
if (addr == 0xffffffff)
|
||||
return 0xffff;
|
||||
|
||||
/*Could be done in a better way but it works.*/
|
||||
if (!svga->lowres || (svga->attrregs[0x10] & 0x40)) {
|
||||
|
||||
@@ -1262,11 +1262,6 @@ svga_do_render(svga_t *svga)
|
||||
if (!svga->override) {
|
||||
svga->render_line_offset = svga->start_retrace_latch - svga->crtc[0x4];
|
||||
svga->render(svga);
|
||||
|
||||
svga->x_add = svga->left_overscan;
|
||||
svga_render_overscan_left(svga);
|
||||
svga_render_overscan_right(svga);
|
||||
svga->x_add = svga->left_overscan - svga->scrollcache;
|
||||
}
|
||||
|
||||
if (svga->overlay_on) {
|
||||
@@ -1293,6 +1288,13 @@ svga_do_render(svga_t *svga)
|
||||
if (svga->hwcursor_on && svga->interlace)
|
||||
svga->hwcursor_on--;
|
||||
}
|
||||
|
||||
if (!svga->override) {
|
||||
svga->x_add = svga->left_overscan;
|
||||
svga_render_overscan_left(svga);
|
||||
svga_render_overscan_right(svga);
|
||||
svga->x_add = svga->left_overscan - svga->scrollcache;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
@@ -121,6 +122,8 @@ typedef struct banshee_t {
|
||||
uint32_t vidProcCfg;
|
||||
uint32_t vidScreenSize;
|
||||
uint32_t vidSerialParallelPort;
|
||||
uint32_t vidChromaKeyMin;
|
||||
uint32_t vidChromaKeyMax;
|
||||
|
||||
uint32_t agpReqSize;
|
||||
uint32_t agpHostAddressHigh;
|
||||
@@ -153,6 +156,8 @@ typedef struct banshee_t {
|
||||
uint8_t pci_slot;
|
||||
uint8_t irq_state;
|
||||
|
||||
bool chroma_key_enabled;
|
||||
|
||||
void *i2c, *i2c_ddc, *ddc;
|
||||
} banshee_t;
|
||||
|
||||
@@ -186,6 +191,8 @@ enum {
|
||||
Video_hwCurC0 = 0x68,
|
||||
Video_hwCurC1 = 0x6c,
|
||||
Video_vidSerialParallelPort = 0x78,
|
||||
Video_vidChromaKeyMin = 0x8c,
|
||||
Video_vidChromaKeyMax = 0x90,
|
||||
Video_vidScreenSize = 0x98,
|
||||
Video_vidOverlayStartCoords = 0x9c,
|
||||
Video_vidOverlayEndScreenCoords = 0xa0,
|
||||
@@ -946,6 +953,14 @@ banshee_ext_outl(uint16_t addr, uint32_t val, void *priv)
|
||||
i2c_gpio_set(banshee->i2c, !!(val & VIDSERIAL_I2C_SCK_W), !!(val & VIDSERIAL_I2C_SDA_W));
|
||||
break;
|
||||
|
||||
case Video_vidChromaKeyMin:
|
||||
banshee->vidChromaKeyMin = val;
|
||||
break;
|
||||
|
||||
case Video_vidChromaKeyMax:
|
||||
banshee->vidChromaKeyMax = val;
|
||||
break;
|
||||
|
||||
case Video_vidScreenSize:
|
||||
banshee->vidScreenSize = val;
|
||||
voodoo->h_disp = (val & 0xfff) + 1;
|
||||
@@ -1253,6 +1268,12 @@ banshee_ext_inl(uint16_t addr, void *priv)
|
||||
#endif
|
||||
break;
|
||||
|
||||
case Video_vidChromaKeyMin:
|
||||
ret = banshee->vidChromaKeyMin;
|
||||
break;
|
||||
case Video_vidChromaKeyMax:
|
||||
ret = banshee->vidChromaKeyMax;
|
||||
break;
|
||||
case Video_vidScreenSize:
|
||||
ret = banshee->vidScreenSize;
|
||||
break;
|
||||
@@ -2634,12 +2655,97 @@ voodoo_generate_vb_filters(voodoo_t *voodoo, int fcr, int fcg)
|
||||
}
|
||||
}
|
||||
|
||||
/* 1 = render overlay, 0 = render desktop */
|
||||
static bool
|
||||
banshee_chroma_key(banshee_t* banshee, uint32_t x, uint32_t y)
|
||||
{
|
||||
uint32_t src_addr_desktop = banshee->desktop_addr + y * (banshee->vidDesktopOverlayStride & 0x3fff);
|
||||
bool res = true;
|
||||
uint8_t chromaKeyMaxIndex = banshee->vidChromaKeyMax & 0xff;
|
||||
uint8_t chromaKeyMinIndex = banshee->vidChromaKeyMin & 0xff;
|
||||
uint32_t desktop_pixel = 0;
|
||||
uint8_t desktop_r = 0;
|
||||
uint8_t desktop_g = 0;
|
||||
uint8_t desktop_b = 0;
|
||||
uint32_t prev_desktop_y = banshee->desktop_y - 1;
|
||||
|
||||
if (!banshee->chroma_key_enabled)
|
||||
return true;
|
||||
|
||||
if (y > 2048)
|
||||
return true;
|
||||
|
||||
if (!(banshee->vidProcCfg & (1 << 5))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (VIDPROCCFG_DESKTOP_PIX_FORMAT) {
|
||||
case PIX_FORMAT_8:
|
||||
{
|
||||
desktop_pixel = banshee->svga.vram[src_addr_desktop + x];
|
||||
res = (desktop_pixel & 0xFF) >= chromaKeyMinIndex && (desktop_pixel & 0xFF) <= chromaKeyMaxIndex;
|
||||
break;
|
||||
}
|
||||
case PIX_FORMAT_RGB565:
|
||||
{
|
||||
if (banshee->vidProcCfg & VIDPROCCFG_DESKTOP_TILE) {
|
||||
uint32_t addr = 0;
|
||||
if (prev_desktop_y & 0x80000000)
|
||||
return false;
|
||||
if (banshee->vidProcCfg & VIDPROCCFG_HALF_MODE)
|
||||
addr = banshee->desktop_addr + ((prev_desktop_y >> 1) & 31) * 128 + ((prev_desktop_y >> 6) * banshee->desktop_stride_tiled);
|
||||
else
|
||||
addr = banshee->desktop_addr + (prev_desktop_y & 31) * 128 + ((prev_desktop_y >> 5) * banshee->desktop_stride_tiled);
|
||||
|
||||
addr += 128 * 32 * (x >> 6);
|
||||
addr += (x & 63) * 2;
|
||||
desktop_pixel = *(uint16_t*)&banshee->svga.vram[addr & banshee->svga.vram_mask];
|
||||
} else {
|
||||
desktop_pixel = *(uint16_t*)&banshee->svga.vram[(src_addr_desktop + x * 2) & banshee->svga.vram_mask];
|
||||
}
|
||||
|
||||
desktop_r = (desktop_pixel & 0x1f);
|
||||
desktop_g = (desktop_pixel & 0x7e0) >> 5;
|
||||
desktop_b = (desktop_pixel & 0xf800) >> 11;
|
||||
|
||||
res = (desktop_r >= ((banshee->vidChromaKeyMin >> 11) & 0x1F) && desktop_r <= ((banshee->vidChromaKeyMax >> 11) & 0x1F)) &&
|
||||
(desktop_g >= ((banshee->vidChromaKeyMin >> 5) & 0x3F) && desktop_g <= ((banshee->vidChromaKeyMax >> 5) & 0x3F)) &&
|
||||
(desktop_b >= ((banshee->vidChromaKeyMin) & 0x1F) && desktop_b <= ((banshee->vidChromaKeyMax) & 0x1F));
|
||||
break;
|
||||
}
|
||||
case PIX_FORMAT_RGB24:
|
||||
{
|
||||
desktop_r = banshee->svga.vram[(src_addr_desktop + x * 3) & banshee->svga.vram_mask];
|
||||
desktop_g = banshee->svga.vram[(src_addr_desktop + x * 3 + 1) & banshee->svga.vram_mask];
|
||||
desktop_b = banshee->svga.vram[(src_addr_desktop + x * 3 + 2) & banshee->svga.vram_mask];
|
||||
res = (desktop_r >= ((banshee->vidChromaKeyMin >> 16) & 0xFF) && desktop_r <= ((banshee->vidChromaKeyMax >> 16) & 0xFF)) &&
|
||||
(desktop_g >= ((banshee->vidChromaKeyMin >> 8) & 0xFF) && desktop_g <= ((banshee->vidChromaKeyMax >> 8) & 0xFF)) &&
|
||||
(desktop_b >= ((banshee->vidChromaKeyMin) & 0xFF) && desktop_b <= ((banshee->vidChromaKeyMax) & 0xFF));
|
||||
break;
|
||||
}
|
||||
case PIX_FORMAT_RGB32:
|
||||
{
|
||||
desktop_r = banshee->svga.vram[(src_addr_desktop + x * 4) & banshee->svga.vram_mask];
|
||||
desktop_g = banshee->svga.vram[(src_addr_desktop + x * 4 + 1) & banshee->svga.vram_mask];
|
||||
desktop_b = banshee->svga.vram[(src_addr_desktop + x * 4 + 2) & banshee->svga.vram_mask];
|
||||
res = (desktop_r >= ((banshee->vidChromaKeyMin >> 16) & 0xFF) && desktop_r <= ((banshee->vidChromaKeyMax >> 16) & 0xFF)) &&
|
||||
(desktop_g >= ((banshee->vidChromaKeyMin >> 8) & 0xFF) && desktop_g <= ((banshee->vidChromaKeyMax >> 8) & 0xFF)) &&
|
||||
(desktop_b >= ((banshee->vidChromaKeyMin) & 0xFF) && desktop_b <= ((banshee->vidChromaKeyMax) & 0xFF));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
res ^= !!(banshee->vidProcCfg & (1 << 6));
|
||||
return res;
|
||||
}
|
||||
|
||||
static void
|
||||
banshee_overlay_draw(svga_t *svga, int displine)
|
||||
{
|
||||
banshee_t *banshee = (banshee_t *) svga->priv;
|
||||
voodoo_t *voodoo = banshee->voodoo;
|
||||
uint32_t *p;
|
||||
bool chroma_test_passed = true;
|
||||
int x;
|
||||
int y = voodoo->overlay.src_y >> 20;
|
||||
uint32_t src_addr = svga->overlay_latch.addr + ((banshee->vidProcCfg & VIDPROCCFG_OVERLAY_TILE) ? ((y & 31) * 128 + (y >> 5) * svga->overlay_latch.pitch) : y * svga->overlay_latch.pitch);
|
||||
@@ -2654,6 +2760,8 @@ banshee_overlay_draw(svga_t *svga, int displine)
|
||||
voodoo->overlay.src_y += (1 << 20);
|
||||
return;
|
||||
}
|
||||
|
||||
chroma_test_passed = banshee_chroma_key(banshee, svga->overlay_latch.x, displine - svga->y_add);
|
||||
|
||||
if ((voodoo->overlay.src_y >> 20) < 2048)
|
||||
voodoo->dirty_line[voodoo->overlay.src_y >> 20] = 0;
|
||||
@@ -2671,7 +2779,8 @@ banshee_overlay_draw(svga_t *svga, int displine)
|
||||
|
||||
if (skip_filtering) {
|
||||
/*No scaling or filtering required, just write straight to output buffer*/
|
||||
OVERLAY_SAMPLE(p);
|
||||
if (chroma_test_passed)
|
||||
OVERLAY_SAMPLE(p);
|
||||
} else {
|
||||
OVERLAY_SAMPLE(banshee->overlay_buffer[0]);
|
||||
|
||||
@@ -2688,25 +2797,31 @@ banshee_overlay_draw(svga_t *svga, int displine)
|
||||
((0x10000 - x_coeff) * y_coeff) >> 16,
|
||||
(x_coeff * y_coeff) >> 16
|
||||
};
|
||||
uint32_t samp0 = banshee->overlay_buffer[0][src_x >> 20];
|
||||
uint32_t samp1 = banshee->overlay_buffer[0][(src_x >> 20) + 1];
|
||||
uint32_t samp2 = banshee->overlay_buffer[1][src_x >> 20];
|
||||
uint32_t samp3 = banshee->overlay_buffer[1][(src_x >> 20) + 1];
|
||||
int r = (((samp0 >> 16) & 0xff) * coeffs[0] + ((samp1 >> 16) & 0xff) * coeffs[1] + ((samp2 >> 16) & 0xff) * coeffs[2] + ((samp3 >> 16) & 0xff) * coeffs[3]) >> 16;
|
||||
int g = (((samp0 >> 8) & 0xff) * coeffs[0] + ((samp1 >> 8) & 0xff) * coeffs[1] + ((samp2 >> 8) & 0xff) * coeffs[2] + ((samp3 >> 8) & 0xff) * coeffs[3]) >> 16;
|
||||
int b = ((samp0 & 0xff) * coeffs[0] + (samp1 & 0xff) * coeffs[1] + (samp2 & 0xff) * coeffs[2] + (samp3 & 0xff) * coeffs[3]) >> 16;
|
||||
p[x] = (r << 16) | (g << 8) | b;
|
||||
uint32_t samp0 = banshee->overlay_buffer[0][src_x >> 20];
|
||||
uint32_t samp1 = banshee->overlay_buffer[0][(src_x >> 20) + 1];
|
||||
uint32_t samp2 = banshee->overlay_buffer[1][src_x >> 20];
|
||||
uint32_t samp3 = banshee->overlay_buffer[1][(src_x >> 20) + 1];
|
||||
int r = (((samp0 >> 16) & 0xff) * coeffs[0] + ((samp1 >> 16) & 0xff) * coeffs[1] + ((samp2 >> 16) & 0xff) * coeffs[2] + ((samp3 >> 16) & 0xff) * coeffs[3]) >> 16;
|
||||
int g = (((samp0 >> 8) & 0xff) * coeffs[0] + ((samp1 >> 8) & 0xff) * coeffs[1] + ((samp2 >> 8) & 0xff) * coeffs[2] + ((samp3 >> 8) & 0xff) * coeffs[3]) >> 16;
|
||||
int b = ((samp0 & 0xff) * coeffs[0] + (samp1 & 0xff) * coeffs[1] + (samp2 & 0xff) * coeffs[2] + (samp3 & 0xff) * coeffs[3]) >> 16;
|
||||
chroma_test_passed = banshee_chroma_key(banshee, svga->overlay_latch.x + x, displine - svga->y_add);
|
||||
|
||||
if (chroma_test_passed)
|
||||
p[x] = (r << 16) | (g << 8) | b;
|
||||
|
||||
src_x += voodoo->overlay.vidOverlayDudx;
|
||||
}
|
||||
} else {
|
||||
for (x = 0; x < svga->overlay_latch.cur_xsize; x++) {
|
||||
uint32_t samp0 = banshee->overlay_buffer[0][src_x >> 20];
|
||||
uint32_t samp1 = banshee->overlay_buffer[1][src_x >> 20];
|
||||
int r = (((samp0 >> 16) & 0xff) * (0x10000 - y_coeff) + ((samp1 >> 16) & 0xff) * y_coeff) >> 16;
|
||||
int g = (((samp0 >> 8) & 0xff) * (0x10000 - y_coeff) + ((samp1 >> 8) & 0xff) * y_coeff) >> 16;
|
||||
int b = ((samp0 & 0xff) * (0x10000 - y_coeff) + (samp1 & 0xff) * y_coeff) >> 16;
|
||||
p[x] = (r << 16) | (g << 8) | b;
|
||||
uint32_t samp0 = banshee->overlay_buffer[0][src_x >> 20];
|
||||
uint32_t samp1 = banshee->overlay_buffer[1][src_x >> 20];
|
||||
int r = (((samp0 >> 16) & 0xff) * (0x10000 - y_coeff) + ((samp1 >> 16) & 0xff) * y_coeff) >> 16;
|
||||
int g = (((samp0 >> 8) & 0xff) * (0x10000 - y_coeff) + ((samp1 >> 8) & 0xff) * y_coeff) >> 16;
|
||||
int b = ((samp0 & 0xff) * (0x10000 - y_coeff) + (samp1 & 0xff) * y_coeff) >> 16;
|
||||
chroma_test_passed = banshee_chroma_key(banshee, svga->overlay_latch.x + x, displine - svga->y_add);
|
||||
|
||||
if (chroma_test_passed)
|
||||
p[x] = (r << 16) | (g << 8) | b;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -2761,21 +2876,30 @@ banshee_overlay_draw(svga_t *svga, int displine)
|
||||
fil3[x * 3 + 2] = vb_filter_v1_rb[fil[x * 3 + 2]][fil[(x - 1) * 3 + 2]];
|
||||
}
|
||||
for (x = 0; x < svga->overlay_latch.cur_xsize; x++) {
|
||||
fil[x * 3] = vb_filter_v1_rb[fil[x * 3]][fil3[(x + 1) * 3]];
|
||||
fil[x * 3 + 1] = vb_filter_v1_g[fil[x * 3 + 1]][fil3[(x + 1) * 3 + 1]];
|
||||
fil[x * 3 + 2] = vb_filter_v1_rb[fil[x * 3 + 2]][fil3[(x + 1) * 3 + 2]];
|
||||
p[x] = (fil[x * 3 + 2] << 16) | (fil[x * 3 + 1] << 8) | fil[x * 3];
|
||||
fil[x * 3] = vb_filter_v1_rb[fil[x * 3]][fil3[(x + 1) * 3]];
|
||||
fil[x * 3 + 1] = vb_filter_v1_g[fil[x * 3 + 1]][fil3[(x + 1) * 3 + 1]];
|
||||
fil[x * 3 + 2] = vb_filter_v1_rb[fil[x * 3 + 2]][fil3[(x + 1) * 3 + 2]];
|
||||
chroma_test_passed = banshee_chroma_key(banshee, svga->overlay_latch.x + x, displine - svga->y_add);
|
||||
|
||||
if (chroma_test_passed)
|
||||
p[x] = (fil[x * 3 + 2] << 16) | (fil[x * 3 + 1] << 8) | fil[x * 3];
|
||||
}
|
||||
} else /* filter disabled by emulator option */
|
||||
{
|
||||
if (banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE) {
|
||||
for (x = 0; x < svga->overlay_latch.cur_xsize; x++) {
|
||||
p[x] = banshee->overlay_buffer[0][src_x >> 20];
|
||||
chroma_test_passed = banshee_chroma_key(banshee, svga->overlay_latch.x + x, displine - svga->y_add);
|
||||
if (chroma_test_passed)
|
||||
p[x] = banshee->overlay_buffer[0][src_x >> 20];
|
||||
|
||||
src_x += voodoo->overlay.vidOverlayDudx;
|
||||
}
|
||||
} else {
|
||||
for (x = 0; x < svga->overlay_latch.cur_xsize; x++)
|
||||
p[x] = banshee->overlay_buffer[0][x];
|
||||
for (x = 0; x < svga->overlay_latch.cur_xsize; x++) {
|
||||
chroma_test_passed = banshee_chroma_key(banshee, svga->overlay_latch.x + x, displine - svga->y_add);
|
||||
if (chroma_test_passed)
|
||||
p[x] = banshee->overlay_buffer[0][x];
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -2830,25 +2954,35 @@ banshee_overlay_draw(svga_t *svga, int displine)
|
||||
if (banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE) /* 2x2 on a scaled low res */
|
||||
{
|
||||
for (x = 0; x < svga->overlay_latch.cur_xsize; x++) {
|
||||
p[x] = (fil[(src_x >> 20) * 3 + 2] << 16) | (fil[(src_x >> 20) * 3 + 1] << 8) | fil[(src_x >> 20) * 3];
|
||||
chroma_test_passed = banshee_chroma_key(banshee, svga->overlay_latch.x + x, displine - svga->y_add);
|
||||
if (chroma_test_passed)
|
||||
p[x] = (fil[(src_x >> 20) * 3 + 2] << 16) | (fil[(src_x >> 20) * 3 + 1] << 8) | fil[(src_x >> 20) * 3];
|
||||
|
||||
src_x += voodoo->overlay.vidOverlayDudx;
|
||||
}
|
||||
} else {
|
||||
for (x = 0; x < svga->overlay_latch.cur_xsize; x++) {
|
||||
p[x] = (fil[x * 3 + 2] << 16) | (fil[x * 3 + 1] << 8) | fil[x * 3];
|
||||
chroma_test_passed = banshee_chroma_key(banshee, svga->overlay_latch.x + x, displine - svga->y_add);
|
||||
if (chroma_test_passed)
|
||||
p[x] = (fil[x * 3 + 2] << 16) | (fil[x * 3 + 1] << 8) | fil[x * 3];
|
||||
}
|
||||
}
|
||||
} else /* filter disabled by emulator option */
|
||||
{
|
||||
if (banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE) {
|
||||
for (x = 0; x < svga->overlay_latch.cur_xsize; x++) {
|
||||
p[x] = banshee->overlay_buffer[0][src_x >> 20];
|
||||
chroma_test_passed = banshee_chroma_key(banshee, svga->overlay_latch.x + x, displine - svga->y_add);
|
||||
if (chroma_test_passed)
|
||||
p[x] = banshee->overlay_buffer[0][src_x >> 20];
|
||||
|
||||
src_x += voodoo->overlay.vidOverlayDudx;
|
||||
}
|
||||
} else {
|
||||
for (x = 0; x < svga->overlay_latch.cur_xsize; x++)
|
||||
p[x] = banshee->overlay_buffer[0][x];
|
||||
for (x = 0; x < svga->overlay_latch.cur_xsize; x++) {
|
||||
chroma_test_passed = banshee_chroma_key(banshee, svga->overlay_latch.x + x, displine - svga->y_add);
|
||||
if (chroma_test_passed)
|
||||
p[x] = banshee->overlay_buffer[0][x];
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -2857,13 +2991,18 @@ banshee_overlay_draw(svga_t *svga, int displine)
|
||||
default:
|
||||
if (banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE) {
|
||||
for (x = 0; x < svga->overlay_latch.cur_xsize; x++) {
|
||||
p[x] = banshee->overlay_buffer[0][src_x >> 20];
|
||||
chroma_test_passed = banshee_chroma_key(banshee, svga->overlay_latch.x + x, displine - svga->y_add);
|
||||
if (chroma_test_passed)
|
||||
p[x] = banshee->overlay_buffer[0][src_x >> 20];
|
||||
|
||||
src_x += voodoo->overlay.vidOverlayDudx;
|
||||
}
|
||||
} else {
|
||||
for (x = 0; x < svga->overlay_latch.cur_xsize; x++)
|
||||
p[x] = banshee->overlay_buffer[0][x];
|
||||
for (x = 0; x < svga->overlay_latch.cur_xsize; x++) {
|
||||
chroma_test_passed = banshee_chroma_key(banshee, svga->overlay_latch.x + x, displine - svga->y_add);
|
||||
if (chroma_test_passed)
|
||||
p[x] = banshee->overlay_buffer[0][x];
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -3262,6 +3401,8 @@ banshee_init_common(const device_t *info, char *fn, int has_sgram, int type, int
|
||||
banshee->agp = agp;
|
||||
banshee->has_bios = !!fn;
|
||||
|
||||
banshee->chroma_key_enabled = device_get_config_int("chromakey");
|
||||
|
||||
if (banshee->has_bios) {
|
||||
rom_init(&banshee->bios_rom, fn, 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL);
|
||||
mem_mapping_disable(&banshee->bios_rom.mapping);
|
||||
@@ -3692,6 +3833,17 @@ static const device_config_t banshee_sgram_config[] = {
|
||||
.selection = { { 0 } },
|
||||
.bios = { { 0 } }
|
||||
},
|
||||
{
|
||||
.name = "chromakey",
|
||||
.description = "Video chroma-keying",
|
||||
.type = CONFIG_BINARY,
|
||||
.default_string = NULL,
|
||||
.default_int = 1,
|
||||
.file_filter = NULL,
|
||||
.spinner = { 0 },
|
||||
.selection = { { 0 } },
|
||||
.bios = { { 0 } }
|
||||
},
|
||||
{
|
||||
.name = "dithersub",
|
||||
.description = "Dither subtraction",
|
||||
@@ -3758,6 +3910,17 @@ static const device_config_t banshee_sgram_16mbonly_config[] = {
|
||||
.selection = { { 0 } },
|
||||
.bios = { { 0 } }
|
||||
},
|
||||
{
|
||||
.name = "chromakey",
|
||||
.description = "Video chroma-keying",
|
||||
.type = CONFIG_BINARY,
|
||||
.default_string = NULL,
|
||||
.default_int = 1,
|
||||
.file_filter = NULL,
|
||||
.spinner = { 0 },
|
||||
.selection = { { 0 } },
|
||||
.bios = { { 0 } }
|
||||
},
|
||||
{
|
||||
.name = "dithersub",
|
||||
.description = "Dither subtraction",
|
||||
@@ -3824,6 +3987,17 @@ static const device_config_t banshee_sdram_config[] = {
|
||||
.selection = { { 0 } },
|
||||
.bios = { { 0 } }
|
||||
},
|
||||
{
|
||||
.name = "chromakey",
|
||||
.description = "Video chroma-keying",
|
||||
.type = CONFIG_BINARY,
|
||||
.default_string = NULL,
|
||||
.default_int = 1,
|
||||
.file_filter = NULL,
|
||||
.spinner = { 0 },
|
||||
.selection = { { 0 } },
|
||||
.bios = { { 0 } }
|
||||
},
|
||||
{
|
||||
.name = "dithersub",
|
||||
.description = "Dither subtraction",
|
||||
|
||||
@@ -917,7 +917,19 @@ do_screen_to_screen_stretch_line(voodoo_t *voodoo, uint8_t *src_p, int src_x, in
|
||||
const uint8_t *pattern_mono = (uint8_t *) voodoo->banshee_blt.colorPattern;
|
||||
int use_pattern_trans = (voodoo->banshee_blt.command & (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO)) == (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO);
|
||||
const uint32_t *colorPattern = voodoo->banshee_blt.colorPattern;
|
||||
int src_colorkey;
|
||||
|
||||
switch (voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) {
|
||||
case SRC_FORMAT_COL_8_BPP:
|
||||
src_colorkey = COLORKEY_8;
|
||||
break;
|
||||
case SRC_FORMAT_COL_16_BPP:
|
||||
src_colorkey = COLORKEY_16;
|
||||
break;
|
||||
default:
|
||||
src_colorkey = COLORKEY_32;
|
||||
break;
|
||||
}
|
||||
#if 0
|
||||
int error_y = voodoo->banshee_blt.dstSizeY / 2;
|
||||
|
||||
@@ -925,104 +937,218 @@ do_screen_to_screen_stretch_line(voodoo_t *voodoo, uint8_t *src_p, int src_x, in
|
||||
bansheeblt_log(" srcXY=%i,%i srcsizeXY=%i,%i\n", voodoo->banshee_blt.srcX, voodoo->banshee_blt.srcY, voodoo->banshee_blt.srcSizeX, voodoo->banshee_blt.srcSizeY);
|
||||
bansheeblt_log(" dstXY=%i,%i dstsizeXY=%i,%i\n", voodoo->banshee_blt.dstX, voodoo->banshee_blt.dstY, voodoo->banshee_blt.dstSizeX, voodoo->banshee_blt.dstSizeY);*/
|
||||
#endif
|
||||
if (dst_y >= clip->y_min && dst_y < clip->y_max) {
|
||||
#if 0
|
||||
int src_x = voodoo->banshee_blt.srcX;
|
||||
#endif
|
||||
int dst_x = voodoo->banshee_blt.dstX;
|
||||
int pat_x = voodoo->banshee_blt.patoff_x + voodoo->banshee_blt.dstX;
|
||||
uint8_t pattern_mask = pattern_mono[pat_y & 7];
|
||||
int error_x = voodoo->banshee_blt.dstSizeX / 2;
|
||||
if ((voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) == (voodoo->banshee_blt.dstFormat & DST_FORMAT_COL_MASK)) {
|
||||
if (dst_y >= clip->y_min && dst_y < clip->y_max) {
|
||||
int dst_x = voodoo->banshee_blt.dstX;
|
||||
int pat_x = voodoo->banshee_blt.patoff_x + voodoo->banshee_blt.dstX;
|
||||
uint8_t pattern_mask = pattern_mono[pat_y & 7];
|
||||
int error_x = voodoo->banshee_blt.dstSizeX / 2;
|
||||
|
||||
#if 0
|
||||
bansheeblt_log(" Plot dest line %03i : src line %03i\n", dst_y, src_y);
|
||||
#endif
|
||||
for (voodoo->banshee_blt.cur_x = 0; voodoo->banshee_blt.cur_x < voodoo->banshee_blt.dstSizeX; voodoo->banshee_blt.cur_x++) {
|
||||
int pattern_trans = use_pattern_trans ? (pattern_mask & (1 << (7 - (pat_x & 7)))) : 1;
|
||||
for (voodoo->banshee_blt.cur_x = 0; voodoo->banshee_blt.cur_x < voodoo->banshee_blt.dstSizeX; voodoo->banshee_blt.cur_x++) {
|
||||
int pattern_trans = use_pattern_trans ? (pattern_mask & (1 << (7 - (pat_x & 7)))) : 1;
|
||||
|
||||
if (dst_x >= clip->x_min && dst_x < clip->x_max && pattern_trans) {
|
||||
switch (voodoo->banshee_blt.dstFormat & DST_FORMAT_COL_MASK) {
|
||||
case DST_FORMAT_COL_8_BPP:
|
||||
{
|
||||
uint32_t dst_addr = get_addr(voodoo, dst_x, dst_y, 0, 0); //(voodoo->banshee_blt.dstBaseAddr + dst_x + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask;
|
||||
uint32_t src = src_p[src_x];
|
||||
uint32_t dest = voodoo->vram[dst_addr];
|
||||
uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? ((pattern_mask & (1 << (7 - (pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : colorPattern[(pat_x & 7) + (pat_y & 7) * 8];
|
||||
if (dst_x >= clip->x_min && dst_x < clip->x_max && pattern_trans) {
|
||||
switch (voodoo->banshee_blt.dstFormat & DST_FORMAT_COL_MASK) {
|
||||
case DST_FORMAT_COL_8_BPP:
|
||||
{
|
||||
uint32_t dst_addr = get_addr(voodoo, dst_x, dst_y, 0, 0); //(voodoo->banshee_blt.dstBaseAddr + dst_x + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask;
|
||||
uint32_t src = src_p[src_x];
|
||||
uint32_t dest = voodoo->vram[dst_addr];
|
||||
uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? ((pattern_mask & (1 << (7 - (pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : colorPattern[(pat_x & 7) + (pat_y & 7) * 8];
|
||||
|
||||
if (dst_addr > voodoo->fb_mask)
|
||||
if (dst_addr > voodoo->fb_mask)
|
||||
break;
|
||||
|
||||
voodoo->vram[dst_addr] = MIX(voodoo, dest, src, pattern, COLORKEY_8, COLORKEY_8);
|
||||
voodoo->changedvram[dst_addr >> 12] = changeframecount;
|
||||
break;
|
||||
}
|
||||
case DST_FORMAT_COL_16_BPP:
|
||||
{
|
||||
uint32_t dst_addr = get_addr(voodoo, dst_x * 2, dst_y, 0, 0); //(voodoo->banshee_blt.dstBaseAddr + dst_x*2 + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask;
|
||||
uint32_t src = *(uint16_t *) &src_p[src_x * 2];
|
||||
uint32_t dest = *(uint16_t *) &voodoo->vram[dst_addr];
|
||||
uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? ((pattern_mask & (1 << (7 - (pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : colorPattern[(pat_x & 7) + (pat_y & 7) * 8];
|
||||
|
||||
voodoo->vram[dst_addr] = MIX(voodoo, dest, src, pattern, COLORKEY_8, COLORKEY_8);
|
||||
#if 0
|
||||
bansheeblt_log("%i,%i : sdp=%02x,%02x,%02x res=%02x\n", voodoo->banshee_blt.cur_x, voodoo->banshee_blt.cur_y, src, dest, pattern, voodoo->vram[dst_addr]);
|
||||
#endif
|
||||
voodoo->changedvram[dst_addr >> 12] = changeframecount;
|
||||
break;
|
||||
}
|
||||
case DST_FORMAT_COL_16_BPP:
|
||||
{
|
||||
uint32_t dst_addr = get_addr(voodoo, dst_x * 2, dst_y, 0, 0); //(voodoo->banshee_blt.dstBaseAddr + dst_x*2 + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask;
|
||||
uint32_t src = *(uint16_t *) &src_p[src_x * 2];
|
||||
uint32_t dest = *(uint16_t *) &voodoo->vram[dst_addr];
|
||||
uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? ((pattern_mask & (1 << (7 - (pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : colorPattern[(pat_x & 7) + (pat_y & 7) * 8];
|
||||
if (dst_addr > voodoo->fb_mask)
|
||||
break;
|
||||
|
||||
if (dst_addr > voodoo->fb_mask)
|
||||
*(uint16_t *) &voodoo->vram[dst_addr] = MIX(voodoo, dest, src, pattern, COLORKEY_16, COLORKEY_16);
|
||||
voodoo->changedvram[dst_addr >> 12] = changeframecount;
|
||||
break;
|
||||
}
|
||||
case DST_FORMAT_COL_24_BPP:
|
||||
{
|
||||
uint32_t dst_addr = get_addr(voodoo, dst_x * 3, dst_y, 0, 0); //(voodoo->banshee_blt.dstBaseAddr + dst_x*3 + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask;
|
||||
uint32_t src = *(uint32_t *) &src_p[src_x * 3];
|
||||
uint32_t dest = *(uint32_t *) &voodoo->vram[dst_addr];
|
||||
uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? ((pattern_mask & (1 << (7 - (pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : colorPattern[(pat_x & 7) + (pat_y & 7) * 8];
|
||||
|
||||
*(uint16_t *) &voodoo->vram[dst_addr] = MIX(voodoo, dest, src, pattern, COLORKEY_16, COLORKEY_16);
|
||||
#if 0
|
||||
bansheeblt_log("%i,%i : sdp=%02x,%02x,%02x res=%02x\n", voodoo->banshee_blt.cur_x, voodoo->banshee_blt.cur_y, src, dest, pattern, *(uint16_t *)&voodoo->vram[dst_addr]);
|
||||
#endif
|
||||
voodoo->changedvram[dst_addr >> 12] = changeframecount;
|
||||
break;
|
||||
}
|
||||
case DST_FORMAT_COL_24_BPP:
|
||||
{
|
||||
uint32_t dst_addr = get_addr(voodoo, dst_x * 3, dst_y, 0, 0); //(voodoo->banshee_blt.dstBaseAddr + dst_x*3 + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask;
|
||||
uint32_t src = *(uint32_t *) &src_p[src_x * 3];
|
||||
uint32_t dest = *(uint32_t *) &voodoo->vram[dst_addr];
|
||||
uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? ((pattern_mask & (1 << (7 - (pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : colorPattern[(pat_x & 7) + (pat_y & 7) * 8];
|
||||
if (dst_addr > voodoo->fb_mask)
|
||||
break;
|
||||
|
||||
if (dst_addr > voodoo->fb_mask)
|
||||
*(uint32_t *) &voodoo->vram[dst_addr] = (MIX(voodoo, dest, src, pattern, COLORKEY_32, COLORKEY_32) & 0xffffff) | (*(uint32_t *) &voodoo->vram[dst_addr] & 0xff000000);
|
||||
voodoo->changedvram[dst_addr >> 12] = changeframecount;
|
||||
break;
|
||||
}
|
||||
case DST_FORMAT_COL_32_BPP:
|
||||
{
|
||||
uint32_t dst_addr = get_addr(voodoo, dst_x * 4, dst_y, 0, 0); //(voodoo->banshee_blt.dstBaseAddr + dst_x*4 + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask;
|
||||
uint32_t src = *(uint32_t *) &src_p[src_x * 4];
|
||||
uint32_t dest = *(uint32_t *) &voodoo->vram[dst_addr];
|
||||
uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? ((pattern_mask & (1 << (7 - (pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : colorPattern[(pat_x & 7) + (pat_y & 7) * 8];
|
||||
|
||||
*(uint32_t *) &voodoo->vram[dst_addr] = (MIX(voodoo, dest, src, pattern, COLORKEY_32, COLORKEY_32) & 0xffffff) | (*(uint32_t *) &voodoo->vram[dst_addr] & 0xff000000);
|
||||
#if 0
|
||||
bansheeblt_log("%i,%i : sdp=%02x,%02x,%02x res=%02x\n", voodoo->banshee_blt.cur_x, voodoo->banshee_blt.cur_y, src, dest, pattern, voodoo->vram[dst_addr]);
|
||||
#endif
|
||||
voodoo->changedvram[dst_addr >> 12] = changeframecount;
|
||||
break;
|
||||
}
|
||||
case DST_FORMAT_COL_32_BPP:
|
||||
{
|
||||
uint32_t dst_addr = get_addr(voodoo, dst_x * 4, dst_y, 0, 0); //(voodoo->banshee_blt.dstBaseAddr + dst_x*4 + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask;
|
||||
uint32_t src = *(uint32_t *) &src_p[src_x * 4];
|
||||
uint32_t dest = *(uint32_t *) &voodoo->vram[dst_addr];
|
||||
uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? ((pattern_mask & (1 << (7 - (pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : colorPattern[(pat_x & 7) + (pat_y & 7) * 8];
|
||||
if (dst_addr > voodoo->fb_mask)
|
||||
break;
|
||||
|
||||
if (dst_addr > voodoo->fb_mask)
|
||||
*(uint32_t *) &voodoo->vram[dst_addr] = MIX(voodoo, dest, src, pattern, COLORKEY_32, COLORKEY_32);
|
||||
voodoo->changedvram[dst_addr >> 12] = changeframecount;
|
||||
break;
|
||||
}
|
||||
|
||||
*(uint32_t *) &voodoo->vram[dst_addr] = MIX(voodoo, dest, src, pattern, COLORKEY_32, COLORKEY_32);
|
||||
#if 0
|
||||
bansheeblt_log("%i,%i : sdp=%02x,%02x,%02x res=%02x\n", voodoo->banshee_blt.cur_x, voodoo->banshee_blt.cur_y, src, dest, pattern, voodoo->vram[dst_addr]);
|
||||
#endif
|
||||
voodoo->changedvram[dst_addr >> 12] = changeframecount;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
error_x -= voodoo->banshee_blt.srcSizeX;
|
||||
while (error_x < 0) {
|
||||
error_x += voodoo->banshee_blt.dstSizeX;
|
||||
src_x++;
|
||||
error_x -= voodoo->banshee_blt.srcSizeX;
|
||||
while (error_x < 0) {
|
||||
error_x += voodoo->banshee_blt.dstSizeX;
|
||||
src_x++;
|
||||
}
|
||||
dst_x++;
|
||||
pat_x++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Color conversion required. */
|
||||
if (dst_y >= clip->y_min && dst_y < clip->y_max) {
|
||||
int dst_x = voodoo->banshee_blt.dstX;
|
||||
int pat_x = voodoo->banshee_blt.patoff_x + voodoo->banshee_blt.dstX;
|
||||
uint8_t pattern_mask = pattern_mono[pat_y & 7];
|
||||
int error_x = voodoo->banshee_blt.dstSizeX / 2;
|
||||
|
||||
for (voodoo->banshee_blt.cur_x = 0; voodoo->banshee_blt.cur_x < voodoo->banshee_blt.dstSizeX; voodoo->banshee_blt.cur_x++) {
|
||||
int pattern_trans = use_pattern_trans ? (pattern_mask & (1 << (7 - (pat_x & 7)))) : 1;
|
||||
int src_x_real = (src_x * voodoo->banshee_blt.src_bpp) >> 3;
|
||||
|
||||
if (dst_x >= clip->x_min && dst_x < clip->x_max && pattern_trans) {
|
||||
uint32_t src_data = 0;
|
||||
uint32_t src_data_yuv = 0; /* Used in YUYV-to-RGB convesions. */
|
||||
int transparent = 0;
|
||||
|
||||
switch (voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) {
|
||||
case SRC_FORMAT_COL_1_BPP:
|
||||
{
|
||||
uint8_t src_byte = src_p[src_x_real];
|
||||
src_data = (src_byte & (0x80 >> (src_x & 7))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack;
|
||||
if (voodoo->banshee_blt.command & COMMAND_TRANS_MONO)
|
||||
transparent = !(src_byte & (0x80 >> (src_x & 7)));
|
||||
#if 0
|
||||
bansheeblt_log(" 1bpp src_byte=%02x src_x=%i src_data=%x transparent=%i\n", src_byte, src_x, src_data, transparent);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case SRC_FORMAT_COL_8_BPP:
|
||||
{
|
||||
src_data = src_p[src_x_real];
|
||||
break;
|
||||
}
|
||||
case SRC_FORMAT_COL_16_BPP:
|
||||
{
|
||||
uint16_t src_16 = *(uint16_t *) &src_p[src_x_real];
|
||||
int r = (src_16 >> 11);
|
||||
int g = (src_16 >> 5) & 0x3f;
|
||||
int b = src_16 & 0x1f;
|
||||
|
||||
r = (r << 3) | (r >> 2);
|
||||
g = (g << 2) | (g >> 4);
|
||||
b = (b << 3) | (b >> 2);
|
||||
src_data = (r << 16) | (g << 8) | b;
|
||||
break;
|
||||
}
|
||||
case SRC_FORMAT_COL_24_BPP:
|
||||
{
|
||||
src_data = *(uint32_t *) &src_p[src_x_real];
|
||||
break;
|
||||
}
|
||||
case SRC_FORMAT_COL_32_BPP:
|
||||
{
|
||||
src_data = *(uint32_t *) &src_p[src_x_real];
|
||||
break;
|
||||
}
|
||||
case SRC_FORMAT_COL_YUYV:
|
||||
{
|
||||
src_data_yuv = *(uint32_t *) &src_p[src_x_real];
|
||||
break;
|
||||
}
|
||||
case SRC_FORMAT_COL_UYVY:
|
||||
{
|
||||
src_data_yuv = *(uint32_t *) &src_p[src_x_real];
|
||||
src_data_yuv = ((src_data_yuv & 0xFF00) >> 8) | ((src_data_yuv & 0xFF) << 8) |
|
||||
((src_data_yuv & 0xFF000000) >> 8) | ((src_data_yuv & 0xFF0000) << 8);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
fatal("banshee_do_screen_to_screen_stretch_blt: unknown srcFormat %08x\n", voodoo->banshee_blt.srcFormat);
|
||||
}
|
||||
|
||||
if ((voodoo->banshee_blt.dstFormat & DST_FORMAT_COL_MASK) == DST_FORMAT_COL_16_BPP && (voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) != SRC_FORMAT_COL_1_BPP) {
|
||||
int r = src_data >> 16;
|
||||
int g = (src_data >> 8) & 0xff;
|
||||
int b = src_data & 0xff;
|
||||
|
||||
src_data = (b >> 3) | ((g >> 2) << 5) | ((r >> 3) << 11);
|
||||
}
|
||||
|
||||
if ((voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) == SRC_FORMAT_COL_YUYV
|
||||
|| (voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) == SRC_FORMAT_COL_UYVY) {
|
||||
if (((voodoo->banshee_blt.dstFormat & DST_FORMAT_COL_MASK) == DST_FORMAT_COL_24_BPP) ||
|
||||
((voodoo->banshee_blt.dstFormat & DST_FORMAT_COL_MASK) == DST_FORMAT_COL_32_BPP)) {
|
||||
uint32_t rgbcol[2] = { 0, 0 };
|
||||
DECODE_YUYV422(rgbcol, (uint8_t *) &src_data_yuv);
|
||||
|
||||
bansheeblt_log("YUV -> 24 bpp or 32 bpp\n");
|
||||
|
||||
if (!transparent) {
|
||||
PLOT(voodoo, dst_x, dst_y, pat_x, pat_y, pattern_mask, 0xFF, rgbcol[0], src_colorkey);
|
||||
}
|
||||
dst_x++;
|
||||
|
||||
if (!transparent) {
|
||||
PLOT(voodoo, dst_x, dst_y, pat_x, pat_y, pattern_mask, 0xFF, rgbcol[1], src_colorkey);
|
||||
}
|
||||
} else if ((voodoo->banshee_blt.dstFormat & DST_FORMAT_COL_MASK) == DST_FORMAT_COL_16_BPP) {
|
||||
uint32_t rgbcol = 0;
|
||||
DECODE_YUYV422_16BPP((uint16_t *) &rgbcol, (uint8_t *) &src_data_yuv);
|
||||
|
||||
bansheeblt_log("YUV -> 16 bpp\n");
|
||||
|
||||
if (!transparent) {
|
||||
PLOT(voodoo, dst_x, dst_y, pat_x, pat_y, pattern_mask, 0xFF, rgbcol & 0xffff, src_colorkey);
|
||||
}
|
||||
dst_x++;
|
||||
|
||||
if (!transparent) {
|
||||
PLOT(voodoo, dst_x, dst_y, pat_x, pat_y, pattern_mask, 0xFF, rgbcol >> 16, src_colorkey);
|
||||
}
|
||||
} else
|
||||
fatal("banshee_do_screen_to_screen_stretch_blt: unknown dstFormat %08x\n", voodoo->banshee_blt.dstFormat);
|
||||
} else {
|
||||
if (!transparent)
|
||||
PLOT(voodoo, dst_x, dst_y, pat_x, pat_y, pattern_mask, 0xFF, src_data, src_colorkey);
|
||||
}
|
||||
}
|
||||
|
||||
error_x -= voodoo->banshee_blt.srcSizeX;
|
||||
while (error_x < 0) {
|
||||
error_x += voodoo->banshee_blt.dstSizeX;
|
||||
src_x++;
|
||||
}
|
||||
dst_x++;
|
||||
pat_x++;
|
||||
}
|
||||
dst_x++;
|
||||
pat_x++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -965,10 +965,12 @@ voodoo_reg_writel(uint32_t addr, uint32_t val, void *priv)
|
||||
if (chip & CHIP_TREX0) {
|
||||
voodoo->params.textureMode[0] = val;
|
||||
voodoo->params.tformat[0] = (val >> 8) & 0xf;
|
||||
voodoo_recalc_tex(voodoo, 0);
|
||||
}
|
||||
if (chip & CHIP_TREX1) {
|
||||
voodoo->params.textureMode[1] = val;
|
||||
voodoo->params.tformat[1] = (val >> 8) & 0xf;
|
||||
voodoo_recalc_tex(voodoo, 1);
|
||||
}
|
||||
break;
|
||||
case SST_tLOD:
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user