isle-portable/miniwin/src/d3drm/d3drm.cpp
Joshua Peisach 1ff768935e
3DS Port (#450)
* [WIP] 3ds port

Recommit of everything after the 2d renderer merge

* VERY AWESOME FEATURE FRFR

* Stopped CPU suicide and app crashing for now

* put in Texture3DS function thing

* Fix clear color

* Implement 2D rendering via Citro3D

* Set 3dsx smdh metadata

* Render world content, sort of

* Push mesh dynamically

* Remove Citro3D init hacks

* Clean up Citro3D implementation

* Try to upload meshes and convert matricies

* Fix 3D rendering

* Apply optimizations

* Implement lighting

* Set 3dsx smdh metadata

* Revert "Apply optimizations"

This reverts commit 6660082fef.

* Apply optimizations

* Added a cleaner icon (#4)

* Fix pure buffer clear frames (#9)

* Disable OpenGL on 3DS (#10)

* Fix tiled textures and improve UI image quality (#11)

* Create 3DS default config overrides

* 3ds: implement apt hooks

* remove unused import

* Apply suggestions from code review

Co-authored-by: Christian Semmler <mail@csemmler.com>
Co-authored-by: Anonymous Maarten <madebr@users.noreply.github.com>

* Update miniwin/src/d3drm/backends/citro3d/renderer.cpp

Co-authored-by: Anonymous Maarten <madebr@users.noreply.github.com>

* Separate 3DS apt hook code + move cmake 3ds into ISLE_BUILD_APP

* miniwin: use citro3dd if debugging

* Optimize texture encoding (#12)

* Cleanup

* Set correct mipmap level for UI textures (#13)

* cpack: include the .3dsx

* Add 3DS CI

* Fix CI

Co-authored-by: Anonymous Maarten <madebr@users.noreply.github.com>

* syntax

* Refactor c3d renderer (#14)

* Refactor c3d renderer

* format

* Apply suggestions from code review

Co-authored-by: Anders Jenbo <anders@jenbo.dk>

---------

Co-authored-by: Anders Jenbo <anders@jenbo.dk>

* n3ds: just distribute the .3dsx

* upload 3dsx

* Skip uploading 3DS artifacts

* Update ci.yml

* Update ci.yml

* Remove extraneous ifdef

---------

Co-authored-by: MaxBrick <maximusbrick@gmail.com>
Co-authored-by: Anders Jenbo <anders@jenbo.dk>
Co-authored-by: Steven <139715581+StevenSYS@users.noreply.github.com>
Co-authored-by: Christian Semmler <mail@csemmler.com>
Co-authored-by: Anonymous Maarten <madebr@users.noreply.github.com>
2025-07-01 02:43:10 +00:00

266 lines
6.7 KiB
C++

#include "miniwin/d3drm.h"
#include "d3drm_impl.h"
#include "d3drmdevice_impl.h"
#include "d3drmframe_impl.h"
#include "d3drmlight_impl.h"
#include "d3drmmesh_impl.h"
#include "d3drmobject_impl.h"
#include "d3drmrenderer.h"
#ifdef USE_OPENGL1
#include "d3drmrenderer_opengl1.h"
#endif
#ifdef USE_OPENGLES2
#include "d3drmrenderer_opengles2.h"
#endif
#ifdef __3DS__
#include "d3drmrenderer_citro3d.h"
#endif
#ifdef _WIN32
#include "d3drmrenderer_directx9.h"
#endif
#include "d3drmrenderer_sdl3gpu.h"
#include "d3drmrenderer_software.h"
#include "d3drmtexture_impl.h"
#include "d3drmviewport_impl.h"
#include "ddraw_impl.h"
#include "ddsurface_impl.h"
#include "miniwin.h"
#include <SDL3/SDL.h>
Direct3DRMPickedArrayImpl::Direct3DRMPickedArrayImpl(const PickRecord* inputPicks, size_t count)
{
picks.reserve(count);
for (size_t i = 0; i < count; ++i) {
const PickRecord& pick = inputPicks[i];
if (pick.visual) {
pick.visual->AddRef();
}
if (pick.frameArray) {
pick.frameArray->AddRef();
}
picks.push_back(pick);
}
}
Direct3DRMPickedArrayImpl::~Direct3DRMPickedArrayImpl()
{
for (PickRecord& pick : picks) {
if (pick.visual) {
pick.visual->Release();
}
if (pick.frameArray) {
pick.frameArray->Release();
}
}
}
DWORD Direct3DRMPickedArrayImpl::GetSize()
{
return static_cast<DWORD>(picks.size());
}
HRESULT Direct3DRMPickedArrayImpl::GetPick(
DWORD index,
IDirect3DRMVisual** visual,
IDirect3DRMFrameArray** frameArray,
D3DRMPICKDESC* desc
)
{
if (index >= picks.size()) {
return DDERR_INVALIDPARAMS;
}
const PickRecord& pick = picks[index];
*visual = pick.visual;
*frameArray = pick.frameArray;
*desc = pick.desc;
if (*visual) {
(*visual)->AddRef();
}
if (*frameArray) {
(*frameArray)->AddRef();
}
return DD_OK;
}
struct Direct3DRMWinDeviceImpl : public IDirect3DRMWinDevice {
HRESULT Activate() override
{
MINIWIN_NOT_IMPLEMENTED();
return DD_OK;
}
HRESULT Paint() override
{
MINIWIN_NOT_IMPLEMENTED();
return DD_OK;
}
void HandleActivate(WORD wParam) override { MINIWIN_NOT_IMPLEMENTED(); }
void HandlePaint(void* p_dc) override { MINIWIN_NOT_IMPLEMENTED(); }
};
struct Direct3DRMMaterialImpl : public Direct3DRMObjectBaseImpl<IDirect3DRMMaterial> {
Direct3DRMMaterialImpl(D3DVALUE power) : m_power(power) {}
D3DVALUE GetPower() override { return m_power; }
private:
D3DVALUE m_power;
};
HRESULT Direct3DRMImpl::QueryInterface(const GUID& riid, void** ppvObject)
{
if (SDL_memcmp(&riid, &IID_IDirect3DRM2, sizeof(GUID)) == 0) {
this->IUnknown::AddRef();
*ppvObject = static_cast<IDirect3DRM2*>(this);
return DD_OK;
}
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Direct3DRMImpl does not implement guid");
return E_NOINTERFACE;
}
HRESULT Direct3DRMImpl::CreateDeviceFromD3D(
const IDirect3D2* d3d,
IDirect3DDevice2* d3dDevice,
IDirect3DRMDevice2** outDevice
)
{
auto renderer = static_cast<Direct3DRMRenderer*>(d3dDevice);
*outDevice = static_cast<IDirect3DRMDevice2*>(
new Direct3DRMDevice2Impl(renderer->GetVirtualWidth(), renderer->GetVirtualHeight(), renderer)
);
return DD_OK;
}
HRESULT Direct3DRMImpl::CreateDeviceFromSurface(
const GUID* guid,
IDirectDraw* dd,
IDirectDrawSurface* surface,
IDirect3DRMDevice2** outDevice
)
{
DDSURFACEDESC DDSDesc;
DDSDesc.dwSize = sizeof(DDSURFACEDESC);
surface->GetSurfaceDesc(&DDSDesc);
if (SDL_memcmp(&guid, &SDL3_GPU_GUID, sizeof(GUID)) == 0) {
DDRenderer = Direct3DRMSDL3GPURenderer::Create(DDSDesc.dwWidth, DDSDesc.dwHeight);
}
else if (SDL_memcmp(&guid, &SOFTWARE_GUID, sizeof(GUID)) == 0) {
DDRenderer = new Direct3DRMSoftwareRenderer(DDSDesc.dwWidth, DDSDesc.dwHeight);
}
#ifdef USE_OPENGLES2
else if (SDL_memcmp(&guid, &OpenGLES2_GUID, sizeof(GUID)) == 0) {
DDRenderer = OpenGLES2Renderer::Create(DDSDesc.dwWidth, DDSDesc.dwHeight);
}
#endif
#ifdef USE_OPENGL1
else if (SDL_memcmp(&guid, &OpenGL1_GUID, sizeof(GUID)) == 0) {
DDRenderer = OpenGL1Renderer::Create(DDSDesc.dwWidth, DDSDesc.dwHeight);
}
#endif
#ifdef __3DS__
else if (SDL_memcmp(&guid, &Citro3D_GUID, sizeof(GUID)) == 0) {
DDRenderer = new Citro3DRenderer(DDSDesc.dwWidth, DDSDesc.dwHeight);
}
#endif
#ifdef _WIN32
else if (SDL_memcmp(&guid, &DirectX9_GUID, sizeof(GUID)) == 0) {
DDRenderer = DirectX9Renderer::Create(DDSDesc.dwWidth, DDSDesc.dwHeight);
}
#endif
else {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Device GUID not recognized");
return E_NOINTERFACE;
}
*outDevice =
static_cast<IDirect3DRMDevice2*>(new Direct3DRMDevice2Impl(DDSDesc.dwWidth, DDSDesc.dwHeight, DDRenderer));
return DD_OK;
}
HRESULT Direct3DRMImpl::CreateTexture(D3DRMIMAGE* image, IDirect3DRMTexture2** outTexture)
{
*outTexture = static_cast<IDirect3DRMTexture2*>(new Direct3DRMTextureImpl(image));
return DD_OK;
}
HRESULT Direct3DRMImpl::CreateTextureFromSurface(LPDIRECTDRAWSURFACE surface, IDirect3DRMTexture2** outTexture)
{
*outTexture = static_cast<IDirect3DRMTexture2*>(new Direct3DRMTextureImpl(surface, true));
return DD_OK;
}
HRESULT Direct3DRMImpl::CreateMesh(IDirect3DRMMesh** outMesh)
{
*outMesh = static_cast<IDirect3DRMMesh*>(new Direct3DRMMeshImpl);
return DD_OK;
}
HRESULT Direct3DRMImpl::CreateMaterial(D3DVAL power, IDirect3DRMMaterial** outMaterial)
{
*outMaterial = static_cast<IDirect3DRMMaterial*>(new Direct3DRMMaterialImpl(power));
return DD_OK;
}
HRESULT Direct3DRMImpl::CreateLightRGB(D3DRMLIGHTTYPE type, D3DVAL r, D3DVAL g, D3DVAL b, IDirect3DRMLight** outLight)
{
*outLight = static_cast<IDirect3DRMLight*>(new Direct3DRMLightImpl(type, r, g, b));
return DD_OK;
}
HRESULT Direct3DRMImpl::CreateFrame(IDirect3DRMFrame* parent, IDirect3DRMFrame2** outFrame)
{
auto parentImpl = static_cast<Direct3DRMFrameImpl*>(parent);
*outFrame = static_cast<IDirect3DRMFrame2*>(new Direct3DRMFrameImpl{parentImpl});
return DD_OK;
}
HRESULT Direct3DRMImpl::CreateViewport(
IDirect3DRMDevice2* iDevice,
IDirect3DRMFrame* camera,
int x,
int y,
int width,
int height,
IDirect3DRMViewport** outViewport
)
{
auto device = static_cast<Direct3DRMDevice2Impl*>(iDevice);
auto* viewport = new Direct3DRMViewportImpl(width, height, device->m_renderer);
if (camera) {
viewport->SetCamera(camera);
}
*outViewport = static_cast<IDirect3DRMViewport*>(viewport);
device->AddViewport(*outViewport);
return DD_OK;
}
HRESULT Direct3DRMImpl::SetDefaultTextureShades(DWORD count)
{
return DD_OK;
}
HRESULT Direct3DRMImpl::SetDefaultTextureColors(DWORD count)
{
return DD_OK;
}
HRESULT WINAPI Direct3DRMCreate(IDirect3DRM** direct3DRM)
{
*direct3DRM = new Direct3DRMImpl;
return DD_OK;
}
D3DCOLOR D3DRMCreateColorRGBA(D3DVALUE red, D3DVALUE green, D3DVALUE blue, D3DVALUE alpha)
{
int a = static_cast<int>(255.f * alpha);
int r = static_cast<int>(255.f * red);
int g = static_cast<int>(255.f * green);
int b = static_cast<int>(255.f * blue);
return (a << 24) | (r << 16) | (g << 8) | b;
}