Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <cstring>
- #include "GSH_GXM.h"
- #include "gxm.h"
- #include "../../Log.h"
- #include "../../ui_vita/netlog.h"
- #include <psp2/kernel/threadmgr.h>
- #define LOG(...) netlogf(__VA_ARGS__)
- static inline uint32_t rgba_u32_color(uint8_t r, uint8_t g, uint8_t b, uint8_t a)
- {
- return (a << 24) | (b << 16) | (g << 8) | (r);
- }
- CGSH_GXM::CGSH_GXM()
- {
- LOG("CGSH_GXM start\n");
- }
- CGSH_GXM::~CGSH_GXM()
- {
- }
- void CGSH_GXM::InitializeImpl()
- {
- gxm_init();
- PRESENTATION_PARAMS presentationParams;
- presentationParams.mode = CGSHandler::PRESENTATION_MODE::PRESENTATION_MODE_ORIGINAL;
- presentationParams.windowWidth = 960;
- presentationParams.windowHeight = 544;
- SetPresentationParams(presentationParams);
- }
- void CGSH_GXM::ReleaseImpl()
- {
- gxm_finish();
- }
- void CGSH_GXM::ProcessHostToLocalTransfer()
- {
- }
- void CGSH_GXM::ProcessLocalToHostTransfer()
- {
- }
- void CGSH_GXM::ProcessLocalToLocalTransfer()
- {
- }
- void CGSH_GXM::ProcessClutTransfer(uint32, uint32)
- {
- }
- void CGSH_GXM::ReadFramebuffer(uint32, uint32, void*)
- {
- }
- static float CalcZ(float nZ)
- {
- // 32768.0f
- // 8388608.0f
- // 2147483647.0f
- constexpr float m_nMaxZ = 8388608.0f;
- if (nZ < 256){
- //The number is small, so scale to a smaller ratio (65536)
- return nZ / 32768.0f;
- } else {
- // nZ -= m_nMaxZ;
- if(nZ > m_nMaxZ) return 1.0;
- // if(nZ < -m_nMaxZ) return -1.0;
- return nZ / m_nMaxZ;
- }
- }
- void CGSH_GXM::Prim_Triangle()
- {
- XYZ pos[3];
- pos[0] <<= m_vtxBuffer[2].position;
- pos[1] <<= m_vtxBuffer[1].position;
- pos[2] <<= m_vtxBuffer[0].position;
- float x1 = pos[0].GetX(), x2 = pos[1].GetX(), x3 = pos[2].GetX();
- float y1 = pos[0].GetY(), y2 = pos[1].GetY(), y3 = pos[2].GetY();
- uint32 z1 = pos[0].nZ, z2 = pos[1].nZ, z3 = pos[2].nZ;
- RGBAQ rgbaq[3];
- rgbaq[0] <<= m_vtxBuffer[2].rgbaq;
- rgbaq[1] <<= m_vtxBuffer[1].rgbaq;
- rgbaq[2] <<= m_vtxBuffer[0].rgbaq;
- x1 -= m_primOfsX;
- x2 -= m_primOfsX;
- x3 -= m_primOfsX;
- y1 -= m_primOfsY;
- y2 -= m_primOfsY;
- y3 -= m_primOfsY;
- float s[3] = {0, 0, 0};
- float t[3] = {0, 0, 0};
- float q[3] = {1, 1, 1};
- float f[3] = {0, 0, 0};
- if (m_primitiveMode.nFog) {
- f[0] = static_cast<float>(0xFF - m_vtxBuffer[2].fog) / 255.0f;
- f[1] = static_cast<float>(0xFF - m_vtxBuffer[1].fog) / 255.0f;
- f[2] = static_cast<float>(0xFF - m_vtxBuffer[0].fog) / 255.0f;
- }
- if (m_primitiveMode.nTexture) {
- if(m_primitiveMode.nUseUV) {
- UV uv[3];
- uv[0] <<= m_vtxBuffer[2].uv;
- uv[1] <<= m_vtxBuffer[1].uv;
- uv[2] <<= m_vtxBuffer[0].uv;
- s[0] = uv[0].GetU() / static_cast<float>(m_texWidth);
- s[1] = uv[1].GetU() / static_cast<float>(m_texWidth);
- s[2] = uv[2].GetU() / static_cast<float>(m_texWidth);
- t[0] = uv[0].GetV() / static_cast<float>(m_texHeight);
- t[1] = uv[1].GetV() / static_cast<float>(m_texHeight);
- t[2] = uv[2].GetV() / static_cast<float>(m_texHeight);
- } else {
- ST st[3];
- st[0] <<= m_vtxBuffer[2].st;
- st[1] <<= m_vtxBuffer[1].st;
- st[2] <<= m_vtxBuffer[0].st;
- s[0] = st[0].nS;
- s[1] = st[1].nS;
- s[2] = st[2].nS;
- t[0] = st[0].nT;
- t[1] = st[1].nT;
- t[2] = st[2].nT;
- q[0] = rgbaq[0].nQ;
- q[1] = rgbaq[1].nQ;
- q[2] = rgbaq[2].nQ;
- }
- }
- auto color1 = rgba_u32_color(rgbaq[0].nR, rgbaq[0].nG, rgbaq[0].nB, rgbaq[0].nA);
- auto color2 = rgba_u32_color(rgbaq[1].nR, rgbaq[1].nG, rgbaq[1].nB, rgbaq[1].nA);
- auto color3 = rgba_u32_color(rgbaq[2].nR, rgbaq[2].nG, rgbaq[2].nB, rgbaq[2].nA);
- // Flat shading
- if (m_primitiveMode.nShading == 0)
- color1 = color2 = color3;
- struct color_vertex vertices[3] = {
- { .position = {x1, y1, (float)z1}, .color = color1 },
- { .position = {x2, y2, (float)z2}, .color = color2 },
- { .position = {x3, y3, (float)z3}, .color = color3 }
- };
- gxm_vertex_buffer_push(vertices, 3);
- /*vertex.position.x = x;
- vertex.position.y = y;
- vertex.position.z = 1.0f - z;
- vertex.color.r = rgbaq.nR;
- vertex.color.g = rgbaq.nG;
- vertex.color.b = rgbaq.nB;
- vertex.color.a = rgbaq.nA;*/
- /*LOG("TFM {%f, %f, %f}, {%f, %f, %f}\n",
- vertex.position.x, vertex.position.y, vertex.position.z,
- vertex.color.r, vertex.color.g, vertex.color.b);*/
- //gxm_vertex_buffer_push(&vertex);
- /*CDraw::PRIM_VERTEX vertices[] =
- {
- { x1, y1, z1, color1, s[0], t[0], q[0], f[0]},
- { x2, y2, z2, color2, s[1], t[1], q[1], f[1]},
- { x3, y3, z3, color3, s[2], t[2], q[2], f[2]},
- };*/
- //m_draw->AddVertices(std::begin(vertices), std::end(vertices));
- }
- void CGSH_GXM::VertexKick(uint8 registerId, uint64 data)
- {
- if (m_vtxCount == 0)
- return;
- bool drawingKick = (registerId == GS_REG_XYZ2) || (registerId == GS_REG_XYZF2);
- bool fog = (registerId == GS_REG_XYZF2) || (registerId == GS_REG_XYZF3);
- if (fog) {
- m_vtxBuffer[m_vtxCount - 1].position = data & 0x00FFFFFFFFFFFFFFULL;
- m_vtxBuffer[m_vtxCount - 1].rgbaq = m_nReg[GS_REG_RGBAQ];
- m_vtxBuffer[m_vtxCount - 1].uv = m_nReg[GS_REG_UV];
- m_vtxBuffer[m_vtxCount - 1].st = m_nReg[GS_REG_ST];
- m_vtxBuffer[m_vtxCount - 1].fog = static_cast<uint8>(data >> 56);
- } else {
- m_vtxBuffer[m_vtxCount - 1].position = data;
- m_vtxBuffer[m_vtxCount - 1].rgbaq = m_nReg[GS_REG_RGBAQ];
- m_vtxBuffer[m_vtxCount - 1].uv = m_nReg[GS_REG_UV];
- m_vtxBuffer[m_vtxCount - 1].st = m_nReg[GS_REG_ST];
- m_vtxBuffer[m_vtxCount - 1].fog = static_cast<uint8>(m_nReg[GS_REG_FOG] >> 56);
- }
- m_vtxCount--;
- if(m_vtxCount == 0) {
- if ((m_nReg[GS_REG_PRMODECONT] & 1) != 0)
- m_primitiveMode <<= m_nReg[GS_REG_PRIM];
- else
- m_primitiveMode <<= m_nReg[GS_REG_PRMODE];
- if (drawingKick)
- SetRenderingContext(m_primitiveMode);
- switch (m_primitiveType) {
- case PRIM_POINT:
- //if (drawingKick) Prim_Point();
- m_vtxCount = 1;
- break;
- case PRIM_LINE:
- //if (drawingKick) Prim_Line();
- m_vtxCount = 2;
- break;
- case PRIM_LINESTRIP:
- //if (drawingKick) Prim_Line();
- memcpy(&m_vtxBuffer[1], &m_vtxBuffer[0], sizeof(VERTEX));
- m_vtxCount = 1;
- break;
- case PRIM_TRIANGLE:
- if (drawingKick) Prim_Triangle();
- m_vtxCount = 3;
- break;
- case PRIM_TRIANGLESTRIP:
- if (drawingKick) Prim_Triangle();
- memcpy(&m_vtxBuffer[2], &m_vtxBuffer[1], sizeof(VERTEX));
- memcpy(&m_vtxBuffer[1], &m_vtxBuffer[0], sizeof(VERTEX));
- m_vtxCount = 1;
- break;
- case PRIM_TRIANGLEFAN:
- if (drawingKick) Prim_Triangle();
- memcpy(&m_vtxBuffer[1], &m_vtxBuffer[0], sizeof(VERTEX));
- m_vtxCount = 1;
- break;
- case PRIM_SPRITE:
- //if (drawingKick) Prim_Sprite();
- m_vtxCount = 2;
- break;
- }
- }
- #if 0
- //LOG("Vertex kick\n");
- bool draw = (registerId == GS_REG_XYZ2) || (registerId == GS_REG_XYZF2);
- if (!draw)
- return;
- if (m_primitiveType != PRIM_TRIANGLE)
- return;
- if ((m_nReg[GS_REG_PRMODECONT] & 1) != 0)
- m_primitiveMode <<= m_nReg[GS_REG_PRIM];
- else
- m_primitiveMode <<= m_nReg[GS_REG_PRMODE];
- auto prim = make_convertible<PRMODE>(m_primitiveMode);
- unsigned int context = m_primitiveMode.nContext;
- auto offset = make_convertible<XYOFFSET>(m_nReg[GS_REG_XYOFFSET_1 + context]);
- auto scissor = make_convertible<SCISSOR>(m_nReg[GS_REG_SCISSOR_1 + context]);
- uint64 pos = data & 0x00FFFFFFFFFFFFFFULL;
- uint64 nRGBAQ = m_nReg[GS_REG_RGBAQ];
- auto xyz = make_convertible<XYZ>(pos);
- auto rgbaq = make_convertible<RGBAQ>(nRGBAQ);
- /*if (GetCrtIsInterlaced() && GetCrtIsFrameMode()) {
- if (m_nCSR & CSR_FIELD)
- m_nPrimOfsY += 0.5;
- }*/
- // V {1728.000000, 1792.000000, 0.000000}
- // XYOFFSET: {1728.000000, 1792.000000}
- // SCISSOR {0, 639, 0, 511}
- // PRESVP: { x: 160, y: 48, w: 640, h: 448}
- // CRT: {640, 448}
- // TFM { 160.000000, 48.000000, 1.000000}, {0.501961, 0.000000, 0.000000}
- /*LOG("V {%f, %f, %f}\n", xyz.GetX(), xyz.GetY(), xyz.GetZ());
- LOG("XYOFFSET: {%f, %f}\n", offset.GetX(), offset.GetY());
- LOG("SCISSOR: {%d, %d, %d, %d}\n", scissor.scax0, scissor.scax1, scissor.scay0, scissor.scay1);
- LOG("CRT: {%d, %d}\n", GetCrtWidth(), GetCrtHeight());
- LOG("PRESVP: {x: %d, y: %d, w: %d, h: %d}\n", GetPresentationViewport().offsetX,
- GetPresentationViewport().offsetY, GetPresentationViewport().width,
- GetPresentationViewport().height);*/
- float x = xyz.GetX() - offset.GetX();
- float y = xyz.GetY() - offset.GetY();
- float z = CalcZ(xyz.GetZ());
- /* Hacky presentation viewport */
- CGSHandler::PRESENTATION_VIEWPORT presentation_vp = GetPresentationViewport();
- x += presentation_vp.offsetX;
- y += presentation_vp.offsetY;
- struct color_vertex vertex;
- vertex.position.x = x;
- vertex.position.y = y;
- vertex.position.z = 1.0f - z;
- vertex.color.r = rgbaq.nR;
- vertex.color.g = rgbaq.nG;
- vertex.color.b = rgbaq.nB;
- vertex.color.a = rgbaq.nA;
- /*LOG("TFM {%f, %f, %f}, {%f, %f, %f}\n",
- vertex.position.x, vertex.position.y, vertex.position.z,
- vertex.color.r, vertex.color.g, vertex.color.b);*/
- gxm_vertex_buffer_push(&vertex);
- #endif
- }
- void CGSH_GXM::WriteRegisterImpl(uint8 registerId, uint64 data)
- {
- CGSHandler::WriteRegisterImpl(registerId, data);
- //LOG("WriteRegisterImpl\n");
- switch (registerId) {
- case GS_REG_PRIM:
- m_primitiveType = static_cast<unsigned int>(data & 0x07);
- switch (m_primitiveType) {
- case PRIM_POINT:
- m_vtxCount = 1;
- break;
- case PRIM_LINE:
- case PRIM_LINESTRIP:
- m_vtxCount = 2;
- break;
- case PRIM_TRIANGLE:
- case PRIM_TRIANGLESTRIP:
- case PRIM_TRIANGLEFAN:
- m_vtxCount = 3;
- break;
- case PRIM_SPRITE:
- m_vtxCount = 2;
- break;
- }
- break;
- case GS_REG_XYZ2:
- case GS_REG_XYZ3:
- case GS_REG_XYZF2:
- case GS_REG_XYZF3:
- VertexKick(registerId, data);
- break;
- }
- }
- void CGSH_GXM::FlipImpl()
- {
- LOG("CGSH_GXM::FlipImpl\n");
- auto dispInfo = GetCurrentDisplayInfo();
- auto fb = make_convertible<DISPFB>(dispInfo.first);
- auto display = make_convertible<DISPLAY>(dispInfo.second);
- unsigned int dispWidth = (display.nW + 1) / (display.nMagX + 1);
- unsigned int dispHeight = (display.nH + 1);
- if (GetCrtIsInterlaced() && GetCrtIsFrameMode())
- dispHeight /= 2;
- //CGSHandler::PRESENTATION_VIEWPORT vp = GetPresentationViewport();
- //gxm_set_viewport(vp.offsetX, vp.offsetY, vp.width, vp.height, 0.5f, 0.5f);
- //LOG("VP: {%d, %d, %d, %d}\n", vp.offsetX, vp.width, vp.offsetY, vp.height);
- //m_present->SetPresentationViewport(GetPresentationViewport());
- //m_present->DoPresent(fb.nPSM, fb.GetBufPtr(), fb.GetBufWidth(), dispWidth, dispHeight);
- gxm_flip();
- CGSHandler::FlipImpl();
- LOG("Flip done\n");
- gxm_vertex_buffer_reset();
- }
- CGSHandler::FactoryFunction CGSH_GXM::GetFactoryFunction()
- {
- return [=]() { return new CGSH_GXM(); };
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement