Merge branch 'master' into dsi_camera

# Conflicts:
#	src/DSi_I2C.cpp
This commit is contained in:
Arisotura 2020-10-26 20:47:30 +01:00
commit fc922ffb14
51 changed files with 350 additions and 104 deletions

View File

@ -20,8 +20,10 @@ jobs:
- name: Upgrade system - name: Upgrade system
shell: bash shell: bash
working-directory: ${{runner.workspace}} working-directory: ${{runner.workspace}}
run: | run: | #Fix grub installation error - https://github.com/actions/virtual-environments/issues/1605
sudo apt update sudo apt update
sudo apt-get install grub-efi
sudo update-grub
sudo apt full-upgrade sudo apt full-upgrade
- name: Install dependencies - name: Install dependencies
shell: bash shell: bash
@ -32,7 +34,8 @@ jobs:
sudo rm /etc/apt/sources.list sudo rm /etc/apt/sources.list
sudo mv /etc/apt/sources.list{.new,} sudo mv /etc/apt/sources.list{.new,}
sudo apt update sudo apt update
sudo apt install {gcc-10,g++-10,pkg-config}-aarch64-linux-gnu libsdl2-dev:arm64 qtbase5-dev:arm64 libslirp-dev:arm64 sudo apt install aptitude
sudo aptitude install -y {gcc-10,g++-10,pkg-config}-aarch64-linux-gnu libsdl2-dev:arm64 qtbase5-dev:arm64 libslirp-dev:arm64
- name: Create build environment - name: Create build environment
run: mkdir ${{runner.workspace}}/build run: mkdir ${{runner.workspace}}/build
- name: Configure - name: Configure

View File

@ -50,6 +50,12 @@ else()
option(ENABLE_LTO "Enable link-time optimization" OFF) option(ENABLE_LTO "Enable link-time optimization" OFF)
endif() endif()
option(ENABLE_OGLRENDERER "Enable OpenGL renderer" ON)
if (ENABLE_OGLRENDERER)
add_definitions(-DOGLRENDERER_ENABLED)
endif()
if (CMAKE_BUILD_TYPE STREQUAL Debug) if (CMAKE_BUILD_TYPE STREQUAL Debug)
add_compile_options(-Og) add_compile_options(-Og)
endif() endif()

View File

@ -38,7 +38,7 @@ As for the rest, the interface should be pretty straightforward. If you have a q
* Install dependencies: * Install dependencies:
```sh ```sh
sudo apt-get install libgtk-3-dev libcurl4-gnutls-dev libpcap0.8-dev libsdl2-dev qtbase5-dev qtdeclarative5-dev libslirp-dev sudo apt-get install cmake libgtk-3-dev libcurl4-gnutls-dev libpcap0.8-dev libsdl2-dev qtbase5-dev qtdeclarative5-dev libslirp-dev
``` ```
* Compile: * Compile:

View File

@ -24,7 +24,10 @@
#include "types.h" #include "types.h"
#include "NDS.h" #include "NDS.h"
#define ROR(x, n) (((x) >> (n)) | ((x) << (32-(n)))) inline u32 ROR(u32 x, u32 n)
{
return (x >> (n&0x1F)) | (x << ((32-n)&0x1F));
}
enum enum
{ {

View File

@ -1087,7 +1087,10 @@ void ResetBlockCache()
InvalidLiterals.Clear(); InvalidLiterals.Clear();
for (int i = 0; i < ARMJIT_Memory::memregions_Count; i++) for (int i = 0; i < ARMJIT_Memory::memregions_Count; i++)
{
if (FastBlockLookupRegions[i])
memset(FastBlockLookupRegions[i], 0xFF, CodeRegionSizes[i] * sizeof(u64) / 2); memset(FastBlockLookupRegions[i], 0xFF, CodeRegionSizes[i] * sizeof(u64) / 2);
}
for (auto it = RestoreCandidates.begin(); it != RestoreCandidates.end(); it++) for (auto it = RestoreCandidates.begin(); it != RestoreCandidates.end(); it++)
delete it->second; delete it->second;
RestoreCandidates.clear(); RestoreCandidates.clear();

View File

@ -436,7 +436,7 @@ void Compiler::A_Comp_GetOp2(bool S, Op2& op2)
Comp_AddCycles_C(); Comp_AddCycles_C();
u32 shift = (CurInstr.Instr >> 7) & 0x1E; u32 shift = (CurInstr.Instr >> 7) & 0x1E;
u32 imm = ROR(CurInstr.Instr & 0xFF, shift); u32 imm = ::ROR(CurInstr.Instr & 0xFF, shift);
if (S && shift && (CurInstr.SetFlags & 0x2)) if (S && shift && (CurInstr.SetFlags & 0x2))
{ {
@ -447,7 +447,7 @@ void Compiler::A_Comp_GetOp2(bool S, Op2& op2)
ANDI2R(RCPSR, RCPSR, ~(1 << 29)); ANDI2R(RCPSR, RCPSR, ~(1 << 29));
} }
op2 = Op2(ROR(CurInstr.Instr & 0xFF, (CurInstr.Instr >> 7) & 0x1E)); op2 = Op2(imm);
} }
else else
{ {
@ -523,7 +523,7 @@ void Compiler::A_Comp_ALUMovOp()
case ST_LSL: LSL(rd, op2.Reg.Rm, op2.Reg.ShiftAmount); break; case ST_LSL: LSL(rd, op2.Reg.Rm, op2.Reg.ShiftAmount); break;
case ST_LSR: LSR(rd, op2.Reg.Rm, op2.Reg.ShiftAmount); break; case ST_LSR: LSR(rd, op2.Reg.Rm, op2.Reg.ShiftAmount); break;
case ST_ASR: ASR(rd, op2.Reg.Rm, op2.Reg.ShiftAmount); break; case ST_ASR: ASR(rd, op2.Reg.Rm, op2.Reg.ShiftAmount); break;
case ST_ROR: ROR_(rd, op2.Reg.Rm, op2.Reg.ShiftAmount); break; case ST_ROR: ROR(rd, op2.Reg.Rm, op2.Reg.ShiftAmount); break;
} }
} }
else else

View File

@ -76,7 +76,7 @@ void Compiler::A_Comp_MSR()
if (CurInstr.Instr & (1 << 25)) if (CurInstr.Instr & (1 << 25))
{ {
val = W0; val = W0;
MOVI2R(val, ROR((CurInstr.Instr & 0xFF), ((CurInstr.Instr >> 7) & 0x1E))); MOVI2R(val, ::ROR((CurInstr.Instr & 0xFF), ((CurInstr.Instr >> 7) & 0x1E)));
} }
else else
{ {

View File

@ -1,5 +1,5 @@
#ifndef ARMJIT_COMPILER_H #ifndef ARMJIT_A64_COMPILER_H
#define ARMJIT_COMPILER_H #define ARMJIT_A64_COMPILER_H
#include "../ARM.h" #include "../ARM.h"
#include "../ARMJIT.h" #include "../ARMJIT.h"

View File

@ -42,7 +42,7 @@ s64 Compiler::RewriteMemAccess(u64 pc)
return patch.PatchOffset; return patch.PatchOffset;
} }
printf("this is a JIT bug! %08x\n", __builtin_bswap32(*(u32*)pc)); printf("this is a JIT bug! %08x\n", __builtin_bswap32(*(u32*)pc));
assert(false); abort();
} }
bool Compiler::Comp_MemLoadLiteral(int size, bool signExtend, int rd, u32 addr) bool Compiler::Comp_MemLoadLiteral(int size, bool signExtend, int rd, u32 addr)
@ -65,7 +65,7 @@ bool Compiler::Comp_MemLoadLiteral(int size, bool signExtend, int rd, u32 addr)
if (size == 32) if (size == 32)
{ {
CurCPU->DataRead32(addr & ~0x3, &val); CurCPU->DataRead32(addr & ~0x3, &val);
val = ROR(val, (addr & 0x3) << 3); val = ::ROR(val, (addr & 0x3) << 3);
} }
else if (size == 16) else if (size == 16)
{ {
@ -151,7 +151,7 @@ void Compiler::Comp_MemAccess(int rd, int rn, Op2 offset, int size, int flags)
{ {
if (offset.Reg.ShiftType == ST_ROR) if (offset.Reg.ShiftType == ST_ROR)
{ {
ROR_(W0, offset.Reg.Rm, offset.Reg.ShiftAmount); ROR(W0, offset.Reg.Rm, offset.Reg.ShiftAmount);
offset = Op2(W0); offset = Op2(W0);
} }
@ -220,7 +220,7 @@ void Compiler::Comp_MemAccess(int rd, int rn, Op2 offset, int size, int flags)
if (size == 32) if (size == 32)
{ {
if (staticAddress & 0x3) if (staticAddress & 0x3)
ROR_(rdMapped, W0, (staticAddress & 0x3) << 3); ROR(rdMapped, W0, (staticAddress & 0x3) << 3);
else else
MOV(rdMapped, W0); MOV(rdMapped, W0);
} }

View File

@ -1,3 +1,6 @@
#ifndef ARMJIT_COMPILER_H
#define ARMJIT_COMPILER_H
#if defined(__x86_64__) #if defined(__x86_64__)
#include "ARMJIT_x64/ARMJIT_Compiler.h" #include "ARMJIT_x64/ARMJIT_Compiler.h"
#elif defined(__aarch64__) #elif defined(__aarch64__)
@ -10,3 +13,5 @@ namespace ARMJIT
{ {
extern Compiler* JITCompiler; extern Compiler* JITCompiler;
} }
#endif

View File

@ -279,6 +279,7 @@ bool UnmapFromRange(u32 addr, u32 num, u32 offset, u32 size)
#endif #endif
} }
#ifndef __SWITCH__
void SetCodeProtectionRange(u32 addr, u32 size, u32 num, int protection) void SetCodeProtectionRange(u32 addr, u32 size, u32 num, int protection)
{ {
u8* dst = (u8*)(num == 0 ? FastMem9Start : FastMem7Start) + addr; u8* dst = (u8*)(num == 0 ? FastMem9Start : FastMem7Start) + addr;
@ -303,6 +304,7 @@ void SetCodeProtectionRange(u32 addr, u32 size, u32 num, int protection)
mprotect(dst, size, posixProt); mprotect(dst, size, posixProt);
#endif #endif
} }
#endif
struct Mapping struct Mapping
{ {

View File

@ -61,7 +61,8 @@ public:
} }
} }
assert("Welp!"); printf("this is a JIT bug! LoadRegister failed\n");
abort();
} }
void PutLiteral(int reg, u32 val) void PutLiteral(int reg, u32 val)

View File

@ -110,7 +110,7 @@ OpArg Compiler::A_Comp_GetALUOp2(bool S, bool& carryUsed)
Comp_AddCycles_C(); Comp_AddCycles_C();
u32 shift = (CurInstr.Instr >> 7) & 0x1E; u32 shift = (CurInstr.Instr >> 7) & 0x1E;
u32 imm = ROR(CurInstr.Instr & 0xFF, shift); u32 imm = ::ROR(CurInstr.Instr & 0xFF, shift);
carryUsed = false; carryUsed = false;
if (S && shift) if (S && shift)
@ -209,7 +209,8 @@ void Compiler::A_Comp_Arith()
Comp_ArithTriOp(&Compiler::AND, rd, rn, op2, carryUsed, sFlag|opSymmetric|opInvertOp2); Comp_ArithTriOp(&Compiler::AND, rd, rn, op2, carryUsed, sFlag|opSymmetric|opInvertOp2);
break; break;
default: default:
assert("unimplemented"); printf("this is a JIT bug! %04x\n", op);
abort();
} }
if (CurInstr.A_Reg(12) == 15) if (CurInstr.A_Reg(12) == 15)
@ -493,7 +494,7 @@ OpArg Compiler::Comp_RegShiftReg(int op, Gen::OpArg rs, Gen::OpArg rm, bool S, b
{ {
if (S) if (S)
BT(32, R(RSCRATCH), Imm8(31)); BT(32, R(RSCRATCH), Imm8(31));
ROR_(32, R(RSCRATCH), R(ECX)); ROR(32, R(RSCRATCH), R(ECX));
if (S) if (S)
SETcc(CC_C, R(RSCRATCH2)); SETcc(CC_C, R(RSCRATCH2));
} }
@ -555,7 +556,7 @@ OpArg Compiler::Comp_RegShiftImm(int op, int amount, OpArg rm, bool S, bool& car
case 3: // ROR case 3: // ROR
MOV(32, R(RSCRATCH), rm); MOV(32, R(RSCRATCH), rm);
if (amount > 0) if (amount > 0)
ROR_(32, R(RSCRATCH), Imm8(amount)); ROR(32, R(RSCRATCH), Imm8(amount));
else else
{ {
BT(32, R(RCPSR), Imm8(29)); BT(32, R(RCPSR), Imm8(29));
@ -566,7 +567,7 @@ OpArg Compiler::Comp_RegShiftImm(int op, int amount, OpArg rm, bool S, bool& car
return R(RSCRATCH); return R(RSCRATCH);
} }
assert(false); abort();
} }
void Compiler::T_Comp_ShiftImm() void Compiler::T_Comp_ShiftImm()

View File

@ -106,7 +106,7 @@ void Compiler::A_Comp_MSR()
Comp_AddCycles_C(); Comp_AddCycles_C();
OpArg val = CurInstr.Instr & (1 << 25) OpArg val = CurInstr.Instr & (1 << 25)
? Imm32(ROR((CurInstr.Instr & 0xFF), ((CurInstr.Instr >> 7) & 0x1E))) ? Imm32(::ROR((CurInstr.Instr & 0xFF), ((CurInstr.Instr >> 7) & 0x1E)))
: MapReg(CurInstr.A_Reg(0)); : MapReg(CurInstr.A_Reg(0));
u32 mask = 0; u32 mask = 0;

View File

@ -1,5 +1,5 @@
#ifndef ARMJIT_COMPILER_H #ifndef ARMJIT_X64_COMPILER_H
#define ARMJIT_COMPILER_H #define ARMJIT_X64_COMPILER_H
#include "../dolphin/x64Emitter.h" #include "../dolphin/x64Emitter.h"

View File

@ -39,7 +39,7 @@ s32 Compiler::RewriteMemAccess(u64 pc)
return patch.Offset; return patch.Offset;
} }
printf("this is a JIT bug %x\n", pc); printf("this is a JIT bug %llx\n", pc);
abort(); abort();
} }
@ -73,7 +73,7 @@ bool Compiler::Comp_MemLoadLiteral(int size, bool signExtend, int rd, u32 addr)
if (size == 32) if (size == 32)
{ {
CurCPU->DataRead32(addr & ~0x3, &val); CurCPU->DataRead32(addr & ~0x3, &val);
val = ROR(val, (addr & 0x3) << 3); val = ::ROR(val, (addr & 0x3) << 3);
} }
else if (size == 16) else if (size == 16)
{ {
@ -225,13 +225,13 @@ void Compiler::Comp_MemAccess(int rd, int rn, const Op2& op2, int size, int flag
if (addrIsStatic) if (addrIsStatic)
{ {
if (staticAddress & 0x3) if (staticAddress & 0x3)
ROR_(32, rdMapped, Imm8((staticAddress & 0x3) * 8)); ROR(32, rdMapped, Imm8((staticAddress & 0x3) * 8));
} }
else else
{ {
AND(32, R(RSCRATCH3), Imm8(0x3)); AND(32, R(RSCRATCH3), Imm8(0x3));
SHL(32, R(RSCRATCH3), Imm8(3)); SHL(32, R(RSCRATCH3), Imm8(3));
ROR_(32, rdMapped, R(RSCRATCH3)); ROR(32, rdMapped, R(RSCRATCH3));
} }
} }
} }
@ -270,7 +270,7 @@ void Compiler::Comp_MemAccess(int rd, int rn, const Op2& op2, int size, int flag
{ {
MOV(32, rdMapped, R(RSCRATCH)); MOV(32, rdMapped, R(RSCRATCH));
if (staticAddress & 0x3) if (staticAddress & 0x3)
ROR_(32, rdMapped, Imm8((staticAddress & 0x3) * 8)); ROR(32, rdMapped, Imm8((staticAddress & 0x3) * 8));
} }
else else
{ {

View File

@ -26,17 +26,12 @@ add_library(core STATIC
FIFO.h FIFO.h
GBACart.cpp GBACart.cpp
GPU.cpp GPU.cpp
GPU_OpenGL.cpp
GPU_OpenGL_shaders.h
GPU2D.cpp GPU2D.cpp
GPU3D.cpp GPU3D.cpp
GPU3D_OpenGL.cpp
GPU3D_OpenGL_shaders.h
GPU3D_Soft.cpp GPU3D_Soft.cpp
melonDLDI.h melonDLDI.h
NDS.cpp NDS.cpp
NDSCart.cpp NDSCart.cpp
OpenGLSupport.cpp
Platform.h Platform.h
ROMList.h ROMList.h
RTC.cpp RTC.cpp
@ -52,6 +47,16 @@ add_library(core STATIC
xxhash/xxhash.c xxhash/xxhash.c
) )
if (ENABLE_OGLRENDERER)
target_sources(core PRIVATE
GPU_OpenGL.cpp
GPU_OpenGL_shaders.h
GPU3D_OpenGL.cpp
GPU3D_OpenGL_shaders.h
OpenGLSupport.cpp
)
endif()
if (ENABLE_JIT) if (ENABLE_JIT)
enable_language(ASM) enable_language(ASM)
@ -95,8 +100,16 @@ if (ENABLE_JIT)
endif() endif()
endif() endif()
if (WIN32) if (ENABLE_OGLRENDERER)
if (WIN32)
target_link_libraries(core ole32 comctl32 ws2_32 opengl32) target_link_libraries(core ole32 comctl32 ws2_32 opengl32)
else() else()
target_link_libraries(core GL EGL) target_link_libraries(core GL EGL)
endif()
else()
if (WIN32)
target_link_libraries(core ole32 comctl32 ws2_32)
else()
target_link_libraries(core)
endif()
endif() endif()

View File

@ -46,7 +46,7 @@ int RandomizeMAC;
#ifdef JIT_ENABLED #ifdef JIT_ENABLED
int JIT_Enable = false; int JIT_Enable = false;
int JIT_MaxBlockSize = 32; int JIT_MaxBlockSize = 32;
int JIT_BranchOptimisations = 2; int JIT_BranchOptimisations = true;
int JIT_LiteralOptimisations = true; int JIT_LiteralOptimisations = true;
int JIT_FastMemory = true; int JIT_FastMemory = true;
#endif #endif
@ -71,7 +71,7 @@ ConfigEntry ConfigFile[] =
#ifdef JIT_ENABLED #ifdef JIT_ENABLED
{"JIT_Enable", 0, &JIT_Enable, 0, NULL, 0}, {"JIT_Enable", 0, &JIT_Enable, 0, NULL, 0},
{"JIT_MaxBlockSize", 0, &JIT_MaxBlockSize, 32, NULL, 0}, {"JIT_MaxBlockSize", 0, &JIT_MaxBlockSize, 32, NULL, 0},
{"JIT_BranchOptimisations", 0, &JIT_BranchOptimisations, 2, NULL, 0}, {"JIT_BranchOptimisations", 0, &JIT_BranchOptimisations, 1, NULL, 0},
{"JIT_LiteralOptimisations", 0, &JIT_LiteralOptimisations, 1, NULL, 0}, {"JIT_LiteralOptimisations", 0, &JIT_LiteralOptimisations, 1, NULL, 0},
{"JIT_FastMemory", 0, &JIT_FastMemory, 1, NULL, 0}, {"JIT_FastMemory", 0, &JIT_FastMemory, 1, NULL, 0},
#endif #endif
@ -169,7 +169,7 @@ void Save()
if (entry->Type == 0) if (entry->Type == 0)
fprintf(f, "%s=%d\n", entry->Name, *(int*)entry->Value); fprintf(f, "%s=%d\n", entry->Name, *(int*)entry->Value);
else else
fprintf(f, "%s=%s\n", entry->Name, entry->Value); fprintf(f, "%s=%s\n", entry->Name, (char*)entry->Value);
entry++; entry++;
} }

View File

@ -73,6 +73,8 @@ void DMA::Reset()
SrcAddrInc = 0; SrcAddrInc = 0;
DstAddrInc = 0; DstAddrInc = 0;
Stall = false;
Running = false; Running = false;
InProgress = false; InProgress = false;
@ -111,8 +113,8 @@ void DMA::DoSavestate(Savestate* file)
file->Var32(&DstAddrInc); file->Var32(&DstAddrInc);
file->Var32(&Running); file->Var32(&Running);
file->Var32((u32*)&InProgress); file->Bool32(&InProgress);
file->Var32((u32*)&IsGXFIFODMA); file->Bool32(&IsGXFIFODMA);
} }
void DMA::WriteCnt(u32 val) void DMA::WriteCnt(u32 val)

View File

@ -1740,7 +1740,7 @@ u8 ARM7IORead8(u32 addr)
case 0x04004501: return DSi_I2C::Cnt; case 0x04004501: return DSi_I2C::Cnt;
case 0x04004D00: if (SCFG_BIOS & (1<<10)) return 0; return ConsoleID & 0xFF; case 0x04004D00: if (SCFG_BIOS & (1<<10)) return 0; return ConsoleID & 0xFF;
case 0x04004fD01: if (SCFG_BIOS & (1<<10)) return 0; return (ConsoleID >> 8) & 0xFF; case 0x04004D01: if (SCFG_BIOS & (1<<10)) return 0; return (ConsoleID >> 8) & 0xFF;
case 0x04004D02: if (SCFG_BIOS & (1<<10)) return 0; return (ConsoleID >> 16) & 0xFF; case 0x04004D02: if (SCFG_BIOS & (1<<10)) return 0; return (ConsoleID >> 16) & 0xFF;
case 0x04004D03: if (SCFG_BIOS & (1<<10)) return 0; return (ConsoleID >> 24) & 0xFF; case 0x04004D03: if (SCFG_BIOS & (1<<10)) return 0; return (ConsoleID >> 24) & 0xFF;
case 0x04004D04: if (SCFG_BIOS & (1<<10)) return 0; return (ConsoleID >> 32) & 0xFF; case 0x04004D04: if (SCFG_BIOS & (1<<10)) return 0; return (ConsoleID >> 32) & 0xFF;

View File

@ -50,7 +50,7 @@ void Reset()
Registers[0x10] = 0x00; // power btn Registers[0x10] = 0x00; // power btn
Registers[0x11] = 0x00; // reset Registers[0x11] = 0x00; // reset
Registers[0x12] = 0x00; // power btn tap Registers[0x12] = 0x00; // power btn tap
Registers[0x20] = 0x83; // battery Registers[0x20] = 0x8F; // battery
Registers[0x21] = 0x07; Registers[0x21] = 0x07;
Registers[0x30] = 0x13; Registers[0x30] = 0x13;
Registers[0x31] = 0x00; // camera power Registers[0x31] = 0x00; // camera power
@ -189,6 +189,8 @@ void WriteCnt(u8 val)
case 0x4A: Data = DSi_BPTWL::Read(islast); break; case 0x4A: Data = DSi_BPTWL::Read(islast); break;
case 0x78: Data = DSi_Camera0->I2C_Read(islast); break; case 0x78: Data = DSi_Camera0->I2C_Read(islast); break;
case 0x7A: Data = DSi_Camera1->I2C_Read(islast); break; case 0x7A: Data = DSi_Camera1->I2C_Read(islast); break;
case 0xA0:
case 0xE0: Data = 0xFF; break;
default: default:
printf("I2C: read on unknown device %02X, cnt=%02X, data=%02X, last=%d\n", Device, val, 0, islast); printf("I2C: read on unknown device %02X, cnt=%02X, data=%02X, last=%d\n", Device, val, 0, islast);
Data = 0xFF; Data = 0xFF;
@ -213,6 +215,8 @@ void WriteCnt(u8 val)
case 0x4A: DSi_BPTWL::Start(); break; case 0x4A: DSi_BPTWL::Start(); break;
case 0x78: DSi_Camera0->I2C_Start(); break; case 0x78: DSi_Camera0->I2C_Start(); break;
case 0x7A: DSi_Camera1->I2C_Start(); break; case 0x7A: DSi_Camera1->I2C_Start(); break;
case 0xA0:
case 0xE0: ack = false; break;
default: default:
printf("I2C: %s start on unknown device %02X\n", (Data&0x01)?"read":"write", Device); printf("I2C: %s start on unknown device %02X\n", (Data&0x01)?"read":"write", Device);
ack = false; ack = false;
@ -228,6 +232,8 @@ void WriteCnt(u8 val)
case 0x4A: DSi_BPTWL::Write(Data, islast); break; case 0x4A: DSi_BPTWL::Write(Data, islast); break;
case 0x78: DSi_Camera0->I2C_Write(Data, islast); break; case 0x78: DSi_Camera0->I2C_Write(Data, islast); break;
case 0x7A: DSi_Camera1->I2C_Write(Data, islast); break; case 0x7A: DSi_Camera1->I2C_Write(Data, islast); break;
case 0xA0:
case 0xE0: ack = false; break;
default: default:
printf("I2C: write on unknown device %02X, cnt=%02X, data=%02X, last=%d\n", Device, val, Data, islast); printf("I2C: write on unknown device %02X, cnt=%02X, data=%02X, last=%d\n", Device, val, Data, islast);
ack = false; ack = false;

View File

@ -778,6 +778,23 @@ void DSi_MMCStorage::SendCMD(u8 cmd, u32 param)
Host->SendResponse(CSR, true); Host->SendResponse(CSR, true);
return; return;
case 1: // SEND_OP_COND
// CHECKME!!
// also TODO: it's different for the SD card
if (Internal)
{
param &= ~(1<<30);
OCR &= 0xBF000000;
OCR |= (param & 0x40FFFFFF);
Host->SendResponse(OCR, true);
SetState(0x01);
}
else
{
printf("CMD1 on SD card!!\n");
}
return;
case 2: case 2:
case 10: // get CID case 10: // get CID
Host->SendResponse(*(u32*)&CID[12], false); Host->SendResponse(*(u32*)&CID[12], false);
@ -801,6 +818,11 @@ void DSi_MMCStorage::SendCMD(u8 cmd, u32 param)
} }
return; return;
case 6: // MMC: 'SWITCH'
// TODO!
Host->SendResponse(CSR, true);
return;
case 7: // select card (by RCA) case 7: // select card (by RCA)
Host->SendResponse(CSR, true); Host->SendResponse(CSR, true);
return; return;

View File

@ -103,7 +103,7 @@ class DSi_SDDevice
{ {
public: public:
DSi_SDDevice(DSi_SDHost* host) { Host = host; IRQ = false; } DSi_SDDevice(DSi_SDHost* host) { Host = host; IRQ = false; }
~DSi_SDDevice() {} virtual ~DSi_SDDevice() {}
virtual void Reset() = 0; virtual void Reset() = 0;

View File

@ -280,6 +280,7 @@ void AssignFramebuffers()
void InitRenderer(int renderer) void InitRenderer(int renderer)
{ {
#ifdef OGLRENDERER_ENABLED
if (renderer == 1) if (renderer == 1)
{ {
if (!GLCompositor::Init()) if (!GLCompositor::Init())
@ -292,8 +293,8 @@ void InitRenderer(int renderer)
renderer = 0; renderer = 0;
} }
} }
else
if (renderer == 0) #endif
{ {
GPU3D::SoftRenderer::Init(); GPU3D::SoftRenderer::Init();
} }
@ -308,11 +309,13 @@ void DeInitRenderer()
{ {
GPU3D::SoftRenderer::DeInit(); GPU3D::SoftRenderer::DeInit();
} }
#ifdef OGLRENDERER_ENABLED
else else
{ {
GPU3D::GLRenderer::DeInit(); GPU3D::GLRenderer::DeInit();
GLCompositor::DeInit(); GLCompositor::DeInit();
} }
#endif
} }
void ResetRenderer() void ResetRenderer()
@ -321,11 +324,13 @@ void ResetRenderer()
{ {
GPU3D::SoftRenderer::Reset(); GPU3D::SoftRenderer::Reset();
} }
#ifdef OGLRENDERER_ENABLED
else else
{ {
GLCompositor::Reset(); GLCompositor::Reset();
GPU3D::GLRenderer::Reset(); GPU3D::GLRenderer::Reset();
} }
#endif
} }
void SetRenderSettings(int renderer, RenderSettings& settings) void SetRenderSettings(int renderer, RenderSettings& settings)
@ -364,11 +369,13 @@ void SetRenderSettings(int renderer, RenderSettings& settings)
{ {
GPU3D::SoftRenderer::SetRenderSettings(settings); GPU3D::SoftRenderer::SetRenderSettings(settings);
} }
#ifdef OGLRENDERER_ENABLED
else else
{ {
GLCompositor::SetRenderSettings(settings); GLCompositor::SetRenderSettings(settings);
GPU3D::GLRenderer::SetRenderSettings(settings); GPU3D::GLRenderer::SetRenderSettings(settings);
} }
#endif
} }
@ -1055,7 +1062,9 @@ void StartScanline(u32 line)
GPU2D_B->VBlank(); GPU2D_B->VBlank();
GPU3D::VBlank(); GPU3D::VBlank();
#ifdef OGLRENDERER_ENABLED
if (Accelerated) GLCompositor::RenderFrame(); if (Accelerated) GLCompositor::RenderFrame();
#endif
} }
else if (VCount == 144) else if (VCount == 144)
{ {

View File

@ -437,6 +437,7 @@ void SetDispStat(u32 cpu, u16 val);
void SetVCount(u16 val); void SetVCount(u16 val);
#ifdef OGLRENDERER_ENABLED
namespace GLCompositor namespace GLCompositor
{ {
@ -450,6 +451,7 @@ void RenderFrame();
void BindOutputTexture(); void BindOutputTexture();
} }
#endif
} }

View File

@ -102,6 +102,7 @@ GPU2D::~GPU2D()
void GPU2D::Reset() void GPU2D::Reset()
{ {
Enabled = false;
DispCnt = 0; DispCnt = 0;
memset(BGCnt, 0, 4*2); memset(BGCnt, 0, 4*2);
memset(BGXPos, 0, 4*2); memset(BGXPos, 0, 4*2);
@ -814,7 +815,6 @@ void GPU2D::DrawScanline(u32 line)
int i = 0; int i = 0;
for (; i < (stride & ~1); i+=2) for (; i < (stride & ~1); i+=2)
*(u64*)&dst[i] = *(u64*)&BGOBJLine[i]; *(u64*)&dst[i] = *(u64*)&BGOBJLine[i];
if (stride & 1) dst[i] = BGOBJLine[i];
} }
break; break;
@ -949,6 +949,7 @@ void GPU2D::VBlankEnd()
//OBJMosaicY = 0; //OBJMosaicY = 0;
//OBJMosaicYCount = 0; //OBJMosaicYCount = 0;
#ifdef OGLRENDERER_ENABLED
if (Accelerated) if (Accelerated)
{ {
if ((Num == 0) && (CaptureCnt & (1<<31)) && (((CaptureCnt >> 29) & 0x3) != 1)) if ((Num == 0) && (CaptureCnt & (1<<31)) && (((CaptureCnt >> 29) & 0x3) != 1))
@ -956,6 +957,7 @@ void GPU2D::VBlankEnd()
GPU3D::GLRenderer::PrepareCaptureFrame(); GPU3D::GLRenderer::PrepareCaptureFrame();
} }
} }
#endif
} }

View File

@ -470,7 +470,7 @@ void DoSavestate(Savestate* file)
file->VarArray(vtx->Color, sizeof(s32)*3); file->VarArray(vtx->Color, sizeof(s32)*3);
file->VarArray(vtx->TexCoords, sizeof(s16)*2); file->VarArray(vtx->TexCoords, sizeof(s16)*2);
file->Var32((u32*)&vtx->Clipped); file->Bool32(&vtx->Clipped);
file->VarArray(vtx->FinalPosition, sizeof(s32)*2); file->VarArray(vtx->FinalPosition, sizeof(s32)*2);
file->VarArray(vtx->FinalColor, sizeof(s32)*3); file->VarArray(vtx->FinalColor, sizeof(s32)*3);
@ -507,7 +507,7 @@ void DoSavestate(Savestate* file)
file->VarArray(vtx->Color, sizeof(s32)*3); file->VarArray(vtx->Color, sizeof(s32)*3);
file->VarArray(vtx->TexCoords, sizeof(s16)*2); file->VarArray(vtx->TexCoords, sizeof(s16)*2);
file->Var32((u32*)&vtx->Clipped); file->Bool32(&vtx->Clipped);
file->VarArray(vtx->FinalPosition, sizeof(s32)*2); file->VarArray(vtx->FinalPosition, sizeof(s32)*2);
file->VarArray(vtx->FinalColor, sizeof(s32)*3); file->VarArray(vtx->FinalColor, sizeof(s32)*3);
@ -545,17 +545,17 @@ void DoSavestate(Savestate* file)
file->VarArray(poly->FinalZ, sizeof(s32)*10); file->VarArray(poly->FinalZ, sizeof(s32)*10);
file->VarArray(poly->FinalW, sizeof(s32)*10); file->VarArray(poly->FinalW, sizeof(s32)*10);
file->Var32((u32*)&poly->WBuffer); file->Bool32(&poly->WBuffer);
file->Var32(&poly->Attr); file->Var32(&poly->Attr);
file->Var32(&poly->TexParam); file->Var32(&poly->TexParam);
file->Var32(&poly->TexPalette); file->Var32(&poly->TexPalette);
file->Var32((u32*)&poly->FacingView); file->Bool32(&poly->FacingView);
file->Var32((u32*)&poly->Translucent); file->Bool32(&poly->Translucent);
file->Var32((u32*)&poly->IsShadowMask); file->Bool32(&poly->IsShadowMask);
file->Var32((u32*)&poly->IsShadow); file->Bool32(&poly->IsShadow);
if (file->IsAtleastVersion(4, 1)) if (file->IsAtleastVersion(4, 1))
file->Var32((u32*)&poly->Type); file->Var32((u32*)&poly->Type);
@ -2528,13 +2528,19 @@ void VBlank()
void VCount215() void VCount215()
{ {
if (GPU::Renderer == 0) SoftRenderer::RenderFrame(); if (GPU::Renderer == 0) SoftRenderer::RenderFrame();
#ifdef OGLRENDERER_ENABLED
else GLRenderer::RenderFrame(); else GLRenderer::RenderFrame();
#endif
} }
u32* GetLine(int line) u32* GetLine(int line)
{ {
if (GPU::Renderer == 0) return SoftRenderer::GetLine(line); if (GPU::Renderer == 0) return SoftRenderer::GetLine(line);
#ifdef OGLRENDERER_ENABLED
else return GLRenderer::GetLine(line); else return GLRenderer::GetLine(line);
#else
return NULL;
#endif
} }

View File

@ -139,6 +139,7 @@ u32* GetLine(int line);
} }
#ifdef OGLRENDERER_ENABLED
namespace GLRenderer namespace GLRenderer
{ {
@ -154,6 +155,7 @@ u32* GetLine(int line);
void SetupAccelFrame(); void SetupAccelFrame();
} }
#endif
} }

View File

@ -775,7 +775,7 @@ bool DoSavestate(Savestate* file)
file->Var8(&WRAMCnt); file->Var8(&WRAMCnt);
file->Var32((u32*)&RunningGame); file->Bool32(&RunningGame);
if (!file->Saving) if (!file->Saving)
{ {
@ -1124,6 +1124,11 @@ void MicInputFrame(s16* data, int samples)
return SPI_TSC::MicInputFrame(data, samples); return SPI_TSC::MicInputFrame(data, samples);
} }
int ImportSRAM(u8* data, u32 length)
{
return NDSCart::ImportSRAM(data, length);
}
void Halt() void Halt()
{ {
@ -2996,6 +3001,7 @@ u32 ARM9IORead32(u32 addr)
case 0x04000130: return (KeyInput & 0xFFFF) | (KeyCnt << 16); case 0x04000130: return (KeyInput & 0xFFFF) | (KeyCnt << 16);
case 0x04000180: return IPCSync9; case 0x04000180: return IPCSync9;
case 0x04000184: return ARM9IORead16(addr);
case 0x040001A0: return NDSCart::SPICnt | (NDSCart::ReadSPIData() << 16); case 0x040001A0: return NDSCart::SPICnt | (NDSCart::ReadSPIData() << 16);
case 0x040001A4: return NDSCart::ROMCnt; case 0x040001A4: return NDSCart::ROMCnt;
@ -3373,10 +3379,11 @@ void ARM9IOWrite32(u32 addr, u32 val)
case 0x04000130: case 0x04000130:
KeyCnt = val >> 16; KeyCnt = val >> 16;
return; return;
case 0x04000180: case 0x04000180:
case 0x04000184:
ARM9IOWrite16(addr, val); ARM9IOWrite16(addr, val);
return; return;
case 0x04000188: case 0x04000188:
if (IPCFIFOCnt9 & 0x8000) if (IPCFIFOCnt9 & 0x8000)
{ {
@ -3635,6 +3642,7 @@ u32 ARM7IORead32(u32 addr)
case 0x04000138: return RTC::Read(); case 0x04000138: return RTC::Read();
case 0x04000180: return IPCSync7; case 0x04000180: return IPCSync7;
case 0x04000184: return ARM7IORead16(addr);
case 0x040001A0: return NDSCart::SPICnt | (NDSCart::ReadSPIData() << 16); case 0x040001A0: return NDSCart::SPICnt | (NDSCart::ReadSPIData() << 16);
case 0x040001A4: return NDSCart::ROMCnt; case 0x040001A4: return NDSCart::ROMCnt;
@ -3935,6 +3943,7 @@ void ARM7IOWrite32(u32 addr, u32 val)
case 0x04000138: RTC::Write(val & 0xFFFF, false); return; case 0x04000138: RTC::Write(val & 0xFFFF, false); return;
case 0x04000180: case 0x04000180:
case 0x04000184:
ARM7IOWrite16(addr, val); ARM7IOWrite16(addr, val);
return; return;
case 0x04000188: case 0x04000188:
@ -3979,6 +3988,11 @@ void ARM7IOWrite32(u32 addr, u32 val)
case 0x040001B0: *(u32*)&ROMSeed0[8] = val; return; case 0x040001B0: *(u32*)&ROMSeed0[8] = val; return;
case 0x040001B4: *(u32*)&ROMSeed1[8] = val; return; case 0x040001B4: *(u32*)&ROMSeed1[8] = val; return;
case 0x040001C0:
SPI::WriteCnt(val & 0xFFFF);
SPI::WriteData((val >> 16) & 0xFF);
return;
case 0x04000208: IME[1] = val & 0x1; UpdateIRQ(1); return; case 0x04000208: IME[1] = val & 0x1; UpdateIRQ(1); return;
case 0x04000210: IE[1] = val; UpdateIRQ(1); return; case 0x04000210: IE[1] = val; UpdateIRQ(1); return;
case 0x04000214: IF[1] &= ~val; UpdateIRQ(1); return; case 0x04000214: IF[1] &= ~val; UpdateIRQ(1); return;

View File

@ -212,6 +212,8 @@ void SetLidClosed(bool closed);
void MicInputFrame(s16* data, int samples); void MicInputFrame(s16* data, int samples);
int ImportSRAM(u8* data, u32 length);
void ScheduleEvent(u32 id, bool periodic, s32 delay, void (*func)(u32), u32 param); void ScheduleEvent(u32 id, bool periodic, s32 delay, void (*func)(u32), u32 param);
void CancelEvent(u32 id); void CancelEvent(u32 id);

View File

@ -1034,6 +1034,19 @@ void RelocateSave(const char* path, bool write)
NDSCart_SRAM::RelocateSave(path, write); NDSCart_SRAM::RelocateSave(path, write);
} }
int ImportSRAM(const u8* data, u32 length)
{
memcpy(NDSCart_SRAM::SRAM, data, std::min(length, NDSCart_SRAM::SRAMLength));
FILE* f = Platform::OpenFile(NDSCart_SRAM::SRAMPath, "wb");
if (f)
{
fwrite(NDSCart_SRAM::SRAM, NDSCart_SRAM::SRAMLength, 1, f);
fclose(f);
}
return length - NDSCart_SRAM::SRAMLength;
}
void ResetCart() void ResetCart()
{ {
// CHECKME: what if there is a transfer in progress? // CHECKME: what if there is a transfer in progress?

View File

@ -48,6 +48,8 @@ void DecryptSecureArea(u8* out);
bool LoadROM(const char* path, const char* sram, bool direct); bool LoadROM(const char* path, const char* sram, bool direct);
void RelocateSave(const char* path, bool write); void RelocateSave(const char* path, bool write);
int ImportSRAM(const u8* data, u32 length);
void ResetCart(); void ResetCart();
void WriteROMCnt(u32 val); void WriteROMCnt(u32 val);

View File

@ -16,6 +16,9 @@
with melonDS. If not, see http://www.gnu.org/licenses/. with melonDS. If not, see http://www.gnu.org/licenses/.
*/ */
// Required by MinGW to enable localtime_r in time.h
#define _POSIX_THREAD_SAFE_FUNCTIONS
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
@ -125,31 +128,29 @@ void ByteIn(u8 val)
case 0x20: case 0x20:
{ {
time_t timestamp; time_t timestamp = time(NULL);
struct tm* timedata; struct tm timedata;
time(&timestamp); localtime_r(&timestamp, &timedata);
timedata = localtime(&timestamp);
Output[0] = BCD(timedata->tm_year - 100); Output[0] = BCD(timedata.tm_year - 100);
Output[1] = BCD(timedata->tm_mon + 1); Output[1] = BCD(timedata.tm_mon + 1);
Output[2] = BCD(timedata->tm_mday); Output[2] = BCD(timedata.tm_mday);
Output[3] = BCD(timedata->tm_wday); Output[3] = BCD(timedata.tm_wday);
Output[4] = BCD(timedata->tm_hour); Output[4] = BCD(timedata.tm_hour);
Output[5] = BCD(timedata->tm_min); Output[5] = BCD(timedata.tm_min);
Output[6] = BCD(timedata->tm_sec); Output[6] = BCD(timedata.tm_sec);
} }
break; break;
case 0x60: case 0x60:
{ {
time_t timestamp; time_t timestamp = time(NULL);
struct tm* timedata; struct tm timedata;
time(&timestamp); localtime_r(&timestamp, &timedata);
timedata = localtime(&timestamp);
Output[0] = BCD(timedata->tm_hour); Output[0] = BCD(timedata.tm_hour);
Output[1] = BCD(timedata->tm_min); Output[1] = BCD(timedata.tm_min);
Output[2] = BCD(timedata->tm_sec); Output[2] = BCD(timedata.tm_sec);
} }
break; break;

View File

@ -261,6 +261,22 @@ void Savestate::Var64(u64* var)
} }
} }
void Savestate::Bool32(bool* var)
{
// for compability
if (Saving)
{
u32 val = *var;
Var32(&val);
}
else
{
u32 val;
Var32(&val);
*var = val != 0;
}
}
void Savestate::VarArray(void* data, u32 len) void Savestate::VarArray(void* data, u32 len)
{ {
if (Error) return; if (Error) return;

View File

@ -46,6 +46,8 @@ public:
void Var32(u32* var); void Var32(u32* var);
void Var64(u64* var); void Var64(u64* var);
void Bool32(bool* var);
void VarArray(void* data, u32 len); void VarArray(void* data, u32 len);
bool IsAtleastVersion(u32 major, u32 minor) bool IsAtleastVersion(u32 major, u32 minor)

View File

@ -237,7 +237,7 @@ void DoSavestate(Savestate* file)
file->Var64(&USCounter); file->Var64(&USCounter);
file->Var64(&USCompare); file->Var64(&USCompare);
file->Var32((u32*)&BlockBeaconIRQ14); file->Bool32(&BlockBeaconIRQ14);
file->Var32(&ComStatus); file->Var32(&ComStatus);
file->Var32(&TXCurSlot); file->Var32(&TXCurSlot);

View File

@ -1631,7 +1631,7 @@ void ARM64XEmitter::ASR(ARM64Reg Rd, ARM64Reg Rm, int shift)
int bits = Is64Bit(Rd) ? 64 : 32; int bits = Is64Bit(Rd) ? 64 : 32;
SBFM(Rd, Rm, shift, bits - 1); SBFM(Rd, Rm, shift, bits - 1);
} }
void ARM64XEmitter::ROR_(ARM64Reg Rd, ARM64Reg Rm, int shift) void ARM64XEmitter::ROR(ARM64Reg Rd, ARM64Reg Rm, int shift)
{ {
EXTR(Rd, Rm, Rm, shift); EXTR(Rd, Rm, Rm, shift);
} }

View File

@ -727,7 +727,7 @@ public:
void LSR(ARM64Reg Rd, ARM64Reg Rm, int shift); void LSR(ARM64Reg Rd, ARM64Reg Rm, int shift);
void LSL(ARM64Reg Rd, ARM64Reg Rm, int shift); void LSL(ARM64Reg Rd, ARM64Reg Rm, int shift);
void ASR(ARM64Reg Rd, ARM64Reg Rm, int shift); void ASR(ARM64Reg Rd, ARM64Reg Rm, int shift);
void ROR_(ARM64Reg Rd, ARM64Reg Rm, int shift); void ROR(ARM64Reg Rd, ARM64Reg Rm, int shift);
// Logical (immediate) // Logical (immediate)
void AND(ARM64Reg Rd, ARM64Reg Rn, u32 immr, u32 imms, bool invert = false); void AND(ARM64Reg Rd, ARM64Reg Rn, u32 immr, u32 imms, bool invert = false);

View File

@ -1214,7 +1214,7 @@ void XEmitter::ROL(int bits, const OpArg& dest, const OpArg& shift)
{ {
WriteShift(bits, dest, shift, 0); WriteShift(bits, dest, shift, 0);
} }
void XEmitter::ROR_(int bits, const OpArg& dest, const OpArg& shift) void XEmitter::ROR(int bits, const OpArg& dest, const OpArg& shift)
{ {
WriteShift(bits, dest, shift, 1); WriteShift(bits, dest, shift, 1);
} }

View File

@ -489,7 +489,7 @@ public:
// Shift // Shift
void ROL(int bits, const OpArg& dest, const OpArg& shift); void ROL(int bits, const OpArg& dest, const OpArg& shift);
void ROR_(int bits, const OpArg& dest, const OpArg& shift); void ROR(int bits, const OpArg& dest, const OpArg& shift);
void RCL(int bits, const OpArg& dest, const OpArg& shift); void RCL(int bits, const OpArg& dest, const OpArg& shift);
void RCR(int bits, const OpArg& dest, const OpArg& shift); void RCR(int bits, const OpArg& dest, const OpArg& shift);
void SHL(int bits, const OpArg& dest, const OpArg& shift); void SHL(int bits, const OpArg& dest, const OpArg& shift);

View File

@ -100,6 +100,9 @@ bool SaveState(const char* filename);
// undo the latest savestate load // undo the latest savestate load
void UndoStateLoad(); void UndoStateLoad();
// imports savedata from an external file. Returns the difference between the filesize and the SRAM size
int ImportSRAM(const char* filename);
// enable or disable cheats // enable or disable cheats
void EnableCheats(bool enable); void EnableCheats(bool enable);

View File

@ -588,6 +588,21 @@ void UndoStateLoad()
} }
} }
int ImportSRAM(const char* filename)
{
FILE* file = fopen(filename, "rb");
fseek(file, 0, SEEK_END);
u32 size = ftell(file);
u8* importData = new u8[size];
rewind(file);
fread(importData, size, 1, file);
fclose(file);
int diff = NDS::ImportSRAM(importData, size);
delete[] importData;
return diff;
}
void EnableCheats(bool enable) void EnableCheats(bool enable)
{ {
CheatsOn = enable; CheatsOn = enable;

View File

@ -98,7 +98,9 @@ int GetEventKeyVal(QKeyEvent* event)
void KeyPress(QKeyEvent* event) void KeyPress(QKeyEvent* event)
{ {
int keyHK = GetEventKeyVal(event); int keyHK = GetEventKeyVal(event);
int keyKP = keyHK & ~event->modifiers(); int keyKP = keyHK;
if (event->modifiers() != Qt::KeypadModifier)
keyKP &= ~event->modifiers();
for (int i = 0; i < 12; i++) for (int i = 0; i < 12; i++)
if (keyKP == Config::KeyMapping[i]) if (keyKP == Config::KeyMapping[i])
@ -112,7 +114,9 @@ void KeyPress(QKeyEvent* event)
void KeyRelease(QKeyEvent* event) void KeyRelease(QKeyEvent* event)
{ {
int keyHK = GetEventKeyVal(event); int keyHK = GetEventKeyVal(event);
int keyKP = keyHK & ~event->modifiers(); int keyKP = keyHK;
if (event->modifiers() != Qt::KeypadModifier)
keyKP &= ~event->modifiers();
for (int i = 0; i < 12; i++) for (int i = 0; i < 12; i++)
if (keyKP == Config::KeyMapping[i]) if (keyKP == Config::KeyMapping[i])

View File

@ -54,6 +54,7 @@ const int hk_general[] =
HK_Reset, HK_Reset,
HK_FastForward, HK_FastForward,
HK_FastForwardToggle, HK_FastForwardToggle,
HK_FullscreenToggle,
HK_Lid, HK_Lid,
HK_Mic, HK_Mic,
}; };
@ -64,6 +65,7 @@ const char* hk_general_labels[] =
"Reset", "Reset",
"Fast forward", "Fast forward",
"Toggle FPS limit", "Toggle FPS limit",
"Toggle Fullscreen",
"Close/open lid", "Close/open lid",
"Microphone", "Microphone",
}; };
@ -86,7 +88,7 @@ InputConfigDialog::InputConfigDialog(QWidget* parent) : QDialog(parent), ui(new
addonsJoyMap[i] = Config::HKJoyMapping[hk_addons[i]]; addonsJoyMap[i] = Config::HKJoyMapping[hk_addons[i]];
} }
for (int i = 0; i < 6; i++) for (int i = 0; i < 7; i++)
{ {
hkGeneralKeyMap[i] = Config::HKKeyMapping[hk_general[i]]; hkGeneralKeyMap[i] = Config::HKKeyMapping[hk_general[i]];
hkGeneralJoyMap[i] = Config::HKJoyMapping[hk_general[i]]; hkGeneralJoyMap[i] = Config::HKJoyMapping[hk_general[i]];
@ -94,7 +96,7 @@ InputConfigDialog::InputConfigDialog(QWidget* parent) : QDialog(parent), ui(new
populatePage(ui->tabInput, 12, dskeylabels, keypadKeyMap, keypadJoyMap); populatePage(ui->tabInput, 12, dskeylabels, keypadKeyMap, keypadJoyMap);
populatePage(ui->tabAddons, 2, hk_addons_labels, addonsKeyMap, addonsJoyMap); populatePage(ui->tabAddons, 2, hk_addons_labels, addonsKeyMap, addonsJoyMap);
populatePage(ui->tabHotkeysGeneral, 6, hk_general_labels, hkGeneralKeyMap, hkGeneralJoyMap); populatePage(ui->tabHotkeysGeneral, 7, hk_general_labels, hkGeneralKeyMap, hkGeneralJoyMap);
int njoy = SDL_NumJoysticks(); int njoy = SDL_NumJoysticks();
if (njoy > 0) if (njoy > 0)
@ -177,7 +179,7 @@ void InputConfigDialog::on_InputConfigDialog_accepted()
Config::HKJoyMapping[hk_addons[i]] = addonsJoyMap[i]; Config::HKJoyMapping[hk_addons[i]] = addonsJoyMap[i];
} }
for (int i = 0; i < 6; i++) for (int i = 0; i < 7; i++)
{ {
Config::HKKeyMapping[hk_general[i]] = hkGeneralKeyMap[i]; Config::HKKeyMapping[hk_general[i]] = hkGeneralKeyMap[i];
Config::HKJoyMapping[hk_general[i]] = hkGeneralJoyMap[i]; Config::HKJoyMapping[hk_general[i]] = hkGeneralJoyMap[i];
@ -226,7 +228,7 @@ void KeyMapButton::keyPressEvent(QKeyEvent* event)
{ {
if (!isChecked()) return QPushButton::keyPressEvent(event); if (!isChecked()) return QPushButton::keyPressEvent(event);
printf("KEY PRESSED = %08X %08X | %08X %08X %08X\n", event->key(), event->modifiers(), event->nativeVirtualKey(), event->nativeModifiers(), event->nativeScanCode()); printf("KEY PRESSED = %08X %08X | %08X %08X %08X\n", event->key(), (int)event->modifiers(), event->nativeVirtualKey(), event->nativeModifiers(), event->nativeScanCode());
int key = event->key(); int key = event->key();
int mod = event->modifiers(); int mod = event->modifiers();

View File

@ -64,7 +64,7 @@ private:
int keypadKeyMap[12], keypadJoyMap[12]; int keypadKeyMap[12], keypadJoyMap[12];
int addonsKeyMap[2], addonsJoyMap[2]; int addonsKeyMap[2], addonsJoyMap[2];
int hkGeneralKeyMap[6], hkGeneralJoyMap[6]; int hkGeneralKeyMap[7], hkGeneralJoyMap[7];
}; };

View File

@ -110,6 +110,7 @@ ConfigEntry PlatformConfigFile[] =
{"HKKey_Reset", 0, &HKKeyMapping[HK_Reset], -1, NULL, 0}, {"HKKey_Reset", 0, &HKKeyMapping[HK_Reset], -1, NULL, 0},
{"HKKey_FastForward", 0, &HKKeyMapping[HK_FastForward], -1, NULL, 0}, {"HKKey_FastForward", 0, &HKKeyMapping[HK_FastForward], -1, NULL, 0},
{"HKKey_FastForwardToggle", 0, &HKKeyMapping[HK_FastForwardToggle], -1, NULL, 0}, {"HKKey_FastForwardToggle", 0, &HKKeyMapping[HK_FastForwardToggle], -1, NULL, 0},
{"HKKey_FullscreenToggle", 0, &HKKeyMapping[HK_FullscreenToggle], -1, NULL, 0},
{"HKKey_SolarSensorDecrease", 0, &HKKeyMapping[HK_SolarSensorDecrease], -1, NULL, 0}, {"HKKey_SolarSensorDecrease", 0, &HKKeyMapping[HK_SolarSensorDecrease], -1, NULL, 0},
{"HKKey_SolarSensorIncrease", 0, &HKKeyMapping[HK_SolarSensorIncrease], -1, NULL, 0}, {"HKKey_SolarSensorIncrease", 0, &HKKeyMapping[HK_SolarSensorIncrease], -1, NULL, 0},
@ -119,6 +120,7 @@ ConfigEntry PlatformConfigFile[] =
{"HKJoy_Reset", 0, &HKJoyMapping[HK_Reset], -1, NULL, 0}, {"HKJoy_Reset", 0, &HKJoyMapping[HK_Reset], -1, NULL, 0},
{"HKJoy_FastForward", 0, &HKJoyMapping[HK_FastForward], -1, NULL, 0}, {"HKJoy_FastForward", 0, &HKJoyMapping[HK_FastForward], -1, NULL, 0},
{"HKJoy_FastForwardToggle", 0, &HKJoyMapping[HK_FastForwardToggle], -1, NULL, 0}, {"HKJoy_FastForwardToggle", 0, &HKJoyMapping[HK_FastForwardToggle], -1, NULL, 0},
{"HKJoy_FastForwardToggle", 0, &HKJoyMapping[HK_FullscreenToggle], -1, NULL, 0},
{"HKJoy_SolarSensorDecrease", 0, &HKJoyMapping[HK_SolarSensorDecrease], -1, NULL, 0}, {"HKJoy_SolarSensorDecrease", 0, &HKJoyMapping[HK_SolarSensorDecrease], -1, NULL, 0},
{"HKJoy_SolarSensorIncrease", 0, &HKJoyMapping[HK_SolarSensorIncrease], -1, NULL, 0}, {"HKJoy_SolarSensorIncrease", 0, &HKJoyMapping[HK_SolarSensorIncrease], -1, NULL, 0},

View File

@ -29,6 +29,7 @@ enum
HK_Reset, HK_Reset,
HK_FastForward, HK_FastForward,
HK_FastForwardToggle, HK_FastForwardToggle,
HK_FullscreenToggle,
HK_SolarSensorDecrease, HK_SolarSensorDecrease,
HK_SolarSensorIncrease, HK_SolarSensorIncrease,
HK_MAX HK_MAX

View File

@ -50,6 +50,10 @@ VideoSettingsDialog::VideoSettingsDialog(QWidget* parent) : QDialog(parent), ui(
connect(grp3DRenderer, SIGNAL(buttonClicked(int)), this, SLOT(onChange3DRenderer(int))); connect(grp3DRenderer, SIGNAL(buttonClicked(int)), this, SLOT(onChange3DRenderer(int)));
grp3DRenderer->button(Config::_3DRenderer)->setChecked(true); grp3DRenderer->button(Config::_3DRenderer)->setChecked(true);
#ifndef OGLRENDERER_ENABLED
ui->rb3DOpenGL->setEnabled(false);
#endif
ui->cbGLDisplay->setChecked(Config::ScreenUseGL != 0); ui->cbGLDisplay->setChecked(Config::ScreenUseGL != 0);
ui->cbVSync->setChecked(Config::ScreenVSync != 0); ui->cbVSync->setChecked(Config::ScreenVSync != 0);

View File

@ -49,7 +49,9 @@
#include "NDS.h" #include "NDS.h"
#include "GBACart.h" #include "GBACart.h"
#ifdef OGLRENDERER_ENABLED
#include "OpenGLSupport.h" #include "OpenGLSupport.h"
#endif
#include "GPU.h" #include "GPU.h"
#include "SPU.h" #include "SPU.h"
#include "Wifi.h" #include "Wifi.h"
@ -113,7 +115,6 @@ void audioCallback(void* data, Uint8* stream, int len)
if (num_in < len_in-margin) if (num_in < len_in-margin)
{ {
int last = num_in-1; int last = num_in-1;
if (last < 0) last = 0;
for (int i = num_in; i < len_in-margin; i++) for (int i = num_in; i < len_in-margin; i++)
((u32*)buf_in)[i] = ((u32*)buf_in)[last]; ((u32*)buf_in)[i] = ((u32*)buf_in)[last];
@ -266,6 +267,7 @@ EmuThread::EmuThread(QObject* parent) : QThread(parent)
connect(this, SIGNAL(windowEmuPause()), mainWindow->actPause, SLOT(trigger())); connect(this, SIGNAL(windowEmuPause()), mainWindow->actPause, SLOT(trigger()));
connect(this, SIGNAL(windowEmuReset()), mainWindow->actReset, SLOT(trigger())); connect(this, SIGNAL(windowEmuReset()), mainWindow->actReset, SLOT(trigger()));
connect(this, SIGNAL(screenLayoutChange()), mainWindow->panel, SLOT(onScreenLayoutChanged())); connect(this, SIGNAL(screenLayoutChange()), mainWindow->panel, SLOT(onScreenLayoutChanged()));
connect(this, SIGNAL(windowFullscreenToggle()), mainWindow, SLOT(onFullscreenToggled()));
if (mainWindow->hasOGL) initOpenGL(); if (mainWindow->hasOGL) initOpenGL();
} }
@ -335,13 +337,17 @@ void EmuThread::run()
videoSettings.Soft_Threaded = Config::Threaded3D != 0; videoSettings.Soft_Threaded = Config::Threaded3D != 0;
videoSettings.GL_ScaleFactor = Config::GL_ScaleFactor; videoSettings.GL_ScaleFactor = Config::GL_ScaleFactor;
#ifdef OGLRENDERER_ENABLED
if (hasOGL) if (hasOGL)
{ {
oglContext->makeCurrent(oglSurface); oglContext->makeCurrent(oglSurface);
videoRenderer = OpenGL::Init() ? Config::_3DRenderer : 0; videoRenderer = OpenGL::Init() ? Config::_3DRenderer : 0;
} }
else else
#endif
{
videoRenderer = 0; videoRenderer = 0;
}
GPU::InitRenderer(videoRenderer); GPU::InitRenderer(videoRenderer);
GPU::SetRenderSettings(videoRenderer, videoSettings); GPU::SetRenderSettings(videoRenderer, videoSettings);
@ -365,6 +371,8 @@ void EmuThread::run()
if (Input::HotkeyPressed(HK_Pause)) emit windowEmuPause(); if (Input::HotkeyPressed(HK_Pause)) emit windowEmuPause();
if (Input::HotkeyPressed(HK_Reset)) emit windowEmuReset(); if (Input::HotkeyPressed(HK_Reset)) emit windowEmuReset();
if (Input::HotkeyPressed(HK_FullscreenToggle)) emit windowFullscreenToggle();
if (GBACart::CartInserted && GBACart::HasSolarSensor) if (GBACart::CartInserted && GBACart::HasSolarSensor)
{ {
if (Input::HotkeyPressed(HK_SolarSensorDecrease)) if (Input::HotkeyPressed(HK_SolarSensorDecrease))
@ -393,14 +401,18 @@ void EmuThread::run()
if (hasOGL != mainWindow->hasOGL) if (hasOGL != mainWindow->hasOGL)
{ {
hasOGL = mainWindow->hasOGL; hasOGL = mainWindow->hasOGL;
#ifdef OGLRENDERER_ENABLED
if (hasOGL) if (hasOGL)
{ {
oglContext->makeCurrent(oglSurface); oglContext->makeCurrent(oglSurface);
videoRenderer = OpenGL::Init() ? Config::_3DRenderer : 0; videoRenderer = OpenGL::Init() ? Config::_3DRenderer : 0;
} }
else else
#endif
{
videoRenderer = 0; videoRenderer = 0;
} }
}
else else
videoRenderer = hasOGL ? Config::_3DRenderer : 0; videoRenderer = hasOGL ? Config::_3DRenderer : 0;
@ -920,12 +932,14 @@ void ScreenPanelGL::paintGL()
int frontbuf = GPU::FrontBuffer; int frontbuf = GPU::FrontBuffer;
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
#ifdef OGLRENDERER_ENABLED
if (GPU::Renderer != 0) if (GPU::Renderer != 0)
{ {
// hardware-accelerated render // hardware-accelerated render
GPU::GLCompositor::BindOutputTexture(); GPU::GLCompositor::BindOutputTexture();
} }
else else
#endif
{ {
// regular render // regular render
glBindTexture(GL_TEXTURE_2D, screenTexture); glBindTexture(GL_TEXTURE_2D, screenTexture);
@ -1049,6 +1063,9 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent)
actUndoStateLoad->setShortcut(QKeySequence(Qt::Key_F12)); actUndoStateLoad->setShortcut(QKeySequence(Qt::Key_F12));
connect(actUndoStateLoad, &QAction::triggered, this, &MainWindow::onUndoStateLoad); connect(actUndoStateLoad, &QAction::triggered, this, &MainWindow::onUndoStateLoad);
actImportSavefile = menu->addAction("Import savefile");
connect(actImportSavefile, &QAction::triggered, this, &MainWindow::onImportSavefile);
menu->addSeparator(); menu->addSeparator();
actQuit = menu->addAction("Quit"); actQuit = menu->addAction("Quit");
@ -1217,6 +1234,7 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent)
actLoadState[i]->setEnabled(false); actLoadState[i]->setEnabled(false);
} }
actUndoStateLoad->setEnabled(false); actUndoStateLoad->setEnabled(false);
actImportSavefile->setEnabled(false);
actPause->setEnabled(false); actPause->setEnabled(false);
actReset->setEnabled(false); actReset->setEnabled(false);
@ -1615,6 +1633,41 @@ void MainWindow::onUndoStateLoad()
OSD::AddMessage(0, "State load undone"); OSD::AddMessage(0, "State load undone");
} }
void MainWindow::onImportSavefile()
{
if (!RunningSomething) return;
emuThread->emuPause();
QString path = QFileDialog::getOpenFileName(this,
"Select savefile",
Config::LastROMFolder,
"Savefiles (*.sav *.bin *.dsv);;Any file (*.*)");
if (!path.isEmpty())
{
if (QMessageBox::warning(this,
"Emulation will be reset and data overwritten",
"The emulation will be reset and the current savefile overwritten.",
QMessageBox::Ok, QMessageBox::Cancel) == QMessageBox::Ok)
{
int res = Frontend::Reset();
if (res != Frontend::Load_OK)
{
QMessageBox::critical(this, "melonDS", "Reset failed\n" + loadErrorStr(res));
}
else
{
int diff = Frontend::ImportSRAM(path.toStdString().c_str());
if (diff > 0)
OSD::AddMessage(0, "Trimmed savefile");
else if (diff < 0)
OSD::AddMessage(0, "Savefile shorter than SRAM");
}
}
}
emuThread->emuUnpause();
}
void MainWindow::onQuit() void MainWindow::onQuit()
{ {
QApplication::quit(); QApplication::quit();
@ -1878,6 +1931,20 @@ void MainWindow::onTitleUpdate(QString title)
setWindowTitle(title); setWindowTitle(title);
} }
void MainWindow::onFullscreenToggled()
{
if (!mainWindow->isFullScreen())
{
mainWindow->showFullScreen();
mainWindow->menuBar()->hide();
}
else
{
mainWindow->showNormal();
mainWindow->menuBar()->show();
}
}
void MainWindow::onEmuStart() void MainWindow::onEmuStart()
{ {
// TODO: make savestates work in DSi mode!! // TODO: make savestates work in DSi mode!!
@ -1906,6 +1973,7 @@ void MainWindow::onEmuStart()
actPause->setChecked(false); actPause->setChecked(false);
actReset->setEnabled(true); actReset->setEnabled(true);
actStop->setEnabled(true); actStop->setEnabled(true);
actImportSavefile->setEnabled(true);
actSetupCheats->setEnabled(true); actSetupCheats->setEnabled(true);
} }
@ -1920,6 +1988,7 @@ void MainWindow::onEmuStop()
actLoadState[i]->setEnabled(false); actLoadState[i]->setEnabled(false);
} }
actUndoStateLoad->setEnabled(false); actUndoStateLoad->setEnabled(false);
actImportSavefile->setEnabled(false);
actPause->setEnabled(false); actPause->setEnabled(false);
actReset->setEnabled(false); actReset->setEnabled(false);

View File

@ -70,6 +70,8 @@ signals:
void screenLayoutChange(); void screenLayoutChange();
void windowFullscreenToggle();
private: private:
volatile int EmuStatus; volatile int EmuStatus;
int PrevEmuStatus; int PrevEmuStatus;
@ -193,6 +195,7 @@ private slots:
void onSaveState(); void onSaveState();
void onLoadState(); void onLoadState();
void onUndoStateLoad(); void onUndoStateLoad();
void onImportSavefile();
void onQuit(); void onQuit();
void onPause(bool checked); void onPause(bool checked);
@ -230,6 +233,8 @@ private slots:
void onUpdateVideoSettings(bool glchange); void onUpdateVideoSettings(bool glchange);
void onFullscreenToggled();
private: private:
void createScreenPanel(); void createScreenPanel();
@ -243,6 +248,7 @@ public:
QAction* actSaveState[9]; QAction* actSaveState[9];
QAction* actLoadState[9]; QAction* actLoadState[9];
QAction* actUndoStateLoad; QAction* actUndoStateLoad;
QAction* actImportSavefile;
QAction* actQuit; QAction* actQuit;
QAction* actPause; QAction* actPause;

View File

@ -19,13 +19,15 @@
#ifndef TYPES_H #ifndef TYPES_H
#define TYPES_H #define TYPES_H
typedef unsigned char u8; #include <stdint.h>
typedef unsigned short u16;
typedef unsigned int u32; typedef uint8_t u8;
typedef unsigned long long int u64; typedef uint16_t u16;
typedef signed char s8; typedef uint32_t u32;
typedef signed short s16; typedef uint64_t u64;
typedef signed int s32; typedef int8_t s8;
typedef signed long long int s64; typedef int16_t s16;
typedef int32_t s32;
typedef int64_t s64;
#endif // TYPES_H #endif // TYPES_H