void pong_idle(){ static point_t orb = {XRES/2, YRES/2}; point_t *points = draw_get_back_buffer(); for(uint8_t i = 0; i < PADDLE_WIDTH; ++i){ for(uint8_t j = 0; j < PADDLE_HEIGHT; ++j){ uint8_t l_offs = PADDLE_LEFT_OFFSET + i*PADDLE_HEIGHT + j; uint8_t r_offs = PADDLE_RIGHT_OFFSET + i*PADDLE_HEIGHT + j; delta_t d_l = { (XRES/2 - points[l_offs].x)/8, (YRES/2 - points[l_offs].y)/8 }; delta_t d_r = { (XRES/2 - points[r_offs].x)/8, (YRES/2 - points[r_offs].y)/8 }; points[l_offs].x = CLAMP_X(points[l_offs].x + d_l.x); points[l_offs].y = CLAMP_Y(points[l_offs].y + d_l.y); points[r_offs].x = CLAMP_X(points[r_offs].x + d_r.x); points[r_offs].y = CLAMP_Y(points[r_offs].y + d_r.y); } } }
bool GLDriver::checkActiveSamplers() { // TODO: Vertex Samplers, Geometry Samplers // Pixel samplers id 0...16 for (auto i = 0; i < latte::MaxSamplers; ++i) { auto sq_tex_sampler_word0 = getRegister<latte::SQ_TEX_SAMPLER_WORD0_N>(latte::Register::SQ_TEX_SAMPLER_WORD0_0 + 4 * (i * 3)); auto sq_tex_sampler_word1 = getRegister<latte::SQ_TEX_SAMPLER_WORD1_N>(latte::Register::SQ_TEX_SAMPLER_WORD1_0 + 4 * (i * 3)); auto sq_tex_sampler_word2 = getRegister<latte::SQ_TEX_SAMPLER_WORD2_N>(latte::Register::SQ_TEX_SAMPLER_WORD2_0 + 4 * (i * 3)); // TODO: is there a sampler bit that indicates this, maybe word2.TYPE? auto sq_tex_resource_word0 = getRegister<latte::SQ_TEX_RESOURCE_WORD0_N>(latte::Register::SQ_TEX_RESOURCE_WORD0_0 + latte::SQ_PS_TEX_RESOURCE_0 + 4 * (i * 7)); auto depthCompare = sq_tex_resource_word0.TILE_TYPE(); if (sq_tex_sampler_word0.value == mPixelSamplerCache[i].word0 && sq_tex_sampler_word1.value == mPixelSamplerCache[i].word1 && sq_tex_sampler_word2.value == mPixelSamplerCache[i].word2 && depthCompare == mPixelSamplerCache[i].depthCompare) { continue; // No change in sampler state } mPixelSamplerCache[i].word0 = sq_tex_sampler_word0.value; mPixelSamplerCache[i].word1 = sq_tex_sampler_word1.value; mPixelSamplerCache[i].word2 = sq_tex_sampler_word2.value; mPixelSamplerCache[i].depthCompare = depthCompare; if (sq_tex_sampler_word0.value == 0 && sq_tex_sampler_word1.value == 0 && sq_tex_sampler_word2.value == 0) { gl::glBindSampler(i, 0); continue; } auto &sampler = mPixelSamplers[i]; if (!sampler.object) { gl::glCreateSamplers(1, &sampler.object); } // Texture clamp auto clamp_x = getTextureWrap(sq_tex_sampler_word0.CLAMP_X()); auto clamp_y = getTextureWrap(sq_tex_sampler_word0.CLAMP_Y()); auto clamp_z = getTextureWrap(sq_tex_sampler_word0.CLAMP_Z()); gl::glSamplerParameteri(sampler.object, gl::GL_TEXTURE_WRAP_S, static_cast<gl::GLint>(clamp_x)); gl::glSamplerParameteri(sampler.object, gl::GL_TEXTURE_WRAP_T, static_cast<gl::GLint>(clamp_y)); gl::glSamplerParameteri(sampler.object, gl::GL_TEXTURE_WRAP_R, static_cast<gl::GLint>(clamp_z)); // Texture filter auto xy_min_filter = getTextureXYFilter(sq_tex_sampler_word0.XY_MIN_FILTER()); auto xy_mag_filter = getTextureXYFilter(sq_tex_sampler_word0.XY_MAG_FILTER()); gl::glSamplerParameteri(sampler.object, gl::GL_TEXTURE_MIN_FILTER, static_cast<gl::GLint>(xy_min_filter)); gl::glSamplerParameteri(sampler.object, gl::GL_TEXTURE_MAG_FILTER, static_cast<gl::GLint>(xy_mag_filter)); // Setup border color auto border_color_type = sq_tex_sampler_word0.BORDER_COLOR_TYPE(); std::array<float, 4> colors; switch (border_color_type) { case latte::SQ_TEX_BORDER_COLOR_TRANS_BLACK: colors = { 0.0f, 0.0f, 0.0f, 0.0f }; break; case latte::SQ_TEX_BORDER_COLOR_OPAQUE_BLACK: colors = { 0.0f, 0.0f, 0.0f, 1.0f }; break; case latte::SQ_TEX_BORDER_COLOR_OPAQUE_WHITE: colors = { 1.0f, 1.0f, 1.0f, 0.0f }; break; case latte::SQ_TEX_BORDER_COLOR_REGISTER: { auto td_ps_sampler_border_red = getRegister<latte::TD_PS_SAMPLER_BORDERN_RED>(latte::Register::TD_PS_SAMPLER_BORDER0_RED + 4 * (i * 4)); auto td_ps_sampler_border_green = getRegister<latte::TD_PS_SAMPLER_BORDERN_GREEN>(latte::Register::TD_PS_SAMPLER_BORDER0_GREEN + 4 * (i * 4)); auto td_ps_sampler_border_blue = getRegister<latte::TD_PS_SAMPLER_BORDERN_BLUE>(latte::Register::TD_PS_SAMPLER_BORDER0_BLUE + 4 * (i * 4)); auto td_ps_sampler_border_alpha = getRegister<latte::TD_PS_SAMPLER_BORDERN_ALPHA>(latte::Register::TD_PS_SAMPLER_BORDER0_ALPHA + 4 * (i * 4)); colors = { td_ps_sampler_border_red.BORDER_RED, td_ps_sampler_border_green.BORDER_GREEN, td_ps_sampler_border_blue.BORDER_BLUE, td_ps_sampler_border_alpha.BORDER_ALPHA, }; break; } default: decaf_abort(fmt::format("Unsupported border_color_type = {}", border_color_type)); } gl::glSamplerParameterfv(sampler.object, gl::GL_TEXTURE_BORDER_COLOR, &colors[0]); // Depth compare auto mode = depthCompare ? gl::GL_COMPARE_REF_TO_TEXTURE : gl::GL_NONE; gl::glSamplerParameteri(sampler.object, gl::GL_TEXTURE_COMPARE_MODE, static_cast<gl::GLint>(mode)); auto depth_compare_function = getTextureCompareFunction(sq_tex_sampler_word0.DEPTH_COMPARE_FUNCTION()); gl::glSamplerParameteri(sampler.object, gl::GL_TEXTURE_COMPARE_FUNC, static_cast<gl::GLint>(depth_compare_function)); // Setup texture LOD auto min_lod = sq_tex_sampler_word1.MIN_LOD(); auto max_lod = sq_tex_sampler_word1.MAX_LOD(); auto lod_bias = sq_tex_sampler_word1.LOD_BIAS(); // TODO: GL_TEXTURE_MIN_LOD, GL_TEXTURE_MAX_LOD, GL_TEXTURE_LOD_BIAS // Bind sampler gl::glBindSampler(i, sampler.object); } return true; }