]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
Resolution/line mode/doublescan automatic integer aspect ratio option
authorToni Wilen <twilen@winuae.net>
Sat, 14 Mar 2026 14:58:29 +0000 (16:58 +0200)
committerToni Wilen <twilen@winuae.net>
Sat, 14 Mar 2026 14:58:29 +0000 (16:58 +0200)
cfgfile.cpp
custom.cpp
drawing.cpp
include/custom.h
include/drawing.h
include/options.h
od-win32/resources/resource.h
od-win32/resources/winuae.rc
od-win32/win32gui.cpp

index 0766f2feb2b2da6d279ea1f7cae07345397ffdfa..74958063740cdd32f6499bfa283c23ee61f628a7 100644 (file)
@@ -2470,6 +2470,7 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type)
        cfgfile_write_strarr(f, _T("gfx_fullscreen_picasso"), fullmodes, p->gfx_apmode[1].gfx_fullscreen);
        cfgfile_write_strarr(f, _T("gfx_center_horizontal"), centermode1, p->gfx_xcenter);
        cfgfile_write_strarr(f, _T("gfx_center_vertical"), centermode1, p->gfx_ycenter);
+       cfgfile_write_bool(f, _T("gfx_keep_aspect"), p->gfx_keep_aspect);
        cfgfile_write_str(f, _T("gfx_colour_mode"), _T("32bit"));
        cfgfile_write_bool(f, _T("gfx_blacker_than_black"), p->gfx_blackerthanblack);
        cfgfile_dwrite_bool(f, _T("gfx_monochrome"), p->gfx_grayscale);
@@ -3703,6 +3704,7 @@ static int cfgfile_parse_host (struct uae_prefs *p, TCHAR *option, TCHAR *value)
 
                || cfgfile_intval (option, value, _T("gfx_center_horizontal_size"), &p->gfx_xcenter_size, 1)
                || cfgfile_intval (option, value, _T("gfx_center_vertical_size"), &p->gfx_ycenter_size, 1)
+               || cfgfile_yesno(option, value, _T("gfx_keep_aspect"), &p->gfx_keep_aspect, 1)
 
                || cfgfile_intval (option, value, _T("filesys_max_size"), &p->filesys_limit, 1)
                || cfgfile_intval (option, value, _T("filesys_max_name_length"), &p->filesys_max_name, 1)
@@ -8571,6 +8573,7 @@ void default_prefs (struct uae_prefs *p, bool reset, int type)
        p->gfx_ycenter_pos = MANUAL_SCALE_MIN_RANGE - 1;
        p->gfx_xcenter_size = -1;
        p->gfx_ycenter_size = -1;
+       p->gfx_keep_aspect = false;
        p->gfx_max_horizontal = RES_HIRES;
        p->gfx_max_vertical = VRES_DOUBLE;
        p->gfx_autoresolution_minv = 0;
index 8eb6ec99a23d924ebe0ddf34e9335bbea583d40f..e302981fc1a4f6157adc6350c51456c75d5651ef 100644 (file)
@@ -2224,20 +2224,22 @@ static void init_beamcon0(void)
                }
                hpixelsd *= 2;
        }
-       bool dbl = line_is_doubled();
-       if (dbl) {
-               vpixels *= 2;
-       }
-       if (hpixelsd < vpixels) {
-               doublescan2x = 1;
-               hpixelsd *= 2;
-               if (hpixelsd < vpixels) {
-                       doublescan2x = 2;
+       if (currprefs.gfx_keep_aspect) {
+               bool dbl = line_is_doubled();
+               if (dbl) {
+                       vpixels *= 2;
                }
-       } else if (hpixelsd > vpixels * 2) {
-               doublescan2x = -1;
-               if (hpixelsd > vpixels * 4) {
-                       doublescan2x = -2;
+               if (hpixelsd < vpixels) {
+                       doublescan2x = 1;
+                       hpixelsd *= 2;
+                       if (hpixelsd < vpixels) {
+                               doublescan2x = 2;
+                       }
+               } else if (hpixelsd > vpixels * 2) {
+                       doublescan2x = -1;
+                       if (hpixelsd > vpixels * 4) {
+                               doublescan2x = -2;
+                       }
                }
        }
 
@@ -5168,6 +5170,10 @@ static void vsync_check_vsyncmode(void)
                }
        }
 
+       if (!current_linear_temp_change && denise_get_hbstate(false) && currprefs.cs_hvcsync < HVSYNC_SYNCPOS) {
+               current_linear_temp_change = 2;
+       }
+
        bool framesync = false;
        if (current_linear_temp_change > 0) {
                current_linear_temp_change--;
@@ -5191,7 +5197,7 @@ static void vsync_check_vsyncmode(void)
                                framesync = true;
                                display_redraw = true;
                        }
-                       if (current_linear_hblen != current_linear_hblen_temp) {
+                       if ((current_linear_hblen != current_linear_hblen_temp || denise_get_hbstate(true)) && currprefs.cs_hvcsync < HVSYNC_SYNCPOS) {
                                current_linear_hblen = current_linear_hblen_temp;
                                init_beamcon0();
                                framesync = true;
@@ -8907,7 +8913,8 @@ void check_prefs_changed_custom(void)
                currprefs.ntscmode != changed_prefs.ntscmode ||
                currprefs.cs_agnusmodel != changed_prefs.cs_agnusmodel ||
                currprefs.cs_denisemodel != changed_prefs.cs_denisemodel ||
-               currprefs.cs_hvcsync != changed_prefs.cs_hvcsync
+               currprefs.cs_hvcsync != changed_prefs.cs_hvcsync ||
+               currprefs.gfx_keep_aspect != changed_prefs.gfx_keep_aspect
                ) {
                        currprefs.picasso96_nocustom = changed_prefs.picasso96_nocustom;
                        if (currprefs.ntscmode != changed_prefs.ntscmode) {
@@ -8932,6 +8939,7 @@ void check_prefs_changed_custom(void)
                        currprefs.cs_agnusmodel = changed_prefs.cs_agnusmodel;
                        currprefs.cs_denisemodel = changed_prefs.cs_denisemodel;
                        currprefs.cs_hvcsync = changed_prefs.cs_hvcsync;
+                       currprefs.gfx_keep_aspect = changed_prefs.gfx_keep_aspect;
                        init_custom();
        }
 
@@ -12159,7 +12167,9 @@ static void do_cck(bool docycles)
 static uae_u16 quick_strobe(void)
 {
        uae_u16 str = get_strobe_reg(0);
+       agnus_trigger_cck -= 2;
        write_drga_strobe(str);
+       agnus_trigger_cck += 2;
        if (prev_strobe == 0x3c && str != 0x3c) {
                INTREQ_INT(5, 0);
        }
index abb89fe34a0c56129299a7086611ea12560a3160..6c1388165cac0ce78bdaf770676cbd8d4d7f5a9e 100644 (file)
@@ -445,6 +445,7 @@ static int linear_denise_hbstrt, linear_denise_hbstop;
 static int linear_denise_frame_hbstrt, linear_denise_frame_hbstop;
 static int linear_denise_frame_hbstrt_tmp, linear_denise_frame_hbstop_tmp;
 static int linear_denise_frame_hbstrt_sel, linear_denise_frame_hbstop_sel;
+static bool denise_blanking_changed;
 static int linear_denise_strobe_offset;
 static int denise_visible_lines, denise_visible_lines_counted;
 static uae_u16 hbstrt_denise_reg, hbstop_denise_reg;
@@ -1016,6 +1017,7 @@ int get_custom_limits(int *pw, int *ph, int *pdx, int *pdy, int *prealh, int *hr
 
        h = y2 - y1 + 1;
        dy = y1 - minfirstline_linear;
+       dy--;
 
        if (plffirstline_total >= 30000) {
                // no planes enabled during frame
@@ -1027,8 +1029,12 @@ int get_custom_limits(int *pw, int *ph, int *pdx, int *pdy, int *prealh, int *hr
                dx = 58;
        }
 
-       if (dx < 0)
+       if (dx < 0) {
                dx = 0;
+       }
+       if (dy < 0) {
+               dy = 0;
+       }
 
        *prealh = -1;
        if (programmedmode != 1 && plffirstline_total < 30000) {
@@ -4995,6 +5001,7 @@ static void denise_handle_quick_strobe(uae_u16 strobe, int offset, int vpos)
 {
        struct denise_rga rd = { 0 };
        rd.rga = strobe;
+       rd.v = 2;
        denise_hcounter_new += maxhpos * 2;
        denise_hcounter_new &= 511;
        denise_hcounter = denise_hcounter_new;
@@ -6204,6 +6211,7 @@ static void draw_denise_line(int gfx_ypos, enum nln_how how, uae_u32 linecnt, in
 
        frame_internal_pixel_cnt = internal_pixel_cnt;
 
+       // detect horizontal blanking
        if (!denise_vblank_active) {
                linear_denise_frame_hbstrt = linear_denise_hbstrt;
                linear_denise_frame_hbstop = linear_denise_hbstop;
@@ -6211,7 +6219,9 @@ static void draw_denise_line(int gfx_ypos, enum nln_how how, uae_u32 linecnt, in
 
                if (linear_denise_frame_hbstrt == linear_denise_frame_hbstrt_tmp && linear_denise_frame_hbstop == linear_denise_frame_hbstop_tmp) {
                        denise_hbstrt_relative_cnt++;
-                       if (denise_hbstrt_relative_cnt > 30) {
+                       if (denise_hbstrt_relative_cnt > maxvpos_display / 2) {
+                               int ss = linear_denise_frame_hbstrt_sel;
+                               int ee = linear_denise_frame_hbstop_sel;
                                linear_denise_frame_hbstrt_sel = linear_denise_frame_hbstrt_tmp;
                                linear_denise_frame_hbstop_sel = linear_denise_frame_hbstop_tmp;
                                if (linear_denise_frame_hbstrt_sel < 0 || linear_denise_frame_hbstop_sel < 0) {
@@ -6222,10 +6232,12 @@ static void draw_denise_line(int gfx_ypos, enum nln_how how, uae_u32 linecnt, in
                                                linear_denise_frame_hbstrt_sel -= internal_pixel_cnt;
                                        }
                                }
-                               linear_denise_strobe_offset += 2 * 8;
-                               linear_denise_frame_hbstrt_sel += linear_denise_strobe_offset;
-                               linear_denise_frame_hbstop_sel += linear_denise_strobe_offset;
+                               linear_denise_frame_hbstrt_sel += linear_denise_strobe_offset + 2 * 8;
+                               linear_denise_frame_hbstop_sel += linear_denise_strobe_offset + 2 * 8;
                                denise_hbstrt_relative_cnt = 0;
+                               if (ss != linear_denise_frame_hbstrt_sel || ee != linear_denise_frame_hbstop_sel) {
+                                       denise_blanking_changed = true;
+                               }
                        }
                } else {
                        linear_denise_frame_hbstrt_tmp = linear_denise_frame_hbstrt;
@@ -6292,6 +6304,15 @@ static void draw_denise_line(int gfx_ypos, enum nln_how how, uae_u32 linecnt, in
        lines_count++;
 }
 
+bool denise_get_hbstate(bool clear)
+{
+       bool v = denise_blanking_changed;
+       if (clear) {
+               denise_blanking_changed = false;
+       }
+       return v;
+}
+
 bool denise_get_hboffsets(int *hbs, int *hbe, int *hblen, int *total)
 {
        if (denise_afterreset) {
index 5bafd4fa7ac709c4c1ec5ca36f87bf42e6efd433..888bf27c0c5d3f8b0cbffd4311db7f2f2990435d 100644 (file)
@@ -140,7 +140,7 @@ extern int maxhpos, maxhposm0, maxhpos_short;
 extern int maxvpos, maxvpos_nom, maxvpos_display, maxvpos_display_vsync, maxhpos_display;
 extern int maxvsize_display;
 extern int hsyncstartpos_hw, hsyncendpos_hw;
-extern int minfirstline, minfirstline_linear, vblank_endline, numscrlines, minfirstline_linear;
+extern int minfirstline, minfirstline_linear, vblank_endline, numscrlines;
 extern float vblank_hz, fake_vblank_hz;
 extern float hblank_hz;
 extern int vblank_skip, doublescan, doublescan2x;
index 16c34420b9e6d89b32b4b5b3b767e3f28252084c..2bd86d684e45858c4f539995049afdb354a465e4 100644 (file)
@@ -204,5 +204,6 @@ void denise_clearbuffers(void);
 uae_u8 *get_row_genlock(int monid, int line);
 void drawing_free(void);
 bool denise_get_hboffsets(int *hbs, int *hbe, int *hblen, int *total);
+bool denise_get_hbstate(bool);
 
 #endif /* UAE_DRAWING_H */
index d5c621bbb3ba11c0ed48fb80c1e196c707dd98eb..0c45e40fadee49b000e6e626c632b00052ebb2ea 100644 (file)
@@ -620,6 +620,7 @@ struct uae_prefs {
        int gfx_xcenter_pos, gfx_ycenter_pos;
        int gfx_xcenter_size, gfx_ycenter_size;
        int gfx_max_horizontal, gfx_max_vertical;
+       bool gfx_keep_aspect;
        int gfx_saturation, gfx_luminance, gfx_contrast, gfx_gamma, gfx_gamma_ch[3];
        bool gfx_blackerthanblack;
        int gfx_threebitcolors;
index f77d59c9d886469c30d111fd5b9e7eb9a03d6653..914e565f5f09381e737c7976ffdc311a7801703d 100644 (file)
 #define IDC_ECS_AGNUS                   1521
 #define IDC_DISPLAY_RESIZE              1521
 #define IDC_ECS_DENISE                  1522
+#define IDC_RLMASPECT                   1522
 #define IDC_ECS                         1523
 #define IDC_AGA                         1524
 #define IDC_OCSA1000                    1525
index 25cccd48cf887a8a14f2523a7adedd3cffe0a855..a6f55184381c93ed3678f5198384d35673564b1b 100644 (file)
@@ -202,20 +202,22 @@ BEGIN
     CONTROL         "",IDC_DA_SLIDER,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,96,276,96,20
     EDITTEXT        IDC_DA_TEXT,205,280,56,12,ES_AUTOHSCROLL | ES_READONLY
     PUSHBUTTON      "Reset to defaults",IDC_DA_RESET,156,298,106,14
-    GROUPBOX        "Centering",IDC_STATIC,289,90,105,46
+    GROUPBOX        "Centering",IDC_STATIC,289,90,105,41
     CONTROL         "Horizontal",IDC_XCENTER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,300,104,90,10
-    CONTROL         "Vertical",IDC_YCENTER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,300,120,90,10
-    GROUPBOX        "Line mode",IDC_STATIC,290,138,104,81
-    CONTROL         "Single",IDC_LM_NORMAL,"Button",BS_AUTORADIOBUTTON | BS_LEFT | WS_GROUP | WS_TABSTOP,299,152,90,10
-    CONTROL         "Double",IDC_LM_DOUBLED,"Button",BS_AUTORADIOBUTTON | BS_LEFT | WS_TABSTOP,299,165,90,10
-    CONTROL         "Scanlines",IDC_LM_SCANLINES,"Button",BS_AUTORADIOBUTTON | BS_LEFT | WS_TABSTOP,299,178,90,10
-    CONTROL         "Double, fields",IDC_LM_PDOUBLED2,"Button",BS_AUTORADIOBUTTON | BS_LEFT | WS_TABSTOP,299,191,90,10
-    CONTROL         "Double, fields+",IDC_LM_PDOUBLED3,"Button",BS_AUTORADIOBUTTON | BS_LEFT | WS_TABSTOP,299,204,90,10
-    GROUPBOX        "Interlaced line mode",IDC_STATIC,290,226,104,70
-    CONTROL         "Single",IDC_LM_INORMAL,"Button",BS_AUTORADIOBUTTON | BS_LEFT | WS_GROUP | WS_TABSTOP,299,242,90,10
-    CONTROL         "Double, frames",IDC_LM_IDOUBLED,"Button",BS_AUTORADIOBUTTON | BS_LEFT | WS_TABSTOP,299,255,90,10
-    CONTROL         "Double, fields",IDC_LM_IDOUBLED2,"Button",BS_AUTORADIOBUTTON | BS_LEFT | WS_TABSTOP,299,268,90,10
-    CONTROL         "Double, fields+",IDC_LM_IDOUBLED3,"Button",BS_AUTORADIOBUTTON | BS_LEFT | WS_TABSTOP,299,281,90,10
+    CONTROL         "Vertical",IDC_YCENTER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,300,117,90,10
+    GROUPBOX        "Line mode",IDC_STATIC,290,159,104,81
+    CONTROL         "Single",IDC_LM_NORMAL,"Button",BS_AUTORADIOBUTTON | BS_LEFT | WS_GROUP | WS_TABSTOP,299,173,90,10
+    CONTROL         "Double",IDC_LM_DOUBLED,"Button",BS_AUTORADIOBUTTON | BS_LEFT | WS_TABSTOP,299,186,90,10
+    CONTROL         "Scanlines",IDC_LM_SCANLINES,"Button",BS_AUTORADIOBUTTON | BS_LEFT | WS_TABSTOP,299,199,90,10
+    CONTROL         "Double, fields",IDC_LM_PDOUBLED2,"Button",BS_AUTORADIOBUTTON | BS_LEFT | WS_TABSTOP,299,212,90,10
+    CONTROL         "Double, fields+",IDC_LM_PDOUBLED3,"Button",BS_AUTORADIOBUTTON | BS_LEFT | WS_TABSTOP,299,225,90,10
+    GROUPBOX        "Interlaced line mode",IDC_STATIC,290,242,104,70
+    CONTROL         "Single",IDC_LM_INORMAL,"Button",BS_AUTORADIOBUTTON | BS_LEFT | WS_GROUP | WS_TABSTOP,299,258,90,10
+    CONTROL         "Double, frames",IDC_LM_IDOUBLED,"Button",BS_AUTORADIOBUTTON | BS_LEFT | WS_TABSTOP,299,271,90,10
+    CONTROL         "Double, fields",IDC_LM_IDOUBLED2,"Button",BS_AUTORADIOBUTTON | BS_LEFT | WS_TABSTOP,299,284,90,10
+    CONTROL         "Double, fields+",IDC_LM_IDOUBLED3,"Button",BS_AUTORADIOBUTTON | BS_LEFT | WS_TABSTOP,299,297,90,10
+    GROUPBOX        "Aspect ratio",IDC_STATIC,289,132,105,26
+    CONTROL         "Automatic integer scaling",IDC_RLMASPECT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,298,143,88,10
 END
 
 IDD_MEMORY DIALOGEX 0, 0, 396, 304
@@ -2219,15 +2221,24 @@ BEGIN
     IDS_SYNCMODE_COMBINED   "Combined + Blanking"
     IDS_SYNCMODE_CSYNC      "Composite Sync + Blanking"
     IDS_SYNCMODE_HVSYNC     "H/V Sync + Blanking"
-    IDS_SYNCMODE_COMBINED2  "Combined + Sync"
-    IDS_SYNCMODE_CSYNC2     "Composite Sync + Sync"
-    IDS_SYNCMODE_HVSYNC2    "H/V Sync + Sync"
     IDS_MEMINFO             "Configured 32-bit address space: %dM, reserved: %dM, Z3 available: %dM (UAE), %dM (Real)"
     IDS_INPUTINVERT         "Invert"
     IDS_BOARDTYPE           "Type"
     IDS_BOARDNAME           "Name"
 END
 
+STRINGTABLE
+BEGIN
+    IDS_DISPLAY_OPTIMIZATION_FULL "Full"
+    IDS_DISPLAY_OPTIMIZATION_PARTIAL "Partial"
+    IDS_DISPLAY_OPTIMIZATION_NONE "None"
+    IDS_KEYBOARD_DISCONNECTED "Keyboard disconnected"
+    IDS_KEYBOARD_HIGHLEVEL  "UAE High level emulation"
+    IDS_SYNCMODE_COMBINED2  "Combined + Sync"
+    IDS_SYNCMODE_CSYNC2     "Composite Sync + Sync"
+    IDS_SYNCMODE_HVSYNC2    "H/V Sync + Sync"
+END
+
 STRINGTABLE
 BEGIN
     IDS_FILTER_PAL_EXTRA    "Brightness\nContrast\nSaturation\nGamma\nBlurriness\nNoise\n"
@@ -2264,15 +2275,6 @@ BEGIN
     IDS_CHOOSE_VIDEO_CODEC  "Choose Video Codec"
 END
 
-STRINGTABLE
-BEGIN
-    IDS_DISPLAY_OPTIMIZATION_FULL "Full"
-    IDS_DISPLAY_OPTIMIZATION_PARTIAL "Partial"
-    IDS_DISPLAY_OPTIMIZATION_NONE "None"
-    IDS_KEYBOARD_DISCONNECTED "Keyboard disconnected"
-    IDS_KEYBOARD_HIGHLEVEL  "UAE High level emulation"
-END
-
 #endif    // English (United Kingdom) resources
 /////////////////////////////////////////////////////////////////////////////
 
index cd995beb4b27cb1c11741667477e6b7adb602e12..78844ec2c58cf41023a81bcfbf20856444f46e99 100644 (file)
@@ -8149,6 +8149,7 @@ static void enable_for_displaydlg (HWND hDlg)
        ew(hDlg, IDC_SCREENMODE_RTG2, rtg);
        ew(hDlg, IDC_XCENTER, workprefs.gfx_overscanmode <= OVERSCANMODE_OVERSCAN);
        ew(hDlg, IDC_YCENTER, workprefs.gfx_overscanmode <= OVERSCANMODE_OVERSCAN);
+       ew(hDlg, IDC_RLMASPECT, TRUE);
        ew(hDlg, IDC_FRAMERATE, !workprefs.cpu_memory_cycle_exact);
        ew(hDlg, IDC_LORES, !workprefs.gfx_autoresolution);
        ew(hDlg, IDC_OVERSCANMODE, TRUE);
@@ -8710,8 +8711,9 @@ static void values_to_displaydlg (HWND hDlg)
        CheckDlgButton(hDlg, IDC_GRAYSCALE, workprefs.gfx_grayscale);
        CheckDlgButton(hDlg, IDC_RESYNCBLANK, workprefs.gfx_monitorblankdelay > 0);
 
-       CheckDlgButton (hDlg, IDC_XCENTER, workprefs.gfx_overscanmode <= OVERSCANMODE_OVERSCAN ? workprefs.gfx_xcenter : FALSE);
-       CheckDlgButton (hDlg, IDC_YCENTER, workprefs.gfx_overscanmode <= OVERSCANMODE_OVERSCAN ? workprefs.gfx_ycenter : FALSE);
+       CheckDlgButton(hDlg, IDC_XCENTER, workprefs.gfx_overscanmode <= OVERSCANMODE_OVERSCAN ? workprefs.gfx_xcenter : FALSE);
+       CheckDlgButton(hDlg, IDC_YCENTER, workprefs.gfx_overscanmode <= OVERSCANMODE_OVERSCAN ? workprefs.gfx_ycenter : FALSE);
+       CheckDlgButton(hDlg, IDC_RLMASPECT, workprefs.gfx_keep_aspect);
 
        xSendDlgItemMessage(hDlg, IDC_DISPLAY_BUFFERCNT, CB_RESETCONTENT, 0, 0);
 #if 0
@@ -8972,9 +8974,11 @@ static void values_from_displaydlg (HWND hDlg, UINT msg, WPARAM wParam, LPARAM l
        }
 
        if (workprefs.gfx_overscanmode <= OVERSCANMODE_OVERSCAN) {
-               workprefs.gfx_xcenter = ischecked (hDlg, IDC_XCENTER) ? 2 : 0; /* Smart centering */
-               workprefs.gfx_ycenter = ischecked (hDlg, IDC_YCENTER) ? 2 : 0; /* Smart centering */
+               /* Smart centering */
+               workprefs.gfx_xcenter = ischecked (hDlg, IDC_XCENTER) ? 2 : 0;
+               workprefs.gfx_ycenter = ischecked (hDlg, IDC_YCENTER) ? 2 : 0;
        }
+       workprefs.gfx_keep_aspect = ischecked(hDlg, IDC_RLMASPECT);
        workprefs.gfx_variable_sync = ischecked(hDlg, IDC_DISPLAY_VARSYNC) ? 1 : 0;
        workprefs.gfx_windowed_resize = ischecked(hDlg, IDC_DISPLAY_RESIZE);