diff --git a/models/cmr12.egg b/models/cmr12.egg index 375273e679..d8656e27fd 100644 --- a/models/cmr12.egg +++ b/models/cmr12.egg @@ -1815,6 +1815,14 @@ 0.978659 0 0 } 476 { + 0.0080542 0.491814264 0 + { 0.948538 0.34035628 } + } + 477 { + 0.267978 0.491814264 0 + { 0.98848 0.34035628 } + } + 478 { 0 1 0 } } @@ -2673,9 +2681,18 @@ { 460 { vpool } } } } + 305 { + { + { chars } + { 276 277 476 477 { vpool } } + } + { + { 280 { vpool } } + } + } ds { { - { 476 { vpool } } + { 478 { vpool } } } } } diff --git a/models/cmss12.egg b/models/cmss12.egg index 4b1915d088..0c531838ca 100644 --- a/models/cmss12.egg +++ b/models/cmss12.egg @@ -1815,6 +1815,14 @@ 0.978659 0 0 } 476 { + 0.174627 0.506365 0 + { 0.531719 0.544 } + } + 477 { + 0.0428523 0.506365 0 + { 0.510343 0.544 } + } + 478 { 0 1 0 } } @@ -2673,9 +2681,18 @@ { 460 { vpool } } } } + 305 { + { + { chars } + { 231 232 476 477 { vpool } } + } + { + { 235 { vpool } } + } + } ds { { - { 476 { vpool } } + { 478 { vpool } } } } } diff --git a/models/cmtt12.egg b/models/cmtt12.egg index fb6fea56d3..b44c9bb322 100644 --- a/models/cmtt12.egg +++ b/models/cmtt12.egg @@ -1815,6 +1815,14 @@ 0.518605 0 0 } 476 { + 0.0609865 0.4672 0 + { 0.305895 0.43927125 } + } + 477 { + 0.457619 0.4672 0 + { 0.37422 0.43927125 } + } + 478 { 0 1 0 } } @@ -2678,9 +2686,18 @@ { 465 { vpool } } } } + 305 { + { + { chars } + { 221 222 476 477 { vpool } } + } + { + { 225 { vpool } } + } + } ds { { - { 476 { vpool } } + { 478 { vpool } } } } } diff --git a/panda/src/device/winRawInputDevice.cxx b/panda/src/device/winRawInputDevice.cxx index 010766edf0..96c9b1adbe 100644 --- a/panda/src/device/winRawInputDevice.cxx +++ b/panda/src/device/winRawInputDevice.cxx @@ -81,6 +81,10 @@ static const struct DeviceMapping { {0x054c, 0x0ba0, InputDevice::DeviceClass::gamepad, QB_rstick_from_z, {"face_x", "face_a", "face_b", "face_y", "lshoulder", "rshoulder", 0, 0, "back", "start", "lstick", "rstick", "guide", 0} }, + // PS2 controller connected through a USB adapter + {0x2563, 0x0523, InputDevice::DeviceClass::gamepad, QB_rstick_from_z | QB_no_analog_triggers, + {"face_y", "face_b", "face_a", "face_x", "lshoulder", "rshoulder", "ltrigger", "rtrigger", "back", "start", "lstick", "rstick"} + }, {0}, }; diff --git a/panda/src/glstuff/glGraphicsBuffer_src.cxx b/panda/src/glstuff/glGraphicsBuffer_src.cxx index ebabce3908..4627f89d5c 100644 --- a/panda/src/glstuff/glGraphicsBuffer_src.cxx +++ b/panda/src/glstuff/glGraphicsBuffer_src.cxx @@ -283,6 +283,12 @@ begin_frame(FrameMode mode, Thread *current_thread) { } else if (mode == FM_refresh) { // Just bind the FBO. rebuild_bitplanes(); + + // Bind the non-multisample FBO, since we won't be rendering anything and + // the caller probably wanted to grab a screenshot. + if (_fbo_multisample != 0 && !_fbo.empty()) { + glgsg->bind_fbo(_fbo[0]); + } } // The host window may not have had sRGB enabled, so we need to do this. @@ -1328,11 +1334,12 @@ end_frame(FrameMode mode, Thread *current_thread) { nassertv(_gsg != nullptr); // Resolve Multisample rendering if using it. - if (_requested_multisamples && _fbo_multisample) { + if (_requested_multisamples && _fbo_multisample && mode != FM_refresh) { resolve_multisamples(); } if (mode == FM_render) { + // Should happen *after* resolving multisamples, with the non-MS FBO bound. copy_to_textures(); } diff --git a/panda/src/text/textGlyph.cxx b/panda/src/text/textGlyph.cxx index bb8d998175..ca9973ee6e 100644 --- a/panda/src/text/textGlyph.cxx +++ b/panda/src/text/textGlyph.cxx @@ -171,66 +171,63 @@ check_quad_geom() { // Check that the vertices are arranged in a square. GeomVertexReader vertex(vdata, InternalName::get_vertex()); + GeomVertexReader texcoord(vdata, InternalName::get_texcoord()); LVecBase3 v = vertex.get_data3(); if (!IS_NEARLY_ZERO(v[1])) { return; } + LTexCoord uv(0); + if (texcoord.has_column()) { + uv = texcoord.get_data2(); + } PN_stdfloat minx = v[0]; PN_stdfloat maxx = v[0]; PN_stdfloat miny = v[2]; PN_stdfloat maxy = v[2]; + PN_stdfloat minu = uv[0]; + PN_stdfloat maxu = uv[0]; + PN_stdfloat minv = uv[1]; + PN_stdfloat maxv = uv[1]; - for (int i = 0; i < 3; ++i) { + for (int i = 1; i < 4; ++i) { v = vertex.get_data3(); if (!IS_NEARLY_ZERO(v[1])) { return; } + if (texcoord.has_column()) { + uv = texcoord.get_data2(); + } if (!IS_NEARLY_EQUAL(v[0], minx) && !IS_NEARLY_EQUAL(v[0], maxx)) { if (!IS_NEARLY_EQUAL(minx, maxx)) { return; } - minx = min(v[0], minx); - maxx = max(v[0], maxx); + if (v[0] < minx) { + minx = v[0]; + minu = uv[0]; + } + if (v[0] > maxx) { + maxx = v[0]; + maxu = uv[0]; + } } if (!IS_NEARLY_EQUAL(v[2], miny) && !IS_NEARLY_EQUAL(v[2], maxy)) { if (!IS_NEARLY_EQUAL(miny, maxy)) { return; } - miny = min(v[2], miny); - maxy = max(v[2], maxy); + if (v[2] < miny) { + miny = v[2]; + minv = uv[1]; + } + if (v[2] > maxy) { + maxy = v[2]; + maxv = uv[1]; + } } - } - - PN_stdfloat minu = 0; - PN_stdfloat maxu = 0; - PN_stdfloat minv = 0; - PN_stdfloat maxv = 0; - - // Same for the texcoord data. - if (format->has_column(InternalName::get_texcoord())) { - GeomVertexReader texcoord(vdata, InternalName::get_texcoord()); - LVecBase2 tc = texcoord.get_data2(); - minu = tc[0]; - maxu = tc[0]; - minv = tc[1]; - maxv = tc[1]; - - for (int i = 0; i < 3; ++i) { - tc = texcoord.get_data2(); - if (!IS_NEARLY_EQUAL(tc[0], minu) && !IS_NEARLY_EQUAL(tc[0], maxu)) { - if (!IS_NEARLY_EQUAL(minu, maxu)) { - return; - } - minu = min(tc[0], minu); - maxu = max(tc[0], maxu); - } - if (!IS_NEARLY_EQUAL(tc[1], minv) && !IS_NEARLY_EQUAL(tc[1], maxv)) { - if (!IS_NEARLY_EQUAL(minv, maxv)) { - return; - } - minv = min(tc[1], minv); - maxv = max(tc[1], maxv); - } + if (!IS_NEARLY_EQUAL(uv[0], minu) && !IS_NEARLY_EQUAL(uv[0], maxu)) { + return; + } + if (!IS_NEARLY_EQUAL(uv[1], minv) && !IS_NEARLY_EQUAL(uv[1], maxv)) { + return; } } diff --git a/panda/src/x11display/x11GraphicsWindow.cxx b/panda/src/x11display/x11GraphicsWindow.cxx index 51a1a3eff7..c6739c3bf3 100644 --- a/panda/src/x11display/x11GraphicsWindow.cxx +++ b/panda/src/x11display/x11GraphicsWindow.cxx @@ -2135,14 +2135,49 @@ get_keyboard_map() const { // Compose a label for some keys; I have not yet been able to find an API // that does this effectively. - if (sym >= XK_a && sym <= XK_z) { + if (sym >= XK_exclam && sym <= XK_asciitilde) { label = toupper((char)sym); } else if (sym >= XK_F1 && sym <= XK_F35) { label = "F" + format_string(sym - XK_F1 + 1); } - else if (sym >= XK_exclamdown && sym <= XK_ydiaeresis) { - // A latin-1 symbol. Translate this to the label. + else if (sym > 0x1000000 && sym < 0x1110000) { + // Unicode code point. Encode as UTF-8. + char32_t ch = sym & 0x0ffffff; + if ((ch & ~0x7f) == 0) { + label = string(1, (char)ch); + } + else if ((ch & ~0x7ff) == 0) { + label = + string(1, (char)((ch >> 6) | 0xc0)) + + string(1, (char)((ch & 0x3f) | 0x80)); + } + else if ((ch & ~0xffff) == 0) { + label = + string(1, (char)((ch >> 12) | 0xe0)) + + string(1, (char)(((ch >> 6) & 0x3f) | 0x80)) + + string(1, (char)((ch & 0x3f) | 0x80)); + } + else { + label = + string(1, (char)((ch >> 18) | 0xf0)) + + string(1, (char)(((ch >> 12) & 0x3f) | 0x80)) + + string(1, (char)(((ch >> 6) & 0x3f) | 0x80)) + + string(1, (char)((ch & 0x3f) | 0x80)); + } + } + else if ((sym >= XK_exclamdown && sym <= XK_umacron) + || (sym >= XK_OE && sym <= XK_Ydiaeresis) + || (sym >= XK_Serbian_dje && sym <= XK_Cyrillic_HARDSIGN) + || (sym >= XK_kana_fullstop && sym <= XK_semivoicedsound) + || (sym >= XK_Arabic_comma && sym <= XK_Arabic_sukun) + || (sym >= XK_Greek_ALPHAaccent && sym <= XK_Greek_omega) + || (sym >= XK_hebrew_doublelowline && sym <= XK_hebrew_taw) + || (sym >= XK_Thai_kokai && sym <= XK_Thai_lekkao) + || (sym >= XK_Hangul_Kiyeog && sym <= XK_Hangul_J_YeorinHieuh) + || sym == XK_EuroSign + || sym == XK_Korean_Won) { + // A non-unicode-based keysym. Translate this to the label. char buffer[255]; int nbytes = XkbTranslateKeySym(_display, &sym, 0, buffer, 255, 0); if (nbytes > 0) {