]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
LDP-1450 character generator emulation. Platoon (Nova) LDP generated message(s?)...
authorToni Wilen <twilen@winuae.net>
Thu, 7 Mar 2024 17:26:29 +0000 (19:26 +0200)
committerToni Wilen <twilen@winuae.net>
Thu, 7 Mar 2024 17:26:29 +0000 (19:26 +0200)
arcadia.cpp
cfgfile.cpp
include/options.h
include/specialmonitors.h
include/statusline.h
od-win32/statusline_win32.cpp
specialmonitors.cpp

index 184f860ca09ac51f5667fa657776429412010e10..ffe9184f2ceb0f4ea92e8eeae3487fa60df83971 100644 (file)
@@ -717,6 +717,60 @@ static int ld_audio, ld_audio_mute;
 static bool ld_video;
 static int ld_vsync;
 static int alg_hsync_delay;
+static uae_u8 ld_uidx_config[3], ld_uidx_offset, ld_uidx_offsetd;
+static char ld_uidx_data[32];
+static uae_u8 ld_user_index;
+
+void genlock_infotext(uae_u8 *d, struct vidbuffer *dst)
+{
+       if (!ld_user_index) {
+#if 0
+               int x = 26;
+               int y = 12;
+               x -= 12;
+               y -= 10;
+               int dx = dst->inwidth * x / (86 - 12);
+               int dy = dst->inheight * y / (59 - 10);
+               int mx = 1, my = 1;
+               mx <<= currprefs.gfx_resolution;
+               my <<= currprefs.gfx_vresolution;
+               ldp_render("ABCDE12345ABCDE12345", 20, d, dst, dx, dy, mx ,my);
+               y += 4;
+               dy = dst->inheight * y / (59 - 10);
+               ldp_render("ABCDE12345ABCDE12345", 20, d, dst, dx, dy, mx, my);
+#endif
+               return;
+       }
+       int x = ld_uidx_config[0] & 63;
+       int y = ld_uidx_config[1] & 63;
+       int mx = (ld_uidx_config[2] & 3) + 1;
+       int my = ((ld_uidx_config[2] >> 2) & 3) + 1;
+       bool dm = (ld_uidx_config[2] & 0x10) != 0;
+       int offset = ld_uidx_offsetd & 31;
+       int len = 32 - offset;
+
+       x -= 12;
+       y -= 10;
+
+       int dx = dst->inwidth * x / (86 - 12);
+       int dy = dst->inheight * y / (59 - 10);
+
+       mx <<= currprefs.gfx_resolution;
+       my <<= currprefs.gfx_vresolution;
+
+       if (dm) {
+               ldp_render(ld_uidx_data, 10, d, dst, dx, dy, mx, my);
+               y += 4;
+               dy = dst->inheight * y / (59 - 10);
+               ldp_render(ld_uidx_data + 10, 10, d, dst, dx, dy, mx, my);
+               y += 4;
+               dy = dst->inheight * y / (59 - 10);
+               ldp_render(ld_uidx_data + 20, 10, d, dst, dx, dy, mx, my);
+       } else {
+               ldp_render(ld_uidx_data, 20, d, dst, dx, dy, mx, my);
+       }
+
+}
 
 static void sb(uae_u8 v)
 {
@@ -735,16 +789,27 @@ static void sony_serial_read(uae_u16 w)
        w &= 0xff;
 
        if (ld_ui >= 0 && ld_ui_cnt >= 0) {
-               ld_ui_cnt++;
                if (ld_ui == 0) {
+                       ld_uidx_config[ld_ui_cnt] = (uae_u8)w;
+                       ld_ui_cnt++;
                        if (ld_ui_cnt == 3) {
                                ld_ui = -1;
                        }
                } else if (ld_ui == 1) {
+                       if (ld_ui_cnt == 0) {
+                               ld_uidx_offset = (uae_u8)w;
+                       } else {
+                               int idx = ld_uidx_offset & 31;
+                               ld_uidx_data[idx] = (uae_u8)w;
+                               ld_uidx_offset++;
+                       }
+                       ld_ui_cnt++;
                        if (ld_ui_cnt >= 34 || (ld_ui_cnt > 1 && w == 0x1a)) {
                                ld_ui = -1;
                        }
                } else if (ld_ui == 2) {
+                       ld_uidx_offsetd = (uae_u8)w;
+                       ld_ui_cnt++;
                        ld_ui = -1;
                }
                ack();
@@ -1039,11 +1104,13 @@ static void sony_serial_read(uae_u16 w)
                write_log("LD: USER INDEX\n");
        break;
        case 0x81: // USER INDEX ON
+       ld_user_index = 1;
        ack();
        if (log_ld)
                write_log("LD: USER INDEX ON\n");
        break;
        case 0x82: // USER INDEX OFF
+       ld_user_index = 0;
        ack();
        if (log_ld)
                write_log(_T("LD: USER INDEX OFF\n"));
@@ -1452,6 +1519,13 @@ void alg_map_banks(void)
                alg_hsync_delay = 0;
                arcadia_hsync_cnt = 0;
                ld_ui = -1;
+               ld_user_index = 0;
+               ld_uidx_config[0] = 0;
+               ld_uidx_config[1] = 0;
+               ld_uidx_config[2] = 0;
+               ld_uidx_offset = 0;
+               ld_uidx_offsetd = 0;
+               memset(ld_uidx_data, 0, sizeof(ld_uidx_data));
        }
 }
 
@@ -1483,6 +1557,15 @@ uae_u8 *restore_alg(uae_u8 *src)
                alg_ser_buf[i] = restore_u8();
        }
        ld_vsync = restore_u32();
+       ld_user_index = restore_u8();
+       ld_uidx_config[0] = restore_u8();
+       ld_uidx_config[1] = restore_u8();
+       ld_uidx_config[2] = restore_u8();
+       ld_uidx_offset = restore_u8();
+       ld_uidx_offsetd = restore_u8();
+       for (int i = 0; i < 32; i++) {
+               ld_uidx_data[i] = restore_u8();
+       }
        return src;
 }
 
@@ -1520,7 +1603,15 @@ uae_u8 *save_alg(size_t *len)
                save_u8(alg_ser_buf[i]);
        }
        save_u32(ld_vsync);
-
+       save_u8(ld_user_index);
+       save_u8(ld_uidx_config[0]);
+       save_u8(ld_uidx_config[1]);
+       save_u8(ld_uidx_config[2]);
+       save_u8(ld_uidx_offset);
+       save_u8(ld_uidx_offsetd);
+       for (int i = 0; i < 32; i++) {
+               save_u8(ld_uidx_data[i]);
+       }
        *len = dst - dstbak;
        return dstbak;
 }
index 3a9f8447890b6aa006610bf76025e5600ee00fa3..33e4b56c723e228c4917470b932e46df6eb8c319 100644 (file)
@@ -2561,6 +2561,7 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type)
        cfgfile_dwrite_strarr(f, _T("genlockmode"), genlockmodes, p->genlock_image);
        cfgfile_dwrite_str(f, _T("genlock_image"), p->genlock_image_file);
        cfgfile_dwrite_str(f, _T("genlock_video"), p->genlock_video_file);
+       cfgfile_dwrite_str(f, _T("genlock_font"), p->genlock_font);
        cfgfile_dwrite(f, _T("genlock_mix"), _T("%d"), p->genlock_mix);
        cfgfile_dwrite(f, _T("genlock_scale"), _T("%d"), p->genlock_scale);
        cfgfile_dwrite(f, _T("genlock_offset_x"), _T("%d"), p->genlock_offset_x);
@@ -6028,6 +6029,7 @@ static int cfgfile_parse_hardware (struct uae_prefs *p, const TCHAR *option, TCH
                || cfgfile_path(option, value, _T("picassoiv_rom_file"), p->picassoivromfile, sizeof p->picassoivromfile / sizeof(TCHAR), &p->path_rom)
                || cfgfile_string(option, value, _T("genlock_image"), p->genlock_image_file, sizeof p->genlock_image_file / sizeof(TCHAR))
                || cfgfile_string(option, value, _T("genlock_video"), p->genlock_video_file, sizeof p->genlock_video_file / sizeof(TCHAR))
+               || cfgfile_string(option, value, _T("genlock_font"), p->genlock_font, sizeof p->genlock_font / sizeof(TCHAR))
                || cfgfile_string(option, value, _T ("pci_devices"), p->pci_devices, sizeof p->pci_devices / sizeof(TCHAR))
                || cfgfile_string (option, value, _T("ghostscript_parameters"), p->ghostscript_parameters, sizeof p->ghostscript_parameters / sizeof (TCHAR)))
                return 1;
@@ -8808,6 +8810,7 @@ static void buildin_default_prefs (struct uae_prefs *p)
        p->genlock = 0;
        p->genlock_image = 0;
        p->genlock_image_file[0] = 0;
+       p->genlock_font[0] = 0;
        
        p->ne2000pciname[0] = 0;
        p->ne2000pcmcianame[0] = 0;
index 06da514a0e8a3d23a558472eccba86651927285b..6cbdaddd7561af81b9fba7e04c019f00cec20002 100644 (file)
@@ -634,6 +634,7 @@ struct uae_prefs {
        bool genlock_alpha;
        TCHAR genlock_image_file[MAX_DPATH];
        TCHAR genlock_video_file[MAX_DPATH];
+       TCHAR genlock_font[MAX_DPATH];
        int monitoremu;
        int monitoremu_mon;
        float chipset_refreshrate;
index 7afc98b369fbdcd7c1b78cd22964ea770d363c07..e67e3f02d1f4115cda898493f1ba984ddb9a8bb4 100644 (file)
@@ -13,6 +13,7 @@ bool specialmonitor_autoconfig_init(struct autoconfig_info*);
 bool emulate_genlock(struct vidbuffer*, struct vidbuffer*, bool);
 bool emulate_grayscale(struct vidbuffer*, struct vidbuffer*);
 bool specialmonitor_linebased(void);
+void genlock_infotext(uae_u8*, struct vidbuffer*);
 
 const TCHAR *specialmonitorfriendlynames[];
 const TCHAR *specialmonitormanufacturernames[];
index 48f9790c89b14b523e5d10095a2e9d9224602593..21cf9eee61332168f5949988129db1ea4d648194 100644 (file)
@@ -54,5 +54,6 @@ const TCHAR *statusline_fetch(void);
 int statusline_set_multiplier(int, int, int);
 int statusline_get_multiplier(int monid);
 void statusline_set_font(const char *newnumbers, int width, int height);
+void ldp_render(const char *txt, int len, uae_u8 *buf, struct vidbuffer*, int x, int y, int mx, int my);
 
 #endif /* UAE_STATUSLINE_H */
index 703e5f7d1f99291fd37b3ba59fd21a2c80013a54..123049ddc4622270832c234ae03bff71e6240a2c 100644 (file)
@@ -49,6 +49,144 @@ void deletestatusline(int monid)
        statusline_palette = NULL;
 }
 
+
+static char *ldp_font_bitmap;
+static int ldp_font_width, ldp_font_height;
+
+static void create_ldp_font(HWND parent)
+{
+       HDC hdc;
+       LPLOGPALETTE lp;
+       HPALETTE hpal;
+       BITMAPINFO *bi;
+       BITMAPINFOHEADER *bih;
+       HBITMAP bitmap = NULL;
+       int width = 128;
+       int height = 128;
+       int fontsize, fontweight;
+       void *bm;
+       const TCHAR *fn;
+
+       xfree(ldp_font_bitmap);
+
+       if (currprefs.genlock_image != 6 && currprefs.genlock_image != 7 && currprefs.genlock_image != 8) {
+               return;
+       }
+
+       fontsize = 20;
+       fontweight = FW_NORMAL;
+       fn = statusline_fontname;
+       if (currprefs.genlock_font[0]) {
+               fn = currprefs.genlock_font;
+       }
+
+       hdc = CreateCompatibleDC(NULL);
+       if (hdc) {
+               lp = (LOGPALETTE *)xcalloc(uae_u8, sizeof(LOGPALETTE) + 3 * sizeof(PALETTEENTRY));
+               if (lp) {
+                       lp->palNumEntries = 4;
+                       lp->palVersion = 0x300;
+                       lp->palPalEntry[1].peBlue = lp->palPalEntry[1].peGreen = lp->palPalEntry[0].peRed = 0x10;
+                       lp->palPalEntry[2].peBlue = lp->palPalEntry[2].peGreen = lp->palPalEntry[2].peRed = 0xff;
+                       lp->palPalEntry[3].peBlue = lp->palPalEntry[3].peGreen = lp->palPalEntry[3].peRed = 0x7f;
+                       hpal = CreatePalette(lp);
+                       if (hpal) {
+                               SelectPalette(hdc, hpal, FALSE);
+                               bi = (BITMAPINFO *)xcalloc(uae_u8, sizeof(BITMAPINFOHEADER) + 4 * sizeof(RGBQUAD));
+                               if (bi) {
+                                       bih = &bi->bmiHeader;
+                                       bih->biSize = sizeof(BITMAPINFOHEADER);
+                                       bih->biWidth = width;
+                                       bih->biHeight = -height;
+                                       bih->biPlanes = 1;
+                                       bih->biBitCount = 8;
+                                       bih->biCompression = BI_RGB;
+                                       bih->biClrUsed = 4;
+                                       bih->biClrImportant = 4;
+                                       bi->bmiColors[1].rgbBlue = bi->bmiColors[1].rgbGreen = bi->bmiColors[1].rgbRed = 0x10;
+                                       bi->bmiColors[2].rgbBlue = bi->bmiColors[2].rgbGreen = bi->bmiColors[2].rgbRed = 0xff;
+                                       bi->bmiColors[3].rgbBlue = bi->bmiColors[3].rgbGreen = bi->bmiColors[3].rgbRed = 0x7f;
+                                       bitmap = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bm, NULL, 0);
+                                       if (bitmap) {
+                                               SelectObject(hdc, bitmap);
+                                               RealizePalette(hdc);
+                                               HFONT font = CreateFont(-fontsize, 0,
+                                                       0, 0,
+                                                       fontweight,
+                                                       0,
+                                                       FALSE,
+                                                       FALSE,
+                                                       DEFAULT_CHARSET,
+                                                       OUT_TT_PRECIS,
+                                                       CLIP_DEFAULT_PRECIS,
+                                                       PROOF_QUALITY,
+                                                       FIXED_PITCH | FF_DONTCARE,
+                                                       statusline_fontname);
+                                               if (font) {
+                                                       SelectObject(hdc, font);
+                                                       SetTextColor(hdc, PALETTEINDEX(2));
+                                                       SetBkColor(hdc, PALETTEINDEX(1));
+                                                       TEXTMETRIC tm;
+                                                       GetTextMetrics(hdc, &tm);
+                                                       int w = 0;
+                                                       int h = tm.tmAscent + 2;
+                                                       int total = 128 - 32;
+                                                       for (int i = 32; i < 128; i++) {
+                                                               SIZE sz;
+                                                               TCHAR ch = i;
+                                                               if (GetTextExtentPoint32(hdc,&ch, 1, &sz)) {
+                                                                       if (sz.cx > w)
+                                                                               w = sz.cx;
+                                                               }
+                                                       }
+                                                       int offsetx = 10;
+                                                       int offsety = 10 - 1;
+                                                       int fxd = fontsize - w;
+                                                       if (fxd >= 1) {
+                                                               fxd -= 1;
+                                                               offsetx -= fxd / 2;
+                                                               w += fxd / 2;
+                                                               if (offsetx < 0) {
+                                                                       offsetx = 0;
+                                                               }
+                                                       }
+                                                       ldp_font_bitmap = xcalloc(char, w * h * total);
+                                                       if (ldp_font_bitmap) {
+                                                               for (int i = 32; i < 128; i++) {
+                                                                       TCHAR ch = i;
+                                                                       SetBkMode(hdc, OPAQUE);
+                                                                       BitBlt(hdc, 0, 0, width, height, NULL, 0, 0, BLACKNESS);
+                                                                       TextOut(hdc, 10, 10, &ch, 1);
+                                                                       char *dst = ldp_font_bitmap + (i - 32) * w * h;
+                                                                       for (int y = 0; y < h; y++) {
+                                                                               uae_u8 *src = (uae_u8 *)bm + (y + offsety) * width + offsetx;
+                                                                               for (int x = 0; x < w; x++) {
+                                                                                       uae_u8 b = *src++;
+                                                                                       if (b == 2) {
+                                                                                               *dst = 'x';
+                                                                                       }
+                                                                                       dst++;
+                                                                               }
+                                                                       }
+                                                               }
+                                                               ldp_font_width = w;
+                                                               ldp_font_height = h;
+                                                       }
+                                                       DeleteObject(font);
+                                               }
+                                               DeleteObject(bitmap);
+                                       }
+                                       xfree(bi);
+                               }
+                               DeleteObject(hpal);
+                       }
+                       xfree(lp);
+               }
+               ReleaseDC(NULL, hdc);
+       }
+}
+
+
 static void create_led_font(HWND parent, int monid)
 {
        HDC hdc;
@@ -204,6 +342,7 @@ bool createstatusline(HWND parentHwnd, int monid)
                return false;
 
        create_led_font(parentHwnd, monid);
+       create_ldp_font(parentHwnd);
 
        lp = (LOGPALETTE*)xcalloc(uae_u8, sizeof(LOGPALETTE) + 3 * sizeof(PALETTEENTRY));
        if (!lp)
@@ -275,7 +414,7 @@ void statusline_render(int monid, uae_u8 *buf, int bpp, int pitch, int width, in
 {
        struct AmigaMonitor *mon = &AMonitors[monid];
        uae_u32 white = rc[0xff] | gc[0xff] | bc[0xff] | (alpha ? alpha[0xff] : 0);
-       uae_u32 back = rc[0x00] | gc[0x00] | bc[0x00] | (alpha ? alpha[0xa0] : 0);
+       uae_u32 black = rc[0x00] | gc[0x00] | bc[0x00] | (alpha ? alpha[0xa0] : 0);
        const TCHAR *text;
        int y = 0, x = 10, textwidth = 0;
        int bar_xstart;
@@ -316,9 +455,55 @@ void statusline_render(int monid, uae_u8 *buf, int bpp, int pitch, int width, in
                                if (b == 2)
                                        *dst2 = white;
                                else if (b == 1)
-                                       *dst2 = back;
+                                       *dst2 = black;
                        }
                        dst2++;
                }
        }
 }
+
+void ldp_render(const char *txt, int len, uae_u8 *buf, struct vidbuffer *vd, int dx, int dy, int mx, int my)
+{
+       if (!ldp_font_bitmap) {
+               return;
+       }
+       int bpp = vd->pixbytes;
+       uae_u32 white = 0xffffff;
+       uae_u8 *dbuf2 = buf + dy * vd->rowbytes + dx * bpp;
+       for (int i = 0; i < len; i++) {
+               uae_u8 *dbuf = dbuf2 + i * ldp_font_width * mx * bpp;
+               char ch = *txt++;
+               if (ch >= 32) {
+                       ch -= 32;
+               } else {
+                       ch = 0;
+               }
+               char *font = ldp_font_bitmap + ch * ldp_font_width * ldp_font_height;
+               for (int y = 0; y < ldp_font_height; y++) {
+                       for (int mmy = 0; mmy < my; mmy++) {
+                               char *font2 = font;
+                               for (int x = 0; x < ldp_font_width; x++) {
+                                       if (*font2) {
+                                               for (int mmx = 0; mmx < mx; mmx++) {
+                                                       int xx = x * mx + mmx;
+                                                       if (dy + y * my + mmy >= 0 && dy + y * my + mmy < vd->inheight) {
+                                                               if (dx + xx >= 0 && dx + xx < vd->inwidth) {
+                                                                       dbuf[xx * bpp + 0] = 0xff;
+                                                                       dbuf[xx * bpp + 1] = 0xff;
+                                                                       if (bpp == 4) {
+                                                                               dbuf[xx * bpp + 2] = 0xff;
+                                                                               dbuf[xx * bpp + 3] = 0xff;
+                                                                       }
+                                                               }
+                                                       }
+                                               }
+                                       }
+                                       font2++;
+                               }
+                               dbuf += vd->rowbytes;
+                       }
+                       font += ldp_font_width;
+               }
+               dx += ldp_font_width;
+       }
+}
index 302b5e45051e0f44f5ec033ea63659678a3a3696..ed7b02c7fd91397d9b499c0e3fe762b18d0cae7b 100755 (executable)
@@ -2615,6 +2615,9 @@ skip:
        vblank_bottom_stop <<= vdbl;
        vblank_top_start <<= vdbl;
 
+       bool first = true;
+       uae_u8 *firstdstline = NULL;
+
        uae_u8 r = 0, g = 0, b = 0, a = 0;
        for (y = ystart; y < yend; y++) {
                int yoff = ((y * 2 + oddlines) - src->yoffset) >> vdbl;
@@ -2640,6 +2643,10 @@ skip:
                uae_u8 *s = line;
                uae_u8 *d = dstline;
                uae_u8 *s_genlock = line_genlock;
+               if (first) {
+                       firstdstline = dstline;
+                       first = false;
+               }
                int hwidth = 0;
                for (x = 0; x < src->inwidth; x++) {
                        uae_u8 *s2 = s + src->rowbytes;
@@ -2687,6 +2694,11 @@ skip:
                        }
                }
        }
+       
+       if (firstdstline) {
+               firstdstline += hblank_left_start * dst->pixbytes;
+               genlock_infotext(firstdstline, dst);
+       }
 
        dst->nativepositioning = true;
        return true;