{"action":"created","comment":{"url":"https://api.github.com/repos/citra-emu/citra/pulls/comments/30413205","id":30413205,"diff_hunk":"@@ -0,0 +1,701 @@\n+// Copyright 2015 Citra Emulator Project\n+// Licensed under GPLv2 or any later version\n+// Refer to the license.txt file included.\n+\n+#include \"core/settings.h\"\n+#include \"core/hw/gpu.h\"\n+\n+#include \"video_core/color.h\"\n+#include \"video_core/pica.h\"\n+#include \"video_core/utils.h\"\n+#include \"video_core/renderer_opengl/gl_pica_to_gl.h\"\n+#include \"video_core/renderer_opengl/gl_rasterizer.h\"\n+#include \"video_core/renderer_opengl/gl_shaders.h\"\n+#include \"video_core/renderer_opengl/gl_shader_util.h\"\n+\n+#include \"generated/gl_3_2_core.h\"\n+\n+#include <memory>\n+\n+u32 ColorFormatBytesPerPixel(u32 format) {\n+    switch (format) {\n+    case Pica::registers.framebuffer.RGBA8:\n+        return 4;\n+    case Pica::registers.framebuffer.RGB8:\n+        return 3;\n+    case Pica::registers.framebuffer.RGB5A1:\n+    case Pica::registers.framebuffer.RGB565:\n+    case Pica::registers.framebuffer.RGBA4:\n+        return 2;\n+    default:\n+        LOG_CRITICAL(Render_OpenGL, \"Unknown framebuffer color format %x\", format);\n+        UNIMPLEMENTED();\n+        break;\n+    }\n+\n+    return 0;\n+}\n+\n+RasterizerOpenGL::RasterizerOpenGL() : last_fb_color_addr(0), last_fb_depth_addr(0) {\n+\n+}\n+\n+RasterizerOpenGL::~RasterizerOpenGL() {\n+    // Set context for automatic resource destruction\n+    render_window->MakeCurrent();\n+}\n+\n+void RasterizerOpenGL::InitObjects() {\n+    // Create the hardware shader program and get attrib/uniform locations\n+    shader.Create(GLShaders::g_vertex_shader_hw, GLShaders::g_fragment_shader_hw);\n+    attrib_position = glGetAttribLocation(shader.GetHandle(), \"vert_position\");\n+    attrib_color = glGetAttribLocation(shader.GetHandle(), \"vert_color\");\n+    attrib_texcoords = glGetAttribLocation(shader.GetHandle(), \"vert_texcoords\");\n+\n+    uniform_alphatest_func = glGetUniformLocation(shader.GetHandle(), \"alphatest_func\");\n+    uniform_alphatest_ref = glGetUniformLocation(shader.GetHandle(), \"alphatest_ref\");\n+\n+    uniform_tex = glGetUniformLocation(shader.GetHandle(), \"tex\");\n+\n+    uniform_tev_combiner_buffer_color = glGetUniformLocation(shader.GetHandle(), \"tev_combiner_buffer_color\");\n+\n+    for (int i = 0; i < 6; ++i) {\n+        auto& uniform_tev = uniform_tev_cfgs[i];\n+\n+        std::string tev_ref_str = \"tev_cfgs[\" + std::to_string(i) + \"]\";\n+        uniform_tev.color_sources = glGetUniformLocation(shader.GetHandle(), (tev_ref_str + \".color_sources\").c_str());\n+        uniform_tev.alpha_sources = glGetUniformLocation(shader.GetHandle(), (tev_ref_str + \".alpha_sources\").c_str());\n+        uniform_tev.color_modifiers = glGetUniformLocation(shader.GetHandle(), (tev_ref_str + \".color_modifiers\").c_str());\n+        uniform_tev.alpha_modifiers = glGetUniformLocation(shader.GetHandle(), (tev_ref_str + \".alpha_modifiers\").c_str());\n+        uniform_tev.color_alpha_op = glGetUniformLocation(shader.GetHandle(), (tev_ref_str + \".color_alpha_op\").c_str());\n+        uniform_tev.color_alpha_multiplier = glGetUniformLocation(shader.GetHandle(), (tev_ref_str + \".color_alpha_multiplier\").c_str());\n+        uniform_tev.const_color = glGetUniformLocation(shader.GetHandle(), (tev_ref_str + \".const_color\").c_str());\n+        uniform_tev.updates_combiner_buffer_color_alpha = glGetUniformLocation(shader.GetHandle(), (tev_ref_str + \".updates_combiner_buffer_color_alpha\").c_str());\n+    }\n+\n+    uniform_out_maps = glGetUniformLocation(shader.GetHandle(), \"out_maps\");\n+\n+    // Generate VBO and VAO\n+    vertex_buffer.Create();\n+    vertex_array.Create();\n+\n+    // Update OpenGL state\n+    state.draw.vertex_array = vertex_array.GetHandle();\n+    state.draw.vertex_buffer = vertex_buffer.GetHandle();\n+    state.draw.shader_program = shader.GetHandle();\n+\n+    for (auto& texture_unit : state.texture_units) {\n+        texture_unit.enabled_2d = true;\n+    }\n+\n+    state.Apply();\n+\n+    // Set the texture samplers to correspond to different texture units\n+    glUniform1i(uniform_tex, 0);\n+    glUniform1i(uniform_tex + 1, 1);\n+    glUniform1i(uniform_tex + 2, 2);\n+\n+    // Set vertex attributes\n+    glVertexAttribPointer(attrib_position, 4, GL_FLOAT, GL_FALSE, sizeof(HardwareVertex), (GLvoid*)offsetof(HardwareVertex, position));\n+    glVertexAttribPointer(attrib_color, 4, GL_FLOAT, GL_FALSE, sizeof(HardwareVertex), (GLvoid*)offsetof(HardwareVertex, color));\n+    glVertexAttribPointer(attrib_texcoords, 2, GL_FLOAT, GL_FALSE, sizeof(HardwareVertex), (GLvoid*)offsetof(HardwareVertex, tex_coord0));\n+    glVertexAttribPointer(attrib_texcoords + 1, 2, GL_FLOAT, GL_FALSE, sizeof(HardwareVertex), (GLvoid*)offsetof(HardwareVertex, tex_coord1));\n+    glVertexAttribPointer(attrib_texcoords + 2, 2, GL_FLOAT, GL_FALSE, sizeof(HardwareVertex), (GLvoid*)offsetof(HardwareVertex, tex_coord2));\n+    glEnableVertexAttribArray(attrib_position);\n+    glEnableVertexAttribArray(attrib_color);\n+    glEnableVertexAttribArray(attrib_texcoords);\n+    glEnableVertexAttribArray(attrib_texcoords + 1);\n+    glEnableVertexAttribArray(attrib_texcoords + 2);\n+\n+    // Create textures for OGL framebuffer that will be rendered to, initially 1x1 to succeed in framebuffer creation\n+    fb_color_texture.texture.Create();\n+    ReconfigColorTexture(fb_color_texture, Pica::registers.framebuffer.RGBA8, 1, 1);\n+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);\n+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);\n+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);\n+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);\n+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);\n+\n+    fb_depth_texture.texture.Create();\n+    ReconfigDepthTexture(fb_depth_texture, Pica::Regs::DepthFormat::D16, 1, 1);\n+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);\n+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);\n+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);\n+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);\n+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);\n+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);\n+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);\n+\n+    // Configure OpenGL framebuffer\n+    framebuffer.Create();\n+\n+    state.draw.framebuffer = framebuffer.GetHandle();\n+    state.texture_units[0].enabled_2d = true;\n+    state.texture_units[0].texture_2d = 0;\n+    state.Apply();\n+\n+    glActiveTexture(GL_TEXTURE0);\n+    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fb_color_texture.texture.GetHandle(), 0);\n+    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, fb_depth_texture.texture.GetHandle(), 0);\n+\n+    if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {\n+        LOG_CRITICAL(Render_OpenGL, \"Framebuffer setup failed, status %X\", glCheckFramebufferStatus(GL_FRAMEBUFFER));\n+    }\n+}\n+\n+void RasterizerOpenGL::SetWindow(EmuWindow* window) {\n+    render_window = window;\n+}\n+\n+void RasterizerOpenGL::AddTriangle(const Pica::VertexShader::OutputVertex& v0,\n+                                   const Pica::VertexShader::OutputVertex& v1,\n+                                   const Pica::VertexShader::OutputVertex& v2) {\n+    vertex_batch.push_back(HardwareVertex(v0));\n+    vertex_batch.push_back(HardwareVertex(v1));\n+    vertex_batch.push_back(HardwareVertex(v2));\n+}\n+\n+void RasterizerOpenGL::DrawTriangles() {\n+    render_window->MakeCurrent();\n+\n+    state.Apply();\n+\n+    SyncFramebuffer();\n+    SyncDrawState();\n+\n+    glBufferData(GL_ARRAY_BUFFER, vertex_batch.size() * sizeof(HardwareVertex), vertex_batch.data(), GL_STREAM_DRAW);\n+    glDrawArrays(GL_TRIANGLES, 0, (GLsizei)vertex_batch.size());\n+\n+    vertex_batch.clear();\n+}\n+\n+void RasterizerOpenGL::NotifyPreCopy(PAddr src_addr, u32 size) {\n+    render_window->MakeCurrent();\n+\n+    state.Apply();\n+\n+    PAddr cur_fb_color_addr = Pica::registers.framebuffer.GetColorBufferPhysicalAddress();\n+    u32 cur_fb_color_size = ColorFormatBytesPerPixel(Pica::registers.framebuffer.color_format)\n+                            * Pica::registers.framebuffer.GetWidth() * Pica::registers.framebuffer.GetHeight();\n+\n+    PAddr cur_fb_depth_addr = Pica::registers.framebuffer.GetDepthBufferPhysicalAddress();\n+    u32 cur_fb_depth_size = Pica::Regs::BytesPerDepthPixel(Pica::registers.framebuffer.depth_format)\n+                            * Pica::registers.framebuffer.GetWidth() * Pica::registers.framebuffer.GetHeight();\n+\n+    // If source memory region overlaps 3DS framebuffers, commit them before the copy happens\n+    PAddr max_low_addr_bound = std::max(src_addr, cur_fb_color_addr);","path":"src/video_core/renderer_opengl/gl_rasterizer.cpp","position":186,"original_position":186,"commit_id":"72d7acd72607badd5a75092bfea03c4b92cb2e19","original_commit_id":"72d7acd72607badd5a75092bfea03c4b92cb2e19","user":{"login":"neobrain","id":4840017,"avatar_url":"https://avatars.githubusercontent.com/u/4840017?v=3","gravatar_id":"","url":"https://api.github.com/users/neobrain","html_url":"https://github.com/neobrain","followers_url":"https://api.github.com/users/neobrain/followers","following_url":"https://api.github.com/users/neobrain/following{/other_user}","gists_url":"https://api.github.com/users/neobrain/gists{/gist_id}","starred_url":"https://api.github.com/users/neobrain/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/neobrain/subscriptions","organizations_url":"https://api.github.com/users/neobrain/orgs","repos_url":"https://api.github.com/users/neobrain/repos","events_url":"https://api.github.com/users/neobrain/events{/privacy}","received_events_url":"https://api.github.com/users/neobrain/received_events","type":"User","site_admin":false},"body":"I suggest moving this functionality into a file-local utility function called something like `bool MemoryRangesIntersect()`.","created_at":"2015-05-15T14:34:50Z","updated_at":"2015-05-15T14:34:50Z","html_url":"https://github.com/citra-emu/citra/pull/753#discussion_r30413205","pull_request_url":"https://api.github.com/repos/citra-emu/citra/pulls/753","_links":{"self":{"href":"https://api.github.com/repos/citra-emu/citra/pulls/comments/30413205"},"html":{"href":"https://github.com/citra-emu/citra/pull/753#discussion_r30413205"},"pull_request":{"href":"https://api.github.com/repos/citra-emu/citra/pulls/753"}}},"pull_request":{"url":"https://api.github.com/repos/citra-emu/citra/pulls/753","id":35172304,"html_url":"https://github.com/citra-emu/citra/pull/753","diff_url":"https://github.com/citra-emu/citra/pull/753.diff","patch_url":"https://github.com/citra-emu/citra/pull/753.patch","issue_url":"https://api.github.com/repos/citra-emu/citra/issues/753","number":753,"state":"open","locked":false,"title":"[RFC] OpenGL Hardware Renderer","user":{"login":"tfarley","id":5193758,"avatar_url":"https://avatars.githubusercontent.com/u/5193758?v=3","gravatar_id":"","url":"https://api.github.com/users/tfarley","html_url":"https://github.com/tfarley","followers_url":"https://api.github.com/users/tfarley/followers","following_url":"https://api.github.com/users/tfarley/following{/other_user}","gists_url":"https://api.github.com/users/tfarley/gists{/gist_id}","starred_url":"https://api.github.com/users/tfarley/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tfarley/subscriptions","organizations_url":"https://api.github.com/users/tfarley/orgs","repos_url":"https://api.github.com/users/tfarley/repos","events_url":"https://api.github.com/users/tfarley/events{/privacy}","received_events_url":"https://api.github.com/users/tfarley/received_events","type":"User","site_admin":false},"body":"This implements an OpenGL renderer that currently only performs the drawing and rasterizing stages using output vertices from the existing vertex shader interpreter.\r\n\r\nThe components of this with primary source files are:\r\n* OpenGL rasterizer (gl_rasterizer, command_processor)\r\n  * Receives geometry and draws it, manages OpenGL state, syncs with 3ds framebuffers\r\n* Rasterizer fragment shader (gl_shaders)\r\n  * Emulates texture environment stages, alpha testing, etc. with dummy vertex shader\r\n* Rasterizer cache (gl_rasterizer_cache)\r\n  * Loads and holds 3ds textures in OGL VRAM, receives flushes\r\n* Caching/flush management (gsp_gpu + gpu)\r\n  * Notifies rasterizer and cache when 3ds memory changes so they may flush caches\r\n* OpenGL state management (gl_state)\r\n  * Encasulates OpenGL state values, applies when requested with minimal state changes\r\n* OpenGL resource management (gl_resource_manager)\r\n  * Auto-deletion of resources when out of scope, copy prevention\r\n* INI setting for sw/hw rasterizer toggle\r\n\r\nI'd like comments on any/all of these!\r\nIn particular, how reasonable the state and resource management parts are.","created_at":"2015-05-11T21:37:04Z","updated_at":"2015-05-15T14:34:50Z","closed_at":null,"merged_at":null,"merge_commit_sha":"f7df009b258f74ede7f4e2e31e4121aa96a98982","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/citra-emu/citra/pulls/753/commits","review_comments_url":"https://api.github.com/repos/citra-emu/citra/pulls/753/comments","review_comment_url":"https://api.github.com/repos/citra-emu/citra/pulls/comments{/number}","comments_url":"https://api.github.com/repos/citra-emu/citra/issues/753/comments","statuses_url":"https://api.github.com/repos/citra-emu/citra/statuses/72d7acd72607badd5a75092bfea03c4b92cb2e19","head":{"label":"tfarley:ogl-renderer2-rfc","ref":"ogl-renderer2-rfc","sha":"72d7acd72607badd5a75092bfea03c4b92cb2e19","user":{"login":"tfarley","id":5193758,"avatar_url":"https://avatars.githubusercontent.com/u/5193758?v=3","gravatar_id":"","url":"https://api.github.com/users/tfarley","html_url":"https://github.com/tfarley","followers_url":"https://api.github.com/users/tfarley/followers","following_url":"https://api.github.com/users/tfarley/following{/other_user}","gists_url":"https://api.github.com/users/tfarley/gists{/gist_id}","starred_url":"https://api.github.com/users/tfarley/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tfarley/subscriptions","organizations_url":"https://api.github.com/users/tfarley/orgs","repos_url":"https://api.github.com/users/tfarley/repos","events_url":"https://api.github.com/users/tfarley/events{/privacy}","received_events_url":"https://api.github.com/users/tfarley/received_events","type":"User","site_admin":false},"repo":{"id":31484883,"name":"citra","full_name":"tfarley/citra","owner":{"login":"tfarley","id":5193758,"avatar_url":"https://avatars.githubusercontent.com/u/5193758?v=3","gravatar_id":"","url":"https://api.github.com/users/tfarley","html_url":"https://github.com/tfarley","followers_url":"https://api.github.com/users/tfarley/followers","following_url":"https://api.github.com/users/tfarley/following{/other_user}","gists_url":"https://api.github.com/users/tfarley/gists{/gist_id}","starred_url":"https://api.github.com/users/tfarley/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tfarley/subscriptions","organizations_url":"https://api.github.com/users/tfarley/orgs","repos_url":"https://api.github.com/users/tfarley/repos","events_url":"https://api.github.com/users/tfarley/events{/privacy}","received_events_url":"https://api.github.com/users/tfarley/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/tfarley/citra","description":"Nintendo 3DS emulator/debugger","fork":true,"url":"https://api.github.com/repos/tfarley/citra","forks_url":"https://api.github.com/repos/tfarley/citra/forks","keys_url":"https://api.github.com/repos/tfarley/citra/keys{/key_id}","collaborators_url":"https://api.github.com/repos/tfarley/citra/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/tfarley/citra/teams","hooks_url":"https://api.github.com/repos/tfarley/citra/hooks","issue_events_url":"https://api.github.com/repos/tfarley/citra/issues/events{/number}","events_url":"https://api.github.com/repos/tfarley/citra/events","assignees_url":"https://api.github.com/repos/tfarley/citra/assignees{/user}","branches_url":"https://api.github.com/repos/tfarley/citra/branches{/branch}","tags_url":"https://api.github.com/repos/tfarley/citra/tags","blobs_url":"https://api.github.com/repos/tfarley/citra/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/tfarley/citra/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/tfarley/citra/git/refs{/sha}","trees_url":"https://api.github.com/repos/tfarley/citra/git/trees{/sha}","statuses_url":"https://api.github.com/repos/tfarley/citra/statuses/{sha}","languages_url":"https://api.github.com/repos/tfarley/citra/languages","stargazers_url":"https://api.github.com/repos/tfarley/citra/stargazers","contributors_url":"https://api.github.com/repos/tfarley/citra/contributors","subscribers_url":"https://api.github.com/repos/tfarley/citra/subscribers","subscription_url":"https://api.github.com/repos/tfarley/citra/subscription","commits_url":"https://api.github.com/repos/tfarley/citra/commits{/sha}","git_commits_url":"https://api.github.com/repos/tfarley/citra/git/commits{/sha}","comments_url":"https://api.github.com/repos/tfarley/citra/comments{/number}","issue_comment_url":"https://api.github.com/repos/tfarley/citra/issues/comments{/number}","contents_url":"https://api.github.com/repos/tfarley/citra/contents/{+path}","compare_url":"https://api.github.com/repos/tfarley/citra/compare/{base}...{head}","merges_url":"https://api.github.com/repos/tfarley/citra/merges","archive_url":"https://api.github.com/repos/tfarley/citra/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/tfarley/citra/downloads","issues_url":"https://api.github.com/repos/tfarley/citra/issues{/number}","pulls_url":"https://api.github.com/repos/tfarley/citra/pulls{/number}","milestones_url":"https://api.github.com/repos/tfarley/citra/milestones{/number}","notifications_url":"https://api.github.com/repos/tfarley/citra/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/tfarley/citra/labels{/name}","releases_url":"https://api.github.com/repos/tfarley/citra/releases{/id}","created_at":"2015-03-01T02:54:02Z","updated_at":"2015-04-15T01:12:08Z","pushed_at":"2015-05-15T09:20:39Z","git_url":"git://github.com/tfarley/citra.git","ssh_url":"git@github.com:tfarley/citra.git","clone_url":"https://github.com/tfarley/citra.git","svn_url":"https://github.com/tfarley/citra","homepage":null,"size":10595,"stargazers_count":17,"watchers_count":17,"language":"C++","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":2,"mirror_url":null,"open_issues_count":0,"forks":2,"open_issues":0,"watchers":17,"default_branch":"master"}},"base":{"label":"citra-emu:master","ref":"master","sha":"10eb8b0c02badb2f87ec2d71f1679a27b679c171","user":{"login":"citra-emu","id":7605670,"avatar_url":"https://avatars.githubusercontent.com/u/7605670?v=3","gravatar_id":"","url":"https://api.github.com/users/citra-emu","html_url":"https://github.com/citra-emu","followers_url":"https://api.github.com/users/citra-emu/followers","following_url":"https://api.github.com/users/citra-emu/following{/other_user}","gists_url":"https://api.github.com/users/citra-emu/gists{/gist_id}","starred_url":"https://api.github.com/users/citra-emu/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/citra-emu/subscriptions","organizations_url":"https://api.github.com/users/citra-emu/orgs","repos_url":"https://api.github.com/users/citra-emu/repos","events_url":"https://api.github.com/users/citra-emu/events{/privacy}","received_events_url":"https://api.github.com/users/citra-emu/received_events","type":"Organization","site_admin":false},"repo":{"id":19866730,"name":"citra","full_name":"citra-emu/citra","owner":{"login":"citra-emu","id":7605670,"avatar_url":"https://avatars.githubusercontent.com/u/7605670?v=3","gravatar_id":"","url":"https://api.github.com/users/citra-emu","html_url":"https://github.com/citra-emu","followers_url":"https://api.github.com/users/citra-emu/followers","following_url":"https://api.github.com/users/citra-emu/following{/other_user}","gists_url":"https://api.github.com/users/citra-emu/gists{/gist_id}","starred_url":"https://api.github.com/users/citra-emu/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/citra-emu/subscriptions","organizations_url":"https://api.github.com/users/citra-emu/orgs","repos_url":"https://api.github.com/users/citra-emu/repos","events_url":"https://api.github.com/users/citra-emu/events{/privacy}","received_events_url":"https://api.github.com/users/citra-emu/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/citra-emu/citra","description":"Nintendo 3DS emulator/debugger","fork":false,"url":"https://api.github.com/repos/citra-emu/citra","forks_url":"https://api.github.com/repos/citra-emu/citra/forks","keys_url":"https://api.github.com/repos/citra-emu/citra/keys{/key_id}","collaborators_url":"https://api.github.com/repos/citra-emu/citra/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/citra-emu/citra/teams","hooks_url":"https://api.github.com/repos/citra-emu/citra/hooks","issue_events_url":"https://api.github.com/repos/citra-emu/citra/issues/events{/number}","events_url":"https://api.github.com/repos/citra-emu/citra/events","assignees_url":"https://api.github.com/repos/citra-emu/citra/assignees{/user}","branches_url":"https://api.github.com/repos/citra-emu/citra/branches{/branch}","tags_url":"https://api.github.com/repos/citra-emu/citra/tags","blobs_url":"https://api.github.com/repos/citra-emu/citra/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/citra-emu/citra/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/citra-emu/citra/git/refs{/sha}","trees_url":"https://api.github.com/repos/citra-emu/citra/git/trees{/sha}","statuses_url":"https://api.github.com/repos/citra-emu/citra/statuses/{sha}","languages_url":"https://api.github.com/repos/citra-emu/citra/languages","stargazers_url":"https://api.github.com/repos/citra-emu/citra/stargazers","contributors_url":"https://api.github.com/repos/citra-emu/citra/contributors","subscribers_url":"https://api.github.com/repos/citra-emu/citra/subscribers","subscription_url":"https://api.github.com/repos/citra-emu/citra/subscription","commits_url":"https://api.github.com/repos/citra-emu/citra/commits{/sha}","git_commits_url":"https://api.github.com/repos/citra-emu/citra/git/commits{/sha}","comments_url":"https://api.github.com/repos/citra-emu/citra/comments{/number}","issue_comment_url":"https://api.github.com/repos/citra-emu/citra/issues/comments{/number}","contents_url":"https://api.github.com/repos/citra-emu/citra/contents/{+path}","compare_url":"https://api.github.com/repos/citra-emu/citra/compare/{base}...{head}","merges_url":"https://api.github.com/repos/citra-emu/citra/merges","archive_url":"https://api.github.com/repos/citra-emu/citra/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/citra-emu/citra/downloads","issues_url":"https://api.github.com/repos/citra-emu/citra/issues{/number}","pulls_url":"https://api.github.com/repos/citra-emu/citra/pulls{/number}","milestones_url":"https://api.github.com/repos/citra-emu/citra/milestones{/number}","notifications_url":"https://api.github.com/repos/citra-emu/citra/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/citra-emu/citra/labels{/name}","releases_url":"https://api.github.com/repos/citra-emu/citra/releases{/id}","created_at":"2014-05-16T18:33:15Z","updated_at":"2015-05-15T09:30:30Z","pushed_at":"2015-05-15T13:44:40Z","git_url":"git://github.com/citra-emu/citra.git","ssh_url":"git@github.com:citra-emu/citra.git","clone_url":"https://github.com/citra-emu/citra.git","svn_url":"https://github.com/citra-emu/citra","homepage":null,"size":23111,"stargazers_count":828,"watchers_count":828,"language":"C++","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":206,"mirror_url":null,"open_issues_count":59,"forks":206,"open_issues":59,"watchers":828,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/citra-emu/citra/pulls/753"},"html":{"href":"https://github.com/citra-emu/citra/pull/753"},"issue":{"href":"https://api.github.com/repos/citra-emu/citra/issues/753"},"comments":{"href":"https://api.github.com/repos/citra-emu/citra/issues/753/comments"},"review_comments":{"href":"https://api.github.com/repos/citra-emu/citra/pulls/753/comments"},"review_comment":{"href":"https://api.github.com/repos/citra-emu/citra/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/citra-emu/citra/pulls/753/commits"},"statuses":{"href":"https://api.github.com/repos/citra-emu/citra/statuses/72d7acd72607badd5a75092bfea03c4b92cb2e19"}}}}