Marcus Aseth
Utente Attivo
- Messaggi
- 407
- Reazioni
- 138
- Punteggio
- 60
@DispatchCode thanks, ho gia avuto abbastanza problemi cercando di capire come dovevo intrerpretare l'istruzione in base all' endianness (ARM può operare sia in small endian che big endian da quel che ho capito) perchè non mi era chiaro neppure che rappresentazione fosse usata nel grafico nella prima immagine, un pò deludente il fatto che ho finito per usare un disassembler gia funzionante come reference e modificato il modo in cui interpretavo istruzioni fino a che lo stesso input non mi ha dato l'output in quel sito lì, percui ho deciso che valeva la pena spendere un pò di tempo in più ed assicurarmi di capire davvero cosa sta succedendo, visto che riesco a ragionare molto meglio con tutte le info a portata di mano.
Devo ancora aggiungere il display di "CPSR" (registro con tutte le flag dello stato corrente del processore) ed in alto a destra magari in futuro una stack di esecuzione delle istruzioni.
@driverfury Windows, Direct3D, Direct2D, DirectWrite, sotto la classe base dalla quale derivano le mie finestre, tutta boilerplate:
Devo ancora aggiungere il display di "CPSR" (registro con tutte le flag dello stato corrente del processore) ed in alto a destra magari in futuro una stack di esecuzione delle istruzioni.
@driverfury Windows, Direct3D, Direct2D, DirectWrite, sotto la classe base dalla quale derivano le mie finestre, tutta boilerplate:
C++:
#include "GBAEmulator_PCH.h"
#include "D2DWindowBase.h"
#include "GBAEmulator.h"
D2DWindowBase::D2DWindowBase(LONG width, LONG height, HINSTANCE hInstance, GBAEmulator* emuInstance)
: m_isValid{ false }
, m_winWidth{ width }
, m_winHeight{ height }
, m_background(0.047f, 0.062f, 0.129f, 1.f)
, m_hInstance{ hInstance }
, m_emu{ emuInstance }
, m_hwnd{ nullptr }
, m_device{ nullptr }
, m_context{ nullptr }
, m_swapChain{ nullptr }
, m_backBuffer{ nullptr }
{
}
D2DWindowBase::~D2DWindowBase()
{
m_isValid = false;
if (m_DWriteFactory) {
m_DWriteFactory->Release();
}
if (m_device) {
m_device->Release();
}
if (m_context) {
m_context->Release();
}
if (m_swapChain) {
m_swapChain->Release();
}
if (m_backBuffer) {
m_backBuffer->Release();
}
}
bool D2DWindowBase::IsValid() const
{
return m_isValid;
}
LONG D2DWindowBase::Width() const
{
return m_winWidth;
}
LONG D2DWindowBase::Height() const
{
return m_winHeight;
}
HWND D2DWindowBase::Hwnd() const
{
return m_hwnd;
}
//This method shouldn't rely on the m_emu variable because
//not all emu member variables are ensured to be initialized at this point.
bool D2DWindowBase::InitWindow(const std::string& windowCaptionText, const WNDCLASSEX& wndClass, DWORD windowStyle, bool bMenu)
{
//Register Class
//The check below prevents trying to register a previously registered class again
WNDCLASSEX temp{};
if (!GetClassInfoEx(m_hInstance, wndClass.lpszClassName, &temp)) {
if (!RegisterClassEx(&wndClass)) {
MessageBox(nullptr, "Failed to register window class", "Error", MB_OK);
return false;
}
}
//Create Window
DWORD windowExStyle = 0;
RECT client{ 0, 0, m_winWidth, m_winHeight };
SetThreadDpiAwarenessContext(DPI_AWARENESS_CONTEXT_SYSTEM_AWARE);
UINT dpi = GetDpiForSystem();
AdjustWindowRectExForDpi(&client, windowStyle, bMenu, windowExStyle, dpi);
m_winWidth = client.right - client.left;
m_winHeight = client.bottom - client.top;
int x = GetSystemMetrics(SM_CXSCREEN);
int y = GetSystemMetrics(SM_CYSCREEN);
x = x / 2 - m_winWidth / 2;
y = y / 2 - m_winHeight / 2;
m_hwnd = CreateWindowEx(windowExStyle,
wndClass.lpszClassName,
windowCaptionText.c_str(),
windowStyle,
x, y, m_winWidth, m_winHeight,
nullptr,
nullptr,
m_hInstance,
m_emu);
if (!m_hwnd) {
MessageBox(nullptr, "Failed to create window", "Error", MB_OK);
return false;
}
//Init Direct3D
HRESULT hr;
ID3D11Device* d3d_device;
ID3D11DeviceContext* d3d_context;
UINT creationFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
const UINT featureCount = 7;
D3D_FEATURE_LEVEL featureLevels[featureCount] = {
D3D_FEATURE_LEVEL_11_1,
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_10_1,
D3D_FEATURE_LEVEL_10_0,
D3D_FEATURE_LEVEL_9_3,
D3D_FEATURE_LEVEL_9_2,
D3D_FEATURE_LEVEL_9_1
};
hr = D3D11CreateDevice(nullptr,
D3D_DRIVER_TYPE_HARDWARE,
nullptr,
creationFlags,
featureLevels,
featureCount,
D3D11_SDK_VERSION,
&d3d_device,
nullptr,
&d3d_context);
if (FAILED(hr)) {
MessageBox(nullptr, "Failed to initialize D3D", "Error", MB_OK);
return false;
}
//Init Direct2D
IDXGIDevice* dxgiDevice;
d3d_device->QueryInterface(&dxgiDevice);
D2D1_CREATION_PROPERTIES D2D1DeviceDesc{};
D2D1DeviceDesc.threadingMode = D2D1_THREADING_MODE_SINGLE_THREADED;
D2D1DeviceDesc.debugLevel = D2D1_DEBUG_LEVEL_INFORMATION;
hr = D2D1CreateDevice(dxgiDevice, D2D1DeviceDesc, &m_device);
if (FAILED(hr)) {
MessageBox(nullptr, "Failed to create D2D1 Device", "Error", MB_OK);
return false;
}
hr = m_device->CreateDeviceContext(D2D1_DEVICE_CONTEXT_OPTIONS_NONE, &m_context);
if (FAILED(hr)) {
MessageBox(nullptr, "Failed to create D2D1 Context", "Error", MB_OK);
return false;
}
//Create Swap Chain
IDXGIAdapter* dxgiAdapter = nullptr;
hr = dxgiDevice->GetAdapter(&dxgiAdapter);
if (FAILED(hr)) {
MessageBox(nullptr, "Failed to get Adapter", "Error", MB_OK);
return false;
}
IDXGIFactory2* dxgiFactory = nullptr;
hr = dxgiAdapter->GetParent(IID_PPV_ARGS(&dxgiFactory));
if (FAILED(hr)) {
MessageBox(nullptr, "Failed to get dxgiFactory", "Error", MB_OK);
return false;
}
//swap chain desc
DXGI_SWAP_CHAIN_DESC1 swapChainDesc{};
swapChainDesc.Width = m_winWidth;
swapChainDesc.Height = m_winHeight;
swapChainDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
swapChainDesc.Scaling = DXGI_SCALING_NONE;
swapChainDesc.SampleDesc.Count = 1;
swapChainDesc.SampleDesc.Quality = 0;
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_IGNORE;
swapChainDesc.BufferCount = 2;
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
dxgiFactory->CreateSwapChainForHwnd(d3d_device, m_hwnd, &swapChainDesc, nullptr, nullptr, &m_swapChain);
if (FAILED(hr)) {
MessageBox(nullptr, "Failed to create Swap Chain", "Error", MB_OK);
return false;
}
//Create Back Buffer
D2D1_BITMAP_PROPERTIES1 backBufferDesc{};
backBufferDesc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
backBufferDesc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_IGNORE;
backBufferDesc.dpiX = static_cast<FLOAT>(dpi);
backBufferDesc.dpiY = static_cast<FLOAT>(dpi);
backBufferDesc.bitmapOptions = D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW;
IDXGISurface* dxgiBackBuffer;
m_swapChain->GetBuffer(0, IID_PPV_ARGS(&dxgiBackBuffer));
hr = m_context->CreateBitmapFromDxgiSurface(dxgiBackBuffer, &backBufferDesc, &m_backBuffer);
if (FAILED(hr)) {
MessageBox(nullptr, "Failed to create back buffer", "Error", MB_OK);
return false;
}
m_context->SetTarget(m_backBuffer);
//Init DirectWrite
//Create DWrite Factory
if (!m_DWriteFactory) {
hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory), reinterpret_cast<IUnknown**>(&m_DWriteFactory));
if (FAILED(hr)) {
MessageBox(nullptr, "Failed to create DWrite Factory", "Error", MB_OK);
return false;
}
}
d3d_device->Release();
d3d_context->Release();
dxgiDevice->Release();
dxgiAdapter->Release();
dxgiFactory->Release();
dxgiBackBuffer->Release();
return true;
}
Ultima modifica: