diff --git a/.vs/launch.vs.json b/.vs/launch.vs.json index 3ed316dce2..28f29df1e7 100644 --- a/.vs/launch.vs.json +++ b/.vs/launch.vs.json @@ -117,6 +117,13 @@ "name": "Game - Jak 2 - Runtime", "args": ["-v", "--game", "jak2", "--", "-fakeiso", "-debug"] }, + { + "type": "default", + "project": "CMakeLists.txt", + "projectTarget": "gk.exe (bin\\gk.exe)", + "name": "Game - Jak 2 - Runtime (boot)", + "args": ["-v", "--game", "jak2", "--", "-boot", "-fakeiso", "-debug"] + }, { "type": "default", "project": "CMakeLists.txt", diff --git a/common/util/FileUtil.cpp b/common/util/FileUtil.cpp index 865c2be9f5..47ca2517cb 100644 --- a/common/util/FileUtil.cpp +++ b/common/util/FileUtil.cpp @@ -409,11 +409,16 @@ void ISONameFromAnimationName(char* dst, const char* src) { // some special case words map to special letters (likely to avoid animation name conflicts) if (next_ptr - src_ptr == 10 && !memcmp(src_ptr, "resolution", 10)) { + // NOTE : jak 2 also allows "res" here but that doesn't work properly. char_to_add = 'z'; } else if (next_ptr - src_ptr == 6 && !memcmp(src_ptr, "accept", 6)) { char_to_add = 'y'; } else if (next_ptr - src_ptr == 6 && !memcmp(src_ptr, "reject", 6)) { char_to_add = 'n'; + } else if (next_ptr - src_ptr == 5 && !memcmp(src_ptr, "keira", 5)) { + // NOTE : this was added in jak 2. it's safe to use in jak 1 since she was referred to as + // "assistant" there + char_to_add = 'i'; } else { // not a special case, just take the first letter. char_to_add = *src_ptr; diff --git a/decompiler/config/jak2/all-types.gc b/decompiler/config/jak2/all-types.gc index 7546cf7396..ef4d1f84a0 100644 --- a/decompiler/config/jak2/all-types.gc +++ b/decompiler/config/jak2/all-types.gc @@ -4440,7 +4440,7 @@ ((on-screen int32 :offset-assert 4) (last-screen int32 :offset-assert 8) (frames display-frame 2 :offset-assert 12) - (bgcolor uint64 :offset-assert 24) + (bgcolor gs-bgcolor :offset-assert 24) (pmode gs-pmode :offset-assert 32) (clock clock 13 :offset-assert 40) (session-clock clock :offset 40) diff --git a/game/graphics/opengl_renderer/OpenGLRenderer.cpp b/game/graphics/opengl_renderer/OpenGLRenderer.cpp index 8ab9e0218d..25dfdcfd07 100644 --- a/game/graphics/opengl_renderer/OpenGLRenderer.cpp +++ b/game/graphics/opengl_renderer/OpenGLRenderer.cpp @@ -98,6 +98,7 @@ void OpenGLRenderer::init_bucket_renderers_jak2() { init_bucket_renderer("sky-draw", BucketCategory::OTHER, BucketId::SKY_DRAW, 1024); init_bucket_renderer("ocean-mid-far", BucketCategory::OCEAN, BucketId::OCEAN_MID_FAR); + // hardcoded level number!!! for (int i = 0; i < 6; ++i) { #define GET_BUCKET_ID_FOR_LIST(bkt1, bkt2, idx) ((int)(bkt1) + ((int)(bkt2) - (int)(bkt1)) * (idx)) init_bucket_renderer( @@ -143,6 +144,9 @@ void OpenGLRenderer::init_bucket_renderers_jak2() { fmt::format("etie-t-l{}-alpha", i), BucketCategory::TIE, GET_BUCKET_ID_FOR_LIST(BucketId::ETIE_T_L0_ALPHA, BucketId::ETIE_T_L1_ALPHA, i), tie, tfrag3::TieCategory::TRANS_ENVMAP); + init_bucket_renderer( + fmt::format("merc-l{}-alpha", i), BucketCategory::MERC, + GET_BUCKET_ID_FOR_LIST(BucketId::MERC_L0_ALPHA, BucketId::MERC_L1_ALPHA, i)); init_bucket_renderer( fmt::format("tex-l{}-pris", i), BucketCategory::TEX, diff --git a/game/graphics/opengl_renderer/background/Tie3.cpp b/game/graphics/opengl_renderer/background/Tie3.cpp index 3ad32be415..e0024cd1ce 100644 --- a/game/graphics/opengl_renderer/background/Tie3.cpp +++ b/game/graphics/opengl_renderer/background/Tie3.cpp @@ -580,7 +580,8 @@ void Tie3::draw_matching_draws_for_tree(int idx, last_texture = draw.tree_tex_id; } - auto double_draw = setup_tfrag_shader(render_state, draw.mode, ShaderId::TFRAG3); + auto double_draw = setup_tfrag_shader(render_state, draw.mode, + use_envmap ? ShaderId::ETIE_BASE : ShaderId::TFRAG3); glUniform1i(use_envmap ? m_etie_base_uniforms.decal : m_uniforms.decal, draw.mode.get_decal() ? 1 : 0); @@ -991,4 +992,4 @@ void Tie3AnotherCategory::render(DmaFollower& dma, ASSERT(false); } m_parent->render_from_another(render_state, prof, m_category); -} \ No newline at end of file +} diff --git a/game/graphics/opengl_renderer/background/background_common.cpp b/game/graphics/opengl_renderer/background/background_common.cpp index b24d2196e9..e1235e8a70 100644 --- a/game/graphics/opengl_renderer/background/background_common.cpp +++ b/game/graphics/opengl_renderer/background/background_common.cpp @@ -157,9 +157,13 @@ DoubleDraw setup_opengl_from_draw_mode(DrawMode mode, u32 tex_unit, bool mipmap) DoubleDraw setup_tfrag_shader(SharedRenderState* render_state, DrawMode mode, ShaderId shader) { auto draw_settings = setup_opengl_from_draw_mode(mode, GL_TEXTURE0, true); - glUniform1f(glGetUniformLocation(render_state->shaders[shader].id(), "alpha_min"), - draw_settings.aref_first); - glUniform1f(glGetUniformLocation(render_state->shaders[shader].id(), "alpha_max"), 10.f); + auto sh_id = render_state->shaders[shader].id(); + if (auto u_id = glGetUniformLocation(sh_id, "alpha_min"); u_id != -1) { + glUniform1f(u_id, draw_settings.aref_first); + } + if (auto u_id = glGetUniformLocation(sh_id, "alpha_max"); u_id != -1) { + glUniform1f(u_id, 10.f); + } return draw_settings; } diff --git a/game/overlord/isocommon.cpp b/game/overlord/isocommon.cpp index 47614cd6e1..cfbaa266b7 100644 --- a/game/overlord/isocommon.cpp +++ b/game/overlord/isocommon.cpp @@ -154,11 +154,16 @@ void ISONameFromAnimationName(char* dst, const char* src) { // some special case words map to special letters (likely to avoid animation name conflicts) if (next_ptr - src_ptr == 10 && !memcmp(src_ptr, "resolution", 10)) { + // NOTE : jak 2 also allows "res" here but that doesn't work properly. char_to_add = 'z'; } else if (next_ptr - src_ptr == 6 && !memcmp(src_ptr, "accept", 6)) { char_to_add = 'y'; } else if (next_ptr - src_ptr == 6 && !memcmp(src_ptr, "reject", 6)) { char_to_add = 'n'; + } else if (next_ptr - src_ptr == 5 && !memcmp(src_ptr, "keira", 5)) { + // NOTE : this was added in jak 2. it's safe to use in jak 1 since she was referred to as + // "assistant" there + char_to_add = 'i'; } else { // not a special case, just take the first letter. char_to_add = *src_ptr; diff --git a/goal_src/jak2/engine/debug/debug.gc b/goal_src/jak2/engine/debug/debug.gc index a579b6a2e8..50b4a61725 100644 --- a/goal_src/jak2/engine/debug/debug.gc +++ b/goal_src/jak2/engine/debug/debug.gc @@ -1417,41 +1417,16 @@ Most functions take a boolean as their first argument. If the boolean is set to (if (not enable) (return #f) ) - (when (!= (-> light extra x) 0.0) - (add-debug-vector - enable - bucket - position - (-> light direction) - (meters 3) - (new 'static 'rgba :r #xff :g #xff :b #xff :a #x80) - ) - (let ((sphere-pos (new-stack-vector0))) - (let ((v1-3 (-> light direction))) - (let ((a0-3 (* 12288.0 (-> light extra x)))) - (.mov vf7 a0-3) - ) - (.lvf vf5 (&-> v1-3 quad)) - ) - (.lvf vf4 (&-> position quad)) - (.add.x.vf vf6 vf0 vf0 :mask #b1000) - (.mul.x.vf acc vf5 vf7 :mask #b111) - (.add.mul.w.vf vf6 vf4 vf0 acc :mask #b111) - (.svf (&-> sphere-pos quad) vf6) - (let ((color-rgba (logior (logior (logior (shr (shl (the int (* 128.0 (-> light color w))) 56) 32) - (shr (shl (the int (* 128.0 (-> light color z))) 56) 40) - ) - (shr (shl (the int (* 128.0 (-> light color y))) 56) 48) - ) - (shr (shl (the int (* 128.0 (-> light color x))) 56) 56) - ) - ) - ) - (format (clear *temp-string*) "~S ~,,2f" text (-> light extra x)) - (let ((t0-2 *temp-string*)) - (add-debug-text-sphere enable bucket sphere-pos (* 2048.0 (-> light extra x)) t0-2 (the-as rgba color-rgba)) - ) - ) + (when (!= (-> light level) 0.0) + (add-debug-vector enable bucket position (-> light direction) (meters 3) (static-rgba #xff #xff #xff #x80)) + (let ((light-vec-end (vector+*! (new-stack-vector0) position (-> light direction) (* (meters 3) (-> light level)))) + ;; the original code here uses w for alpha but that looks terrible + (light-rgba (new 'static 'rgba :r (the int (* 128.0 (-> light color x))) + :g (the int (* 128.0 (-> light color y))) + :b (the int (* 128.0 (-> light color z))) + :a 128 + ))) + (add-debug-text-sphere enable bucket light-vec-end (* (meters 0.5) (-> light level)) (string-format "~S ~,,2f" text (-> light level)) light-rgba) ) ) #f diff --git a/goal_src/jak2/engine/draw/drawable.gc b/goal_src/jak2/engine/draw/drawable.gc index 9f18c9bee0..9d3c8f3d72 100644 --- a/goal_src/jak2/engine/draw/drawable.gc +++ b/goal_src/jak2/engine/draw/drawable.gc @@ -1062,6 +1062,8 @@ (set! (-> dc shadow-ctrl settings shadow-dir w) shadow-dir-w) ) ) + + (#when PC_PORT (add-debug-lights *display-lights* (bucket-id debug2) (-> lg lights) (-> dc origin))) ) ) ) diff --git a/goal_src/jak2/engine/game/main-h.gc b/goal_src/jak2/engine/game/main-h.gc index 629de9133d..65f1c347af 100644 --- a/goal_src/jak2/engine/game/main-h.gc +++ b/goal_src/jak2/engine/game/main-h.gc @@ -178,6 +178,7 @@ (define *display-sprite-marks* #f) (define *display-sprite-spheres* #f) (define *display-entity-errors* #t) +(#when PC_PORT (define *display-lights* #f)) (define *display-instance-info* #f) (define *display-deci-count* #f) (define *sync-dma* #f) diff --git a/goal_src/jak2/engine/game/main.gc b/goal_src/jak2/engine/game/main.gc index d90d92ddb9..6e868a01dd 100644 --- a/goal_src/jak2/engine/game/main.gc +++ b/goal_src/jak2/engine/game/main.gc @@ -1328,34 +1328,43 @@ (define-extern entity-inspect-draw (function entity-debug-inspect object)) (entity-inspect-draw *entity-debug-inspect*) ) - (when *display-region-inside* - (format *stdcon* "~1kinside region:~%") - ;; go through active levels - (dotimes (lev-i (-> *level* length)) - (let ((lev (-> *level* level lev-i))) - (when (= (-> lev status) 'active) - (let ((region-trees (-> lev bsp region-trees))) - (when (nonzero? region-trees) - (let* ((s3-5 (-> region-trees length)) - (tree-i 0) - (region-tree (-> region-trees tree-i)) - ) - (while (< tree-i s3-5) - (let* ((s0-4 (-> region-tree data2 (+ (-> region-tree length) -1) length)) - (i 0) - (region (-> (the-as drawable-inline-array-region-prim (-> region-tree data2 (+ (-> region-tree length) -1))) data i)) - ) - (while (< i s0-4) - (when (region-method-9 (-> region region) (target-pos 0)) - (debug-draw-region region 0) - (format *stdcon* " region-~D~%" (-> region region id))) - (set! i (+ i 1)) - (set! region (-> (the-as drawable-inline-array-region-prim (-> region-tree data2 (+ (-> region-tree length) -1))) data i)) - ) + ;; go through active levels + (dotimes (lev-i (-> *level* length)) + (let ((lev (-> *level* level lev-i))) + (when (= (-> lev status) 'active) + (let ((region-trees (-> lev bsp region-trees))) + (when (nonzero? region-trees) + (let* ((s3-5 (-> region-trees length)) + (tree-i 0) + (region-tree (-> region-trees tree-i)) + ) + (while (< tree-i s3-5) + (let* ((s0-4 (-> region-tree data2 (+ (-> region-tree length) -1) length)) + (i 0) + (region (-> (the-as drawable-inline-array-region-prim (-> region-tree data2 (+ (-> region-tree length) -1))) data i)) + ) + (while (< i s0-4) + (let ((draw? #f)) + (when (and *display-region-inside* (region-method-9 (-> region region) (target-pos 0))) + (true! draw?) + (format *stdcon* "~1kinside region-~D (~A)~%" (-> region region id) (-> lev name))) + (when (and *region-debug-inspect* (or (= *region-debug-inspect* region) (and *merge-region-prims* (= (-> region region id) (-> *region-debug-inspect* region id))))) + (when (= *region-debug-inspect* region) + (format *stdcon* "~1kinspecting region-~D (~A)~%" (-> *region-debug-inspect* region id) (-> lev name)) + (format *stdcon* " on-enter: ~A~%" (-> *region-debug-inspect* region on-enter)) + (format *stdcon* " on-inside: ~A~%" (-> *region-debug-inspect* region on-inside)) + (format *stdcon* " on-exit: ~A~%" (-> *region-debug-inspect* region on-exit)) + ) + (true! draw?) + ) + (when draw? + (debug-draw-region region 0))) + (set! i (+ i 1)) + (set! region (-> (the-as drawable-inline-array-region-prim (-> region-tree data2 (+ (-> region-tree length) -1))) data i)) ) - (+! tree-i 1) - (set! region-tree (-> region-trees tree-i)) ) + (+! tree-i 1) + (set! region-tree (-> region-trees tree-i)) ) ) ) @@ -1363,15 +1372,6 @@ ) ) ) - (when *region-debug-inspect* - (format *stdcon* "~1kinspecting region-~D~%" (-> *region-debug-inspect* region id)) - (format *stdcon* " on-enter: ~A~%" (-> *region-debug-inspect* region on-enter)) - (format *stdcon* " on-inside: ~A~%" (-> *region-debug-inspect* region on-inside)) - (format *stdcon* " on-exit: ~A~%" (-> *region-debug-inspect* region on-exit)) - (when (or (not *display-region-inside*) (not (region-method-9 (-> *region-debug-inspect* region) (target-pos 0)))) - (debug-draw-region *region-debug-inspect* 0) - ) - ) ) ) (debug-draw-buffers) diff --git a/goal_src/jak2/engine/game/settings.gc b/goal_src/jak2/engine/game/settings.gc index 0ec6e3e61c..bc8f8522a1 100644 --- a/goal_src/jak2/engine/game/settings.gc +++ b/goal_src/jak2/engine/game/settings.gc @@ -1232,15 +1232,9 @@ (if (not (-> s5-0 allow-blackout)) (set! f0-71 0.0) ) - (set! (-> v1-133 bgcolor) - (logior (logand (-> v1-133 bgcolor) -256) (shr (shl (the int (* 255.0 (-> s5-0 bg-r))) 56) 56)) - ) - (set! (-> v1-133 bgcolor) - (logior (logand (-> v1-133 bgcolor) -65281) (shr (shl (the int (* 255.0 (-> s5-0 bg-g))) 56) 48)) - ) - (set! (-> v1-133 bgcolor) - (logior (logand (-> v1-133 bgcolor) -16711681) (shr (shl (the int (* 255.0 (-> s5-0 bg-b))) 56) 40)) - ) + (set! (-> v1-133 bgcolor r) (the int (* 255.0 (-> s5-0 bg-r)))) + (set! (-> v1-133 bgcolor g) (the int (* 255.0 (-> s5-0 bg-g)))) + (set! (-> v1-133 bgcolor b) (the int (* 255.0 (-> s5-0 bg-b)))) (set! (-> v1-133 pmode alp) (the int (* 255.0 (- 1.0 f0-71)))) ) (set! (-> v1-133 run-half-speed) (the-as basic (-> s5-0 half-speed))) diff --git a/goal_src/jak2/engine/gfx/hw/display-h.gc b/goal_src/jak2/engine/gfx/hw/display-h.gc index b3009b7d14..00592d0f06 100644 --- a/goal_src/jak2/engine/gfx/hw/display-h.gc +++ b/goal_src/jak2/engine/gfx/hw/display-h.gc @@ -59,7 +59,7 @@ At any point in time, there are 3 frames in progress: ((on-screen int32 :offset-assert 4) ;; frame index (0 or 1) (last-screen int32 :offset-assert 8) ;; frame index (0 or 1) (frames display-frame 2 :offset-assert 12) ;; per-frame dma/timing - (bgcolor uint64 :offset-assert 24) ;; GS setting + (bgcolor gs-bgcolor :offset-assert 24) ;; GS setting (pmode gs-pmode :offset-assert 32) ;; GS setting (clock clock 13 :offset-assert 40) (session-clock clock :offset 40) diff --git a/goal_src/jak2/engine/gfx/hw/video.gc b/goal_src/jak2/engine/gfx/hw/video.gc index f91cfd0416..c409b0a04c 100644 --- a/goal_src/jak2/engine/gfx/hw/video.gc +++ b/goal_src/jak2/engine/gfx/hw/video.gc @@ -130,7 +130,7 @@ Will also set a bunch of common settings related to profiling and the camera to ) ) (set! (-> gs-bank pmode) (-> display pmode)) - (set! (-> gs-bank bgcolor) (the-as gs-bgcolor (-> display bgcolor))) + (set! (-> gs-bank bgcolor) (-> display bgcolor)) ) (set! (-> gs-bank dspfb1) (new 'static 'gs-display-fb :fbw #xa :fbp (-> video-settings display-fbp))) ) diff --git a/goal_src/jak2/pc/debug/default-menu-pc.gc b/goal_src/jak2/pc/debug/default-menu-pc.gc index 17fd8c88aa..7e97364af0 100644 --- a/goal_src/jak2/pc/debug/default-menu-pc.gc +++ b/goal_src/jak2/pc/debug/default-menu-pc.gc @@ -601,16 +601,33 @@ (defun dm-region-pick-func ((r drawable-region-prim) (msg debug-menu-msg)) (when (= msg (debug-menu-msg press)) (if (= *region-debug-inspect* r) - (set! *region-debug-inspect* (the drawable-region-prim #f)) + (set! *region-debug-inspect* #f) (set! *region-debug-inspect* r)) ) (= *region-debug-inspect* r) ) -(defun build-regions-list () +(defun debug-menu-node-region (the-as drawable-region-prim (-> arg0 id)) region id) (-> (the-as drawable-region-prim (-> arg1 id)) region id)) + ) + +(defun array-uint32-value? ((arr (array uint32)) (val uint)) + (dotimes (i (-> arr length)) + (if (= val (-> arr i)) (return #t))) + #f) +(define *region-debug-id-list* (new 'static 'boxed-array :type uint32 :length 0 :allocated-length 2000)) + +(defun build-regions-list ((merge-prims? symbol)) "Fill the region pick menu" + ;; clear old list (debug-menu-remove-all-items *region-pick-menu*) + (set! *region-debug-inspect* #f) + (set! *merge-region-prims* merge-prims?) + (dotimes (i (-> *region-debug-id-list* allocated-length)) + (set! (-> *region-debug-id-list* i) -1)) + (set! (-> *region-debug-id-list* length) 0) + ;; go through active levels (dotimes (lev-i (-> *level* length)) (let ((lev (-> *level* level lev-i))) @@ -627,12 +644,18 @@ (region (-> (the-as drawable-inline-array-region-prim (-> region-tree data2 (+ (-> region-tree length) -1))) data i)) ) (while (< i s0-4) - (debug-menu-append-item *region-pick-menu* (new-dm-flag (new 'debug 'string 0 (string-format "region-~D" (-> region region id))) region dm-region-pick-func)) - (set! i (+ i 1)) + (when (or (not merge-prims?) (not (array-uint32-value? *region-debug-id-list* (-> region region id)))) + (debug-menu-append-item *region-pick-menu* (new-dm-flag (new 'debug 'string 0 (string-format "region-~D" (-> region region id))) region dm-region-pick-func)) + (when merge-prims? + (set! (-> *region-debug-id-list* (-> *region-debug-id-list* length)) (-> region region id)) + (1+! (-> *region-debug-id-list* length)) + ) + ) + (1+! i) (set! region (-> (the-as drawable-inline-array-region-prim (-> region-tree data2 (+ (-> region-tree length) -1))) data i)) ) ) - (+! tree-i 1) + (1+! tree-i) (set! region-tree (-> region-trees tree-i)) ) ) @@ -641,7 +664,8 @@ ) ) ) - (set! (-> *region-pick-menu* items) (sort (-> *region-pick-menu* items) debug-menu-node *region-pick-menu* items) (sort (-> *region-pick-menu* items) debug-menu-node-region s5-0 allow-blackout)) (set! f0-71 0.0) ) - (set! (-> v1-133 bgcolor) - (logior (logand (-> v1-133 bgcolor) -256) (shr (shl (the int (* 255.0 (-> s5-0 bg-r))) 56) 56)) - ) - (set! (-> v1-133 bgcolor) - (logior (logand (-> v1-133 bgcolor) -65281) (shr (shl (the int (* 255.0 (-> s5-0 bg-g))) 56) 48)) - ) - (set! (-> v1-133 bgcolor) - (logior (logand (-> v1-133 bgcolor) -16711681) (shr (shl (the int (* 255.0 (-> s5-0 bg-b))) 56) 40)) - ) + (set! (-> v1-133 bgcolor r) (the int (* 255.0 (-> s5-0 bg-r)))) + (set! (-> v1-133 bgcolor g) (the int (* 255.0 (-> s5-0 bg-g)))) + (set! (-> v1-133 bgcolor b) (the int (* 255.0 (-> s5-0 bg-b)))) (set! (-> v1-133 pmode alp) (the int (* 255.0 (- 1.0 f0-71)))) ) (set! (-> v1-133 run-half-speed) (the-as basic (-> s5-0 half-speed))) diff --git a/test/decompiler/reference/jak2/engine/gfx/hw/display-h_REF.gc b/test/decompiler/reference/jak2/engine/gfx/hw/display-h_REF.gc index 6ea9a53e38..1e753cb57f 100644 --- a/test/decompiler/reference/jak2/engine/gfx/hw/display-h_REF.gc +++ b/test/decompiler/reference/jak2/engine/gfx/hw/display-h_REF.gc @@ -60,7 +60,7 @@ ((on-screen int32 :offset-assert 4) (last-screen int32 :offset-assert 8) (frames display-frame 2 :offset-assert 12) - (bgcolor uint64 :offset-assert 24) + (bgcolor gs-bgcolor :offset-assert 24) (pmode gs-pmode :offset-assert 32) (clock clock 13 :offset-assert 40) (session-clock clock :offset 40) diff --git a/test/decompiler/reference/jak2/engine/gfx/hw/video_REF.gc b/test/decompiler/reference/jak2/engine/gfx/hw/video_REF.gc index 205034024e..061e247680 100644 --- a/test/decompiler/reference/jak2/engine/gfx/hw/video_REF.gc +++ b/test/decompiler/reference/jak2/engine/gfx/hw/video_REF.gc @@ -134,7 +134,7 @@ Will also set a bunch of common settings related to profiling and the camera to ) ) (set! (-> gs-bank pmode) (-> display pmode)) - (set! (-> gs-bank bgcolor) (the-as gs-bgcolor (-> display bgcolor))) + (set! (-> gs-bank bgcolor) (-> display bgcolor)) ) (set! (-> gs-bank dspfb1) (new 'static 'gs-display-fb :fbw #xa :fbp (-> video-settings display-fbp))) )