mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-04-09 23:55:40 +12:00
Moar HTTP
This commit is contained in:
parent
536e4566db
commit
ba1c3a8ec5
6 changed files with 47 additions and 40 deletions
|
@ -88,6 +88,7 @@ class GPU {
|
||||||
void initGraphicsContext() { renderer.initGraphicsContext(); }
|
void initGraphicsContext() { renderer.initGraphicsContext(); }
|
||||||
void getGraphicsContext() { renderer.getGraphicsContext(); }
|
void getGraphicsContext() { renderer.getGraphicsContext(); }
|
||||||
void display() { renderer.display(); }
|
void display() { renderer.display(); }
|
||||||
|
void screenshot(const std::string& name) { renderer.screenshot(name); }
|
||||||
|
|
||||||
void fireDMA(u32 dest, u32 source, u32 size);
|
void fireDMA(u32 dest, u32 source, u32 size);
|
||||||
void reset();
|
void reset();
|
||||||
|
|
|
@ -69,7 +69,6 @@ class Emulator {
|
||||||
void reset();
|
void reset();
|
||||||
void run();
|
void run();
|
||||||
void runFrame();
|
void runFrame();
|
||||||
void screenshot(const std::string& name);
|
|
||||||
|
|
||||||
bool loadROM(const std::filesystem::path& path);
|
bool loadROM(const std::filesystem::path& path);
|
||||||
bool loadNCSD(const std::filesystem::path& path, ROMType type);
|
bool loadNCSD(const std::filesystem::path& path, ROMType type);
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <span>
|
#include <span>
|
||||||
|
#include <stb_image_write.h>
|
||||||
|
|
||||||
#include "PICA/float_types.hpp"
|
#include "PICA/float_types.hpp"
|
||||||
#include "gl_state.hpp"
|
#include "gl_state.hpp"
|
||||||
|
@ -88,6 +89,9 @@ class Renderer {
|
||||||
void displayTransfer(u32 inputAddr, u32 outputAddr, u32 inputSize, u32 outputSize, u32 flags); // Perform display transfer
|
void displayTransfer(u32 inputAddr, u32 outputAddr, u32 inputSize, u32 outputSize, u32 flags); // Perform display transfer
|
||||||
void drawVertices(PICA::PrimType primType, std::span<const PICA::Vertex> vertices); // Draw the given vertices
|
void drawVertices(PICA::PrimType primType, std::span<const PICA::Vertex> vertices); // Draw the given vertices
|
||||||
|
|
||||||
|
// Take a screenshot of the screen and store it in a file
|
||||||
|
void screenshot(const std::string& name);
|
||||||
|
|
||||||
void setFBSize(u32 width, u32 height) {
|
void setFBSize(u32 width, u32 height) {
|
||||||
fbSize.x() = width;
|
fbSize.x() = width;
|
||||||
fbSize.y() = height;
|
fbSize.y() = height;
|
||||||
|
|
|
@ -669,7 +669,7 @@ void Renderer::initGraphicsContext() {
|
||||||
dummyVAO.create();
|
dummyVAO.create();
|
||||||
|
|
||||||
// Create texture and framebuffer for the 3DS screen
|
// Create texture and framebuffer for the 3DS screen
|
||||||
const u32 screenTextureWidth = 2 * 400; // Top screen is 400 pixels wide, bottom is 320
|
const u32 screenTextureWidth = 400; // Top screen is 400 pixels wide, bottom is 320
|
||||||
const u32 screenTextureHeight = 2 * 240; // Both screens are 240 pixels tall
|
const u32 screenTextureHeight = 2 * 240; // Both screens are 240 pixels tall
|
||||||
|
|
||||||
glGenTextures(1,&lightLUTTextureArray);
|
glGenTextures(1,&lightLUTTextureArray);
|
||||||
|
@ -1028,4 +1028,29 @@ void Renderer::displayTransfer(u32 inputAddr, u32 outputAddr, u32 inputSize, u32
|
||||||
}
|
}
|
||||||
|
|
||||||
OpenGL::draw(OpenGL::TriangleStrip, 4); // Actually draw our 3DS screen
|
OpenGL::draw(OpenGL::TriangleStrip, 4); // Actually draw our 3DS screen
|
||||||
|
}
|
||||||
|
|
||||||
|
void Renderer::screenshot(const std::string& name) {
|
||||||
|
constexpr uint width = 400;
|
||||||
|
constexpr uint height = 2 * 240;
|
||||||
|
|
||||||
|
std::vector<uint8_t> pixels, flippedPixels;
|
||||||
|
pixels.resize(width * height * 4);
|
||||||
|
flippedPixels.resize(pixels.size());;
|
||||||
|
|
||||||
|
OpenGL::bindScreenFramebuffer();
|
||||||
|
glReadPixels(0, 0, width, height, GL_BGRA, GL_UNSIGNED_BYTE, pixels.data());
|
||||||
|
|
||||||
|
// Flip the image vertically
|
||||||
|
for (int y = 0; y < height; y++) {
|
||||||
|
memcpy(&flippedPixels[y * width * 4], &pixels[(height - y - 1) * width * 4], width * 4);
|
||||||
|
// Swap R and B channels
|
||||||
|
for (int x = 0; x < width; x++) {
|
||||||
|
std::swap(flippedPixels[y * width * 4 + x * 4 + 0], flippedPixels[y * width * 4 + x * 4 + 2]);
|
||||||
|
// Set alpha to 0xFF
|
||||||
|
flippedPixels[y * width * 4 + x * 4 + 3] = 0xFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stbi_write_png(name.c_str(), width, height, 4, flippedPixels.data(), 0);
|
||||||
}
|
}
|
|
@ -82,27 +82,6 @@ void Emulator::reset() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Emulator::screenshot(const std::string& name) {
|
|
||||||
std::vector<uint8_t> pixels, flippedPixels;
|
|
||||||
pixels.resize(width * height * 4);
|
|
||||||
flippedPixels.resize(width * height * 4);
|
|
||||||
|
|
||||||
glReadPixels(0, 0, width, height, GL_BGRA, GL_UNSIGNED_BYTE, pixels.data());
|
|
||||||
|
|
||||||
// Flip the image vertically
|
|
||||||
for (int y = 0; y < height; y++) {
|
|
||||||
memcpy(&flippedPixels[y * width * 4], &pixels[(height - y - 1) * width * 4], width * 4);
|
|
||||||
// Swap R and B channels
|
|
||||||
for (int x = 0; x < width; x++) {
|
|
||||||
std::swap(flippedPixels[y * width * 4 + x * 4 + 0], flippedPixels[y * width * 4 + x * 4 + 2]);
|
|
||||||
// Set alpha to 0xFF
|
|
||||||
flippedPixels[y * width * 4 + x * 4 + 3] = 0xFF;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
stbi_write_png(name.c_str(), width, height, 4, flippedPixels.data(), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Emulator::step() {}
|
void Emulator::step() {}
|
||||||
void Emulator::render() {}
|
void Emulator::render() {}
|
||||||
|
|
||||||
|
@ -428,28 +407,27 @@ void Emulator::pollHttpServer() {
|
||||||
|
|
||||||
if (httpServer.pendingAction) {
|
if (httpServer.pendingAction) {
|
||||||
switch (httpServer.action) {
|
switch (httpServer.action) {
|
||||||
case HttpAction::Screenshot: {
|
case HttpAction::Screenshot:
|
||||||
screenshot(HttpServer::httpServerScreenshotPath);
|
gpu.screenshot(HttpServer::httpServerScreenshotPath);
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
case HttpAction::PressKey: {
|
case HttpAction::PressKey:
|
||||||
if (httpServer.pendingKey != 0) {
|
if (httpServer.pendingKey != 0) {
|
||||||
srv.pressKey(httpServer.pendingKey);
|
srv.pressKey(httpServer.pendingKey);
|
||||||
httpServer.pendingKey = 0;
|
httpServer.pendingKey = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
case HttpAction::ReleaseKey: {
|
case HttpAction::ReleaseKey:
|
||||||
if (httpServer.pendingKey != 0) {
|
if (httpServer.pendingKey != 0) {
|
||||||
srv.releaseKey(httpServer.pendingKey);
|
srv.releaseKey(httpServer.pendingKey);
|
||||||
httpServer.pendingKey = 0;
|
httpServer.pendingKey = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
case HttpAction::None: {
|
case HttpAction::None: break;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
httpServer.action = HttpAction::None;
|
httpServer.action = HttpAction::None;
|
||||||
httpServer.pendingAction = false;
|
httpServer.pendingAction = false;
|
||||||
httpServer.pendingAction.notify_all();
|
httpServer.pendingAction.notify_all();
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
#ifdef PANDA3DS_ENABLE_HTTP_SERVER
|
#ifdef PANDA3DS_ENABLE_HTTP_SERVER
|
||||||
#include "httpserver.hpp"
|
#include "httpserver.hpp"
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <map>
|
|
||||||
#include <thread>
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <thread>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "httplib.h"
|
#include "httplib.h"
|
||||||
#include "services/hid.hpp"
|
#include "services/hid.hpp"
|
||||||
|
@ -42,9 +42,7 @@ void HttpServer::startHttpServer() {
|
||||||
std::thread http_thread([this]() {
|
std::thread http_thread([this]() {
|
||||||
httplib::Server server;
|
httplib::Server server;
|
||||||
|
|
||||||
server.Get("/ping", [](const httplib::Request&, httplib::Response& response) {
|
server.Get("/ping", [](const httplib::Request&, httplib::Response& response) { response.set_content("pong", "text/plain"); });
|
||||||
response.set_content("pong", "text/plain");
|
|
||||||
});
|
|
||||||
|
|
||||||
server.Get("/screen", [this](const httplib::Request&, httplib::Response& response) {
|
server.Get("/screen", [this](const httplib::Request&, httplib::Response& response) {
|
||||||
{
|
{
|
||||||
|
@ -61,9 +59,10 @@ void HttpServer::startHttpServer() {
|
||||||
|
|
||||||
server.Get("/input", [this](const httplib::Request& request, httplib::Response& response) {
|
server.Get("/input", [this](const httplib::Request& request, httplib::Response& response) {
|
||||||
bool ok = false;
|
bool ok = false;
|
||||||
for (auto& [keyStr, value]: request.params) {
|
for (auto& [keyStr, value] : request.params) {
|
||||||
auto key = stringToKey(keyStr);
|
auto key = stringToKey(keyStr);
|
||||||
printf("Param: %s\n", keyStr.c_str());
|
printf("Param: %s\n", keyStr.c_str());
|
||||||
|
|
||||||
if (key != 0) {
|
if (key != 0) {
|
||||||
std::scoped_lock lock(actionMutex);
|
std::scoped_lock lock(actionMutex);
|
||||||
pendingAction = true;
|
pendingAction = true;
|
||||||
|
@ -97,6 +96,7 @@ void HttpServer::startHttpServer() {
|
||||||
printf("Starting HTTP server on port 1234\n");
|
printf("Starting HTTP server on port 1234\n");
|
||||||
server.listen("localhost", 1234);
|
server.listen("localhost", 1234);
|
||||||
});
|
});
|
||||||
|
|
||||||
http_thread.detach();
|
http_thread.detach();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue