Synchronet now requires the libarchive development package (e.g. libarchive-dev on Debian-based Linux distros, libarchive.org for more info) to build successfully.

Commits (1)
  • Deucе's avatar
    Use display aspect ratio, not pixel for tracking. · a5c619fc
    Deucе authored
    People are used to thinking about the aspect ratio of displays and
    used to not thinking at all about that of pixels.  Most of the modes
    are simplt 4:3 modes and the text area is the entire window.  The
    only oddball here is the Commodore 64 and 128 40-column modes.
    Because they have a border around them that's wider on the sides than
    the top/bottom, the display aspect ratio is actually narrower than
    a normal NTSC screen (6:5).  It seems the PAL version actually has
    square pixels, but nobody has asked for a PAL Commodore mode, and I
    think that has a different colour palette too so I'm not doing it.
    
    Just to frustrate DigitalMan a bit, the default custom aspect ratio
    is now 4:3 (but can be configured).  At present, modifying the custom
    mode while *in* the custom modes "works", which no sane person would
    want when adjusting the aspect ratio.
    a5c619fc
......@@ -26,6 +26,102 @@ static struct graphics_buffer *free_list;
x = 255; \
} while(0)
/*
* Corrects width/height to have the specified aspect ratio
*/
void
aspect_fix(int *x, int *y, int aspect_width, int aspect_height)
{
int bestx, besty;
// Nothing we can do here...
if (aspect_width == 0 || aspect_height == 0)
return;
bestx = lround((double)*y * aspect_width / aspect_height);
besty = lround((double)*x * aspect_height / aspect_width);
if (bestx < *x && bestx > 0)
*x = bestx;
else
*y = besty;
}
/*
* Given a width/height of a source image, adjust it to match the current aspect
* ratio. Will not reduce either number
*/
void
aspect_correct(int *x, int *y, int aspect_width, int aspect_height)
{
int width = *x;
int height;
if (!aspect_height || !aspect_width)
return;
height = lround((double)(width * aspect_height) / aspect_width);
if (height < *y) {
height = *y;
width = lround(((double)height * aspect_width) / aspect_height);
}
*x = width;
*y = height;
}
/*
* Essentially the opposite of the above. Given an output width/height, translates to
* the size of the source image.
*
* Note that this is much trickier as the "source" bitmap may have been integer scaled
* differently in both directions... so what this does is reverse the aspect ratio
* calculation, then find the next lowest even multiple of the mode bitmap size.
*/
void
aspect_reverse(int *x, int *y, int scrnwidth, int scrnheight, int aspect_width, int aspect_height)
{
int width = *x;
int height = *y;
int cheight;
int cwidth;
if (!aspect_height || !aspect_width) {
width = scrnwidth * (*x / scrnwidth);
if (width < scrnwidth)
width = scrnwidth;
height = scrnheight * (*x / scrnheight);
if (height < scrnheight)
height = scrnheight;
return;
}
// First, find the "controlling" dimension... the one that won't be scaled (ie: the one that gets smaller)
cwidth = lround((double)(height * aspect_width) / aspect_height * scrnwidth / scrnheight);
cheight = lround((double)(width * aspect_height) / aspect_width * scrnheight / scrnwidth);
if (cwidth > width) {
// Width controls, so this is simply finding the largest width multiple that fits in the box
width = scrnwidth * (*x / scrnwidth);
if (width < scrnwidth)
width = scrnwidth;
// Now we need to find the largest bitmap height that would fit in the output height
// So, we scale the height to bitmap size...
height = lround((double)*y / ((double)scrnwidth / scrnheight) * ((double)aspect_width / aspect_height));
// And do the same calculation...
height = lround((double)scrnheight * ((double)height / scrnheight));
}
else if (cheight > height) {
// Height controls
height = scrnheight * (*x / scrnheight);
if (height < scrnheight)
height = scrnheight;
width = lround((double)*x / ((double)scrnheight / scrnwidth) * ((double)aspect_height / aspect_width));
width = lround((double)scrnwidth * ((double)width / scrnwidth));
}
*x = width;
*y = height;
}
void
init_r2y(void)
{
......@@ -94,7 +190,7 @@ release_buffer(struct graphics_buffer *buf)
}
struct graphics_buffer *
do_scale(struct rectlist* rect, int xscale, int yscale, double ratio)
do_scale(struct rectlist* rect, int xscale, int yscale, int aspect_width, int aspect_height)
{
struct graphics_buffer* ret1 = get_buffer();
struct graphics_buffer* ret2 = get_buffer();
......@@ -185,14 +281,10 @@ do_scale(struct rectlist* rect, int xscale, int yscale, double ratio)
yscale = tmp;
}
// Calculate the scaled height from ratio...
fheight = lround((double)(rect->rect.height * (yscale)) / ratio);
if (fheight < rect->rect.height * yscale)
fheight = rect->rect.height * yscale;
fwidth = lround((double)(rect->rect.width * (xscale)) * ratio);
if (fwidth < rect->rect.width * xscale)
fwidth = rect->rect.width * xscale;
// Calculate the scaled height from rxscaleatio...
fwidth = rect->rect.width * xscale;
fheight = rect->rect.height * yscale;
aspect_correct(&fwidth, &fheight, aspect_width, aspect_height);
// Now make sure target is big enough...
size_t needsz = fwidth * fheight * sizeof(uint32_t);
......@@ -222,6 +314,7 @@ do_scale(struct rectlist* rect, int xscale, int yscale, double ratio)
#if 0
fprintf(stderr, "Plan:\n"
"start: %dx%d\n"
"pointymulti: %d\n"
"pointy5: %d\n"
"pointy3: %d\n"
......@@ -230,7 +323,7 @@ fprintf(stderr, "Plan:\n"
"Multiply: %dx%d\n"
"hinterp: %zu -> %zu\n"
"winterp: %zu -> %zu\n",
pointymult, pointy5, pointy3, xbr4, xbr2, xmult, ymult, csrc->h * yscale, ratio < 1 ? fheight : csrc->h * yscale, csrc->w * xscale, ratio > 1 ? fwidth : csrc->w * xscale);
csrc->w, csrc->h, pointymult, pointy5, pointy3, xbr4, xbr2, xmult, ymult, csrc->h * yscale, fheight, csrc->w * xscale, fwidth);
#endif
// And scale...
if (ymult != 1 || xmult != 1) {
......
......@@ -15,4 +15,7 @@ struct graphics_buffer * get_buffer(void);
void release_buffer(struct graphics_buffer *);
void init_r2y(void);
struct graphics_buffer * do_scale(struct rectlist* rect, int xscale, int yscale, double ratio);
struct graphics_buffer * do_scale(struct rectlist* rect, int xscale, int yscale, int aspect_width, int aspect_height);
void aspect_correct(int *x, int *y, int aspect_width, int aspect_height);
void aspect_reverse(int *x, int *y, int scrnwidth, int scrnheight, int aspect_width, int aspect_height);
void aspect_fix(int *x, int *y, int aspect_width, int aspect_height);
......@@ -330,65 +330,27 @@ void sdl_flush(void)
static bool
window_can_scale_internally(int winwidth, int winheight)
{
int idealmw;
int idealmh;
int idealh;
int idealw;
// First, figure out if width or height controlls the image size.
idealmw = lround((double)cvstat.scale_numerator / cvstat.scale_denominator * cvstat.scrnwidth);
idealmh = lround((double)cvstat.scale_denominator / cvstat.scale_numerator * cvstat.scrnheight);
idealw = lround(winheight * cvstat.scale_numerator / cvstat.scale_denominator * cvstat.scrnwidth / cvstat.scrnheight);
idealh = lround(winwidth * cvstat.scale_denominator / cvstat.scale_numerator * cvstat.scrnheight / cvstat.scrnwidth);
if (idealw < winwidth) {
// Height controls size...
if (winheight % idealmh == 0)
return true;
}
else {
// Width controls size...
if (winwidth % idealmw == 0)
return true;
}
int fw, fh;
aspect_fix(&winwidth, &winheight, cvstat.aspect_width, cvstat.aspect_height);
fw = winwidth;
fh = winheight;
aspect_reverse(&winwidth, &winheight, cvstat.scrnwidth, cvstat.scrnheight, cvstat.aspect_width, cvstat.aspect_height);
if (fw == winwidth || fh == winheight)
return true;
return false;
}
static void
internal_scaling_factors(int winwidth, int winheight, int *x, int *y)
{
int idealmh;
int idealmw;
int idealh;
int idealw;
// First, figure out if width or height controlls the image size.
idealmw = lround((double)cvstat.scale_numerator / cvstat.scale_denominator * cvstat.scrnwidth);
idealmh = lround((double)cvstat.scale_denominator / cvstat.scale_numerator * cvstat.scrnheight);
idealw = lround((double)winheight * cvstat.scale_numerator / cvstat.scale_denominator * cvstat.scrnwidth / cvstat.scrnheight);
idealh = lround((double)winwidth * cvstat.scale_denominator / cvstat.scale_numerator * cvstat.scrnheight / cvstat.scrnwidth);
if (idealw < winwidth) {
// Height controls size...
if (idealh == winheight) {
idealmw = cvstat.scrnwidth;
*x = lround((double)idealw / idealmw);
*y = lround((double)idealh / idealmh);
return;
}
}
else {
// Width controls size...
if (idealw == winwidth) {
idealmh = cvstat.scrnheight;
*x = lround((double)idealw / idealmw);
*y = lround((double)idealh / idealmh);
return;
}
}
*x = 1;
*y = 1;
aspect_fix(&winwidth, &winheight, cvstat.aspect_width, cvstat.aspect_height);
aspect_reverse(&winwidth, &winheight, cvstat.scrnwidth, cvstat.scrnheight, cvstat.aspect_width, cvstat.aspect_height);
*x = winwidth / cvstat.scrnwidth;
*y = winheight / cvstat.scrnheight;
if (*x < 1 || *x > 14)
*x = 1;
if (*y < 1 || *y > 14)
*y = 1;
}
static int sdl_init_mode(int mode)
......@@ -410,8 +372,9 @@ static int sdl_init_mode(int mode)
pthread_mutex_lock(&vstatlock);
oldcols = cvstat.cols;
bitmap_drv_init_mode(mode, &bitmap_width, &bitmap_height);
vstat.winwidth = ((double)cvstat.winwidth / (cvstat.scrnwidth)) * (vstat.scrnwidth);
vstat.winheight = ((double)cvstat.winheight / (cvstat.scrnheight * cvstat.vmultiplier)) * (vstat.scrnheight * vstat.vmultiplier);
vstat.winwidth = lround((double)cvstat.winwidth / cvstat.scrnwidth * vstat.scrnwidth);
vstat.winheight = lround((double)cvstat.winheight / cvstat.scrnheight * vstat.scrnheight);
aspect_correct(&vstat.winwidth, &cvstat.winheight, cvstat.aspect_width, cvstat.aspect_height);
if (oldcols != vstat.cols) {
if (oldcols == 0) {
if (ciolib_initial_window_width > 0)
......@@ -434,8 +397,6 @@ static int sdl_init_mode(int mode)
vstat.winwidth = vstat.scrnwidth;
if (vstat.winheight < vstat.scrnheight)
vstat.winheight = vstat.scrnheight;
if(vstat.vmultiplier < 1)
vstat.vmultiplier = 1;
cvstat = vstat;
internal_scaling = window_can_scale_internally(vstat.winwidth, vstat.winheight);
......@@ -622,9 +583,11 @@ static void setup_surfaces_locked(void)
{
int flags=0;
SDL_Event ev;
int charwidth, charheight, cols, rows, vmultiplier;
int charwidth, charheight, cols, rows;
SDL_Texture *newtexture;
int idealw;
int idealh;
int idealmw;
int idealmh;
if(fullscreen)
......@@ -641,19 +604,25 @@ static void setup_surfaces_locked(void)
charheight = cvstat.charheight;
cols = cvstat.cols;
rows = cvstat.rows;
vmultiplier = cvstat.vmultiplier;
idealh = lround((long double)cvstat.winwidth * cvstat.scale_denominator / cvstat.scale_numerator * cvstat.scrnheight / cvstat.scrnwidth);
idealmh = lround((long double)cvstat.scrnwidth * cvstat.scale_denominator / cvstat.scale_numerator * cvstat.scrnheight / cvstat.scrnwidth);
internal_scaling = true;
sdl.SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "0");
idealmw = cvstat.scrnwidth;
idealmh = cvstat.scrnheight;
aspect_correct(&idealmw, &idealmh, cvstat.aspect_width, cvstat.aspect_height);
idealw = cvstat.winwidth;
idealh = cvstat.winheight;
aspect_fix(&idealw, &idealh, cvstat.aspect_width, cvstat.aspect_height);
internal_scaling = window_can_scale_internally(idealw, idealh);
sdl.SetHint(SDL_HINT_RENDER_SCALE_QUALITY, internal_scaling ? "0" : "2");
if (win == NULL) {
// SDL2: This is slow sometimes... not sure why.
if (sdl.CreateWindowAndRenderer(cvstat.winwidth, idealh, flags, &win, &renderer) == 0) {
if (sdl.CreateWindowAndRenderer(cvstat.winwidth, cvstat.winheight, flags, &win, &renderer) == 0) {
sdl.RenderClear(renderer);
newtexture = sdl.CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, cvstat.winwidth, idealh);
if (internal_scaling)
newtexture = sdl.CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, idealw, idealh);
else
newtexture = sdl.CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, cvstat.scrnwidth, cvstat.scrnheight);
if (texture)
if (texture)
sdl.DestroyTexture(texture);
texture = newtexture;
}
......@@ -663,15 +632,18 @@ static void setup_surfaces_locked(void)
}
}
else {
sdl.SetWindowMinimumSize(win, cvstat.scrnwidth, idealmh);
sdl.SetWindowSize(win, cvstat.winwidth, idealh);
newtexture = sdl.CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, cvstat.winwidth, idealh);
sdl.SetWindowMinimumSize(win, idealmw, idealmh);
sdl.SetWindowSize(win, idealw, idealh);
if (internal_scaling)
newtexture = sdl.CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, idealw, idealh);
else
newtexture = sdl.CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, cvstat.scrnwidth, cvstat.scrnheight);
sdl.RenderClear(renderer);
if (texture)
sdl.DestroyTexture(texture);
texture = newtexture;
}
sdl.SetWindowMinimumSize(win, cvstat.scrnwidth, idealmh);
sdl.SetWindowMinimumSize(win, idealmw, idealmh);
if(win!=NULL) {
bitmap_drv_request_pixels();
......@@ -900,37 +872,50 @@ void sdl_video_event_thread(void *data)
// Don't allow ALT-DIR to change size when maximized...
if ((sdl.GetWindowFlags(win) & SDL_WINDOW_MAXIMIZED) == 0) {
bool wc;
pthread_mutex_lock(&vstatlock);
w = cvstat.winwidth;
h = cvstat.winheight;
aspect_fix(&w, &h, cvstat.aspect_width, cvstat.aspect_height);
if (cvstat.aspect_width == 0 || cvstat.aspect_height == 0)
wc = true;
else
wc = lround((double)(h * cvstat.aspect_width) / cvstat.aspect_height * cvstat.scrnwidth / cvstat.scrnheight) > w;
switch(ev.key.keysym.sym) {
case SDLK_LEFT:
if (w % (cvstat.scrnwidth)) {
w = w - w % cvstat.scrnwidth;
if (wc) {
if (w % (cvstat.scrnwidth)) {
w = w - w % cvstat.scrnwidth;
}
else {
w -= cvstat.scrnwidth;
if (w < cvstat.scrnwidth)
w = cvstat.scrnwidth;
}
}
else {
w -= cvstat.scrnwidth;
if (w < cvstat.scrnwidth)
w = cvstat.scrnwidth;
if (h % (cvstat.scrnheight)) {
h = h - h % cvstat.scrnheight;
}
else {
h -= cvstat.scrnheight;
if (h < cvstat.scrnheight)
h = cvstat.scrnheight;
}
}
break;
case SDLK_RIGHT:
w = (w - w % cvstat.scrnwidth) + cvstat.scrnwidth;
break;
case SDLK_UP:
if (h % (cvstat.scrnheight * cvstat.vmultiplier)) {
h = h - h % (cvstat.scrnheight * cvstat.vmultiplier);
}
else {
h -= (cvstat.scrnheight * cvstat.vmultiplier);
if (h < (cvstat.scrnheight * cvstat.vmultiplier))
h = cvstat.scrnheight * cvstat.vmultiplier;
}
break;
case SDLK_DOWN:
h = (h - h % (cvstat.scrnheight * cvstat.vmultiplier)) + (cvstat.scrnheight * cvstat.vmultiplier);
if (wc)
w = (w - w % cvstat.scrnwidth) + cvstat.scrnwidth;
else
h = (h - h % cvstat.scrnheight) + cvstat.scrnheight;
break;
}
if (wc)
h = INT_MAX;
else
w = INT_MAX;
aspect_fix(&w, &h, cvstat.aspect_width, cvstat.aspect_height);
if (w > 16384 || h > 16384)
beep();
else {
......@@ -1063,8 +1048,13 @@ void sdl_video_event_thread(void *data)
if (strcmp(newh, sdl.GetHint(SDL_HINT_RENDER_SCALE_QUALITY))) {
SDL_Texture *newtexture;
sdl.SetHint(SDL_HINT_RENDER_SCALE_QUALITY, newh);
if (internal_scaling)
newtexture = sdl.CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, cvstat.winwidth, cvstat.winheight);
if (internal_scaling) {
int idealw, idealh;
idealw = cvstat.winwidth;
idealh = cvstat.winheight;
aspect_fix(&idealw, &idealh, cvstat.aspect_width, cvstat.aspect_height);
newtexture = sdl.CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, idealw, idealh);
}
else
newtexture = sdl.CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, cvstat.scrnwidth, cvstat.scrnheight);
sdl.RenderClear(renderer);
......@@ -1118,7 +1108,7 @@ void sdl_video_event_thread(void *data)
int xscale, yscale;
internal_scaling_factors(cvstat.winwidth, cvstat.winheight, &xscale, &yscale);
gb = do_scale(list, xscale, yscale,
(double)cvstat.scale_numerator / cvstat.scale_denominator);
cvstat.aspect_width, cvstat.aspect_height);
src.x = 0;
src.y = 0;
src.w = gb->w;
......@@ -1142,8 +1132,8 @@ void sdl_video_event_thread(void *data)
memcpy(pixels, gb->data, gb->w * ch * sizeof(gb->data[0]));
}
sdl.UnlockTexture(texture);
dst.x = 0;
dst.y = 0;
dst.x = (cvstat.winwidth - gb->w) / 2;
dst.y = (cvstat.winheight - gb->h) / 2;
dst.w = gb->w;
dst.h = gb->h;
release_buffer(gb);
......@@ -1172,21 +1162,12 @@ void sdl_video_event_thread(void *data)
memcpy(pixels, list->data, list->rect.width * ch * sizeof(list->data[0]));
}
sdl.UnlockTexture(texture);
dst.x = 0;
dst.y = 0;
dst.w = cvstat.winwidth;
dst.h = cvstat.winheight;
// Get correct aspect ratio for dst...
idealw = lround((long double)dst.h * cvstat.scale_numerator / cvstat.scale_denominator * cvstat.scrnwidth / cvstat.scrnheight);
idealh = lround((long double)dst.w * cvstat.scale_denominator / cvstat.scale_numerator * cvstat.scrnheight / cvstat.scrnwidth);
if (idealw < cvstat.winwidth) {
dst.x = (cvstat.winwidth - idealw) / 2;
dst.w = idealw;
}
else if(idealh < cvstat.winheight) {
dst.y = (cvstat.winheight - idealh) / 2;
dst.h = idealh;
}
aspect_fix(&dst.w, &dst.h, cvstat.aspect_width, cvstat.aspect_height);
dst.x = (cvstat.winwidth - dst.w) / 2;
dst.y = (cvstat.winheight - dst.h) / 2;
}
sdl.RenderCopy(renderer, texture, &src, &dst);
}
......
......@@ -11,114 +11,118 @@
// TODO: Pretty much all the 1:1 aspect ratios are wrong...
struct video_params vparams[] = {
/* BW 40x25 */
{BW40, GREYSCALE_PALETTE, 40, 25, 14, 15, 16, 8, 1, 7, 0, 833, 1000, 320, 200},
{BW40, GREYSCALE_PALETTE, 40, 25, 14, 15, 16, 8, 7, 0, 4, 3, 320, 200},
/* CO 40x25 */
{C40, COLOUR_PALETTE, 40, 25, 14, 15, 16, 8, 1, 7, 0, 833, 1000, 320, 200},
{C40, COLOUR_PALETTE, 40, 25, 14, 15, 16, 8, 7, 0, 4, 3, 320, 200},
/* BW 80x25 */
{BW80, GREYSCALE_PALETTE, 80, 25, 14, 15, 16, 8, 1, 7, 0, 833, 1000, 640, 400},
{BW80, GREYSCALE_PALETTE, 80, 25, 14, 15, 16, 8, 7, 0, 4, 3, 640, 400},
/* CO 80x25 */
{C80, COLOUR_PALETTE, 80, 25, 14, 15, 16, 8, 1, 7, 0, 833, 1000, 640, 400},
{C80, COLOUR_PALETTE, 80, 25, 14, 15, 16, 8, 7, 0, 4, 3, 640, 400},
/* MONO */
{MONO, 0, 80, 25, 14, 15, 16, 8, 1, 7, 0, 833, 1000, 640, 400},
{MONO, 0, 80, 25, 14, 15, 16, 8, 7, 0, 4, 3, 640, 400},
/* CO 40x14 */
{C40X14, COLOUR_PALETTE, 40, 14, 14, 15, 16, 8, 1, 7, 0, 933, 1000, 320, 224},
{C40X14, COLOUR_PALETTE, 40, 14, 14, 15, 16, 8, 7, 0, 4, 3, 320, 224},
/* CO 40x21 */
{C40X21, COLOUR_PALETTE, 40, 21, 14, 15, 16, 8, 1, 7, 0,1400, 1000, 320, 336},
{C40X21, COLOUR_PALETTE, 40, 21, 14, 15, 16, 8, 7, 0, 4, 3, 320, 336},
/* CO 40x28 */
{C40X28, COLOUR_PALETTE, 40, 28, 12, 13, 14, 8, 1, 7, 0,1633, 1000, 320, 392},
{C40X28, COLOUR_PALETTE, 40, 28, 12, 13, 14, 8, 7, 0, 4, 3, 320, 392},
/* CO 40x43 */
{C40X43, COLOUR_PALETTE, 40, 43, 7, 7, 8, 8, 1, 7, 0,3225, 1000, 320, 774},
{C40X43, COLOUR_PALETTE, 40, 43, 7, 7, 8, 8, 7, 0, 4, 3, 320, 774},
/* CO 40x50 */
{C40X50, COLOUR_PALETTE, 40, 50, 7, 7, 8, 8, 1, 7, 0,1666, 1000, 320, 400},
{C40X50, COLOUR_PALETTE, 40, 50, 7, 7, 8, 8, 7, 0, 4, 3, 320, 400},
/* CO 40x60 */
{C40X60, COLOUR_PALETTE, 40, 60, 7, 7, 8, 8, 1, 7, 0, 2, 1, 320, 480},
{C40X60, COLOUR_PALETTE, 40, 60, 7, 7, 8, 8, 7, 0, 4, 3, 320, 480},
/* CO 80x14 */
{C80X14, COLOUR_PALETTE, 80, 14, 14, 15, 16, 8, 1, 7, 0, 466, 1000, 640, 224},
{C80X14, COLOUR_PALETTE, 80, 14, 14, 15, 16, 8, 7, 0, 4, 3, 640, 224},
/* CO 80x21 */
{C80X21, COLOUR_PALETTE, 80, 21, 14, 15, 16, 8, 1, 7, 0, 698, 1000, 640, 336},
{C80X21, COLOUR_PALETTE, 80, 21, 14, 15, 16, 8, 7, 0, 4, 3, 640, 336},
/* CO 80x28 */
{C80X28, COLOUR_PALETTE, 80, 28, 12, 13, 14, 8, 1, 7, 0, 817, 1000, 640, 392},
{C80X28, COLOUR_PALETTE, 80, 28, 12, 13, 14, 8, 7, 0, 4, 3, 640, 392},
/* CO 80x30 */
{C80X30, COLOUR_PALETTE, 80, 30, 14, 15, 16, 8, 1, 7, 0, 1, 1, 640, 480},
{C80X30, COLOUR_PALETTE, 80, 30, 14, 15, 16, 8, 7, 0, 4, 3, 640, 480},
/* CO 80x43 */
{C80X43, COLOUR_PALETTE, 80, 43, 7, 7, 8, 8, 1, 7, 0, 729, 1000, 640, 350},
{C80X43, COLOUR_PALETTE, 80, 43, 7, 7, 8, 8, 7, 0, 4, 3, 640, 350},
/* EGA 80x25 */
{EGA80X25, COLOUR_PALETTE, 80, 25, 12, 13, 14, 8, 1, 7, 0, 729, 1000, 640, 350},
{EGA80X25, COLOUR_PALETTE, 80, 25, 12, 13, 14, 8, 7, 0, 4, 3, 640, 350},
/* CO 80x50 */
{C80X50, COLOUR_PALETTE, 80, 50, 7, 7, 8, 8, 1, 7, 0, 833, 1000, 640, 400},
{C80X50, COLOUR_PALETTE, 80, 50, 7, 7, 8, 8, 7, 0, 4, 3, 640, 400},
/* CO 80x60 */
{C80X60, COLOUR_PALETTE, 80, 60, 7, 7, 8, 8, 1, 7, 0, 1, 1, 640, 480},
{C80X60, COLOUR_PALETTE, 80, 60, 7, 7, 8, 8, 7, 0, 4, 3, 640, 480},
/* B 40x14 */
{BW40X14, GREYSCALE_PALETTE, 40, 14, 14, 15, 16, 8, 1, 7, 0, 933, 1000, 320, 224},
{BW40X14, GREYSCALE_PALETTE, 40, 14, 14, 15, 16, 8, 7, 0, 4, 3, 320, 224},
/* BW 40x21 */
{BW40X21, GREYSCALE_PALETTE, 40, 21, 14, 15, 16, 8, 1, 7, 0, 14, 10, 320, 336},
{BW40X21, GREYSCALE_PALETTE, 40, 21, 14, 15, 16, 8, 7, 0, 4, 3, 320, 336},
/* BW 40x28 */
{BW40X28, GREYSCALE_PALETTE, 40, 28, 12, 13, 14, 8, 1, 7, 0,1633, 1000, 320, 392},
{BW40X28, GREYSCALE_PALETTE, 40, 28, 12, 13, 14, 8, 7, 0, 4, 3, 320, 392},
/* BW 40x43 */
{BW40X43, GREYSCALE_PALETTE, 40, 43, 7, 7, 14, 8, 1, 7, 0,1458, 1000, 320, 350},
{BW40X43, GREYSCALE_PALETTE, 40, 43, 7, 7, 14, 8, 7, 0, 4, 3, 320, 350},
/* BW 40x50 */
{BW40X50, GREYSCALE_PALETTE, 40, 50, 7, 7, 8, 8, 1, 7, 0,1667, 1000, 320, 400},
{BW40X50, GREYSCALE_PALETTE, 40, 50, 7, 7, 8, 8, 7, 0, 4, 3, 320, 400},
/* BW 40x60 */
{BW40X60, GREYSCALE_PALETTE, 40, 60, 7, 7, 8, 8, 1, 7, 0, 2, 1, 320, 480},
{BW40X60, GREYSCALE_PALETTE, 40, 60, 7, 7, 8, 8, 7, 0, 4, 3, 320, 480},
/* BW 80x14 */
{BW80X14, GREYSCALE_PALETTE, 80, 14, 14, 15, 16, 8, 1, 7, 0, 467, 1000, 640, 224},
{BW80X14, GREYSCALE_PALETTE, 80, 14, 14, 15, 16, 8, 7, 0, 4, 3, 640, 224},
/* BW 80x21 */
{BW80X21, GREYSCALE_PALETTE, 80, 21, 14, 15, 16, 8, 1, 7, 0, 7, 10, 640, 336},
{BW80X21, GREYSCALE_PALETTE, 80, 21, 14, 15, 16, 8, 7, 0, 4, 3, 640, 336},
/* BW 80x28 */
{BW80X28, GREYSCALE_PALETTE, 80, 28, 12, 13, 14, 8, 1, 7, 0, 817, 1000, 640, 392},
{BW80X28, GREYSCALE_PALETTE, 80, 28, 12, 13, 14, 8, 7, 0, 4, 3, 640, 392},
/* BW 80x43 */
{BW80X43, GREYSCALE_PALETTE, 80, 43, 7, 7, 14, 8, 1, 7, 0, 729, 1000, 640, 350},
{BW80X43, GREYSCALE_PALETTE, 80, 43, 7, 7, 14, 8, 7, 0, 4, 3, 640, 350},
/* BW 80x50 */
{BW80X50, GREYSCALE_PALETTE, 80, 50, 7, 7, 8, 8, 1, 7, 0, 833, 1000, 640, 400},
{BW80X50, GREYSCALE_PALETTE, 80, 50, 7, 7, 8, 8, 7, 0, 4, 3, 640, 400},
/* BW 80x60 */
{BW80X60, GREYSCALE_PALETTE, 80, 60, 7, 7, 8, 8, 1, 7, 0, 1, 1, 640, 480},
{BW80X60, GREYSCALE_PALETTE, 80, 60, 7, 7, 8, 8, 7, 0, 4, 3, 640, 480},
/* MONO 80x14 */
{MONO14, MONO_PALETTE, 80, 14, 14, 15, 16, 8, 1, 7, 0, 467, 1000, 640, 224},
{MONO14, MONO_PALETTE, 80, 14, 14, 15, 16, 8, 7, 0, 4, 3, 640, 224},
/* MONO 80x21 */
{MONO21, MONO_PALETTE, 80, 21, 14, 15, 16, 8, 1, 7, 0, 7, 10, 640, 336},
{MONO21, MONO_PALETTE, 80, 21, 14, 15, 16, 8, 7, 0, 4, 3, 640, 336},
/* MONO 80x28 */
{MONO28, MONO_PALETTE, 80, 28, 12, 13, 14, 8, 1, 7, 0, 817, 1000, 640, 392},
{MONO28, MONO_PALETTE, 80, 28, 12, 13, 14, 8, 7, 0, 4, 3, 640, 392},
/* MONO 80x43 */
{MONO43, MONO_PALETTE, 80, 43, 7, 7, 14, 8, 1, 7, 0, 729, 1000, 640, 350},
{MONO43, MONO_PALETTE, 80, 43, 7, 7, 14, 8, 7, 0, 4, 3, 640, 350},
/* MONO 80x50 */
{MONO50, MONO_PALETTE, 80, 50, 7, 7, 8, 8, 1, 7, 0, 833, 1000, 640, 400},
{MONO50, MONO_PALETTE, 80, 50, 7, 7, 8, 8, 7, 0, 4, 3, 640, 400},
/* MONO 80x60 */
{MONO60, MONO_PALETTE, 80, 60, 7, 7, 8, 8, 1, 7, 0, 1, 1, 640, 480},
{MONO60, MONO_PALETTE, 80, 60, 7, 7, 8, 8, 7, 0, 4, 3, 640, 480},
/* Magical C4350 Mode */
{C4350, COLOUR_PALETTE, 80, 50, 7, 7, 8, 8, 1, 7, 0, 833, 1000, 640, 400},
{C4350, COLOUR_PALETTE, 80, 50, 7, 7, 8, 8, 7, 0, 4, 3, 640, 400},
/* Commodore 64 40x25 mode */
{C64_40X25, C64_PALETTE, 40, 25, 0, 7, 8, 8, 1, 0x6e, CIOLIB_VIDEO_BGBRIGHT|CIOLIB_VIDEO_NOBLINK, 240, 312, 320, 200},
// This is the NTSC aspect ratio... the pixel aspect ratio is about 75:100 due to the
// borders.
{C64_40X25, C64_PALETTE, 40, 25, 0, 7, 8, 8, 0x6e, CIOLIB_VIDEO_BGBRIGHT|CIOLIB_VIDEO_NOBLINK, 6, 5, 320, 200},
/* Commodore 128 40x25 mode */
{C128_40X25, C64_PALETTE, 40, 25, 0, 7, 8, 8, 1, 0xbd, CIOLIB_VIDEO_BGBRIGHT|CIOLIB_VIDEO_NOBLINK, 240, 312, 320, 200},
// The C128 uses the same aspect ratio as the C64 in 40 column mode
{C128_40X25, C64_PALETTE, 40, 25, 0, 7, 8, 8, 0xbd, CIOLIB_VIDEO_BGBRIGHT|CIOLIB_VIDEO_NOBLINK, 6, 5, 320, 200},
/* Commodore 128 80x25 mode */
{C128_80X25, COLOUR_PALETTE, 80, 25, 0, 7, 8, 8, 2, 7, CIOLIB_VIDEO_BGBRIGHT|CIOLIB_VIDEO_NOBLINK, 240, 312, 640, 200},
// But in 80-column mode is a 4:3 CGA style output.
{C128_80X25, COLOUR_PALETTE, 80, 25, 0, 7, 8, 8, 7, CIOLIB_VIDEO_BGBRIGHT|CIOLIB_VIDEO_NOBLINK, 4, 3, 640, 200},
/* Atari 800 40x24 mode */
{ATARI_40X24, ATARI_PALETTE, 40, 24, 0, 7, 8, 8, 1, 7, 0, 4, 10, 320, 192},
{ATARI_40X24, ATARI_PALETTE, 40, 24, 0, 7, 8, 8, 7, 0, 4, 3, 320, 192},
/* Atari 800 XEP80 80x25 mode */
{ATARI_80X25, GREYSCALE_PALETTE, 80, 25, 0, 15, 16, 8, 1, 7, 0, 833, 1000, 640, 400},
{ATARI_80X25, GREYSCALE_PALETTE, 80, 25, 0, 15, 16, 8, 7, 0, 4, 3, 640, 400},
/* VESA 21x132 mode */
{VESA_132X21, COLOUR_PALETTE, 132, 21, 14, 15, 16, 8, 1, 7, 0, 424, 1000, 1056, 336},
{VESA_132X21, COLOUR_PALETTE, 132, 21, 14, 15, 16, 8, 7, 0, 4, 3, 1056, 336},
/* VESA 25x132 mode */
{VESA_132X25, COLOUR_PALETTE, 132, 25, 14, 15, 16, 8, 1, 7, 0, 505, 1000, 1056, 400},
{VESA_132X25, COLOUR_PALETTE, 132, 25, 14, 15, 16, 8, 7, 0, 4, 3, 1056, 400},
/* VESA 28x132 mode */
{VESA_132X28, COLOUR_PALETTE, 132, 28, 12, 13, 14, 8, 1, 7, 0, 495, 1000, 1056, 392},
{VESA_132X28, COLOUR_PALETTE, 132, 28, 12, 13, 14, 8, 7, 0, 4, 3, 1056, 392},
/* VESA 30x132 mode */
{VESA_132X30, COLOUR_PALETTE, 132, 30, 14, 15, 16, 8, 1, 7, 0, 606, 1000, 1056, 480},
{VESA_132X30, COLOUR_PALETTE, 132, 30, 14, 15, 16, 8, 7, 0, 4, 3, 1056, 480},
/* VESA 34x132 mode */
{VESA_132X34, COLOUR_PALETTE, 132, 34, 12, 13, 14, 8, 1, 7, 0, 601, 1000, 1056, 476},
{VESA_132X34, COLOUR_PALETTE, 132, 34, 12, 13, 14, 8, 7, 0, 4, 3, 1056, 476},
/* VESA 43x132 mode */
{VESA_132X43, COLOUR_PALETTE, 132, 43, 7, 7, 8, 8, 1, 7, 0, 442, 1000, 1056, 350},
{VESA_132X43, COLOUR_PALETTE, 132, 43, 7, 7, 8, 8, 7, 0, 4, 3, 1056, 350},
/* VESA 50x132 mode */
{VESA_132X50, COLOUR_PALETTE, 132, 50, 7, 7, 8, 8, 1, 7, 0, 505, 1000, 1056, 400},
{VESA_132X50, COLOUR_PALETTE, 132, 50, 7, 7, 8, 8, 7, 0, 4, 3, 1056, 400},
/* VESA 60x132 mode */
{VESA_132X60, COLOUR_PALETTE, 132, 60, 7, 7, 8, 8, 1, 7, 0, 606, 1000, 1056, 480},
{VESA_132X60, COLOUR_PALETTE, 132, 60, 7, 7, 8, 8, 7, 0, 4, 3, 1056, 480},
/* Awesome modes */
{ST132X37_16_9, COLOUR_PALETTE, 132, 37, 14, 15, 16, 8, 1, 7, 0, 1, 1, 1056, 600},
{ST132X52_5_4, COLOUR_PALETTE, 132, 52, 14, 15, 16, 8, 1, 7, 0, 1, 1, 1056, 823},
{ST132X37_16_9, COLOUR_PALETTE, 132, 37, 14, 15, 16, 8, 7, 0, 16, 9, 1056, 600},
{ST132X52_5_4, COLOUR_PALETTE, 132, 52, 14, 15, 16, 8, 7, 0, 5, 4, 1056, 823},
/* Stupid modes */
{VGA80X25, COLOUR_PALETTE, 80, 25, 14, 15, 16, 9, 1, 7, CIOLIB_VIDEO_EXPAND | CIOLIB_VIDEO_LINE_GRAPHICS_EXPAND, 740, 1000, 720, 400},
{VGA80X25, COLOUR_PALETTE, 80, 25, 14, 15, 16, 9, 7, CIOLIB_VIDEO_EXPAND | CIOLIB_VIDEO_LINE_GRAPHICS_EXPAND, 4, 3, 720, 400},
/* Custom mode */
{CIOLIB_MODE_CUSTOM, COLOUR_PALETTE, 80, 25, 14, 15, 16, 8, 1, 7, 0, 1, 1, -1, -1},
{CIOLIB_MODE_CUSTOM, COLOUR_PALETTE, 80, 25, 14, 15, 16, 8, 7, 0, 0, 0, -1, -1},
};
uint32_t palettes[5][16] = {
......@@ -340,10 +344,13 @@ int load_vmode(struct video_stats *vs, int mode)
vs->charheight=vparams[i].charheight;
vs->charwidth=vparams[i].charwidth;
vs->mode=mode;
vs->vmultiplier=vparams[i].vmultiplier;
vs->currattr = vparams[i].default_attr;
vs->scale_numerator = vparams[i].scale_numerator;
vs->scale_denominator = vparams[i].scale_denominator;
vs->aspect_width = vparams[i].aspect_width;
vs->aspect_height = vparams[i].aspect_height;
if (vs->aspect_width == 0 || vs->aspect_height == 0) {
vs->aspect_width = vs->scrnwidth;
vs->aspect_height = vs->scrnheight;
}
if (vparams[i].xres > 0)
vs->scrnwidth = vparams[i].xres;
else
......
......@@ -61,11 +61,10 @@ struct video_params {
int curs_end;
int charheight;
int charwidth;
int vmultiplier;
int default_attr;
int flags;
int scale_numerator;
int scale_denominator;
int aspect_width;
int aspect_height;
int xres;
int yres;
};
......@@ -98,13 +97,12 @@ struct video_stats {
int blink_altcharset;
int currattr;
int scaling;
int vmultiplier;
int scrnwidth;
int scrnheight;
int winwidth;
int winheight;
int scale_numerator;
int scale_denominator;
int aspect_width;
int aspect_height;
uint32_t flags;
#define VIDMODES_FLAG_PALETTE_VMEM 1
#define VIDMODES_FLAG_EXPAND 2
......
......@@ -210,9 +210,9 @@ static struct {
static void resize_xim(void)
{
int width = bitmap_width * x_cvstat.scaling;
double ratio = (double)x_cvstat.scale_numerator / x_cvstat.scale_denominator;
int height = lround((double)(bitmap_height * x_cvstat.scaling * x_cvstat.vmultiplier) / ratio);
int height = bitmap_height * x_cvstat.scaling;
aspect_correct(&width, &height, x_cvstat.aspect_width, x_cvstat.aspect_height);
if (xim) {
if (width == xim->width
&& height == xim->height) {
......@@ -310,7 +310,7 @@ static int init_window()
wa.border_pixel = black;
depth = best_depth;
win = x11.XCreateWindow(dpy, DefaultRootWindow(dpy), 0, 0,
640*x_cvstat.scaling, 400*x_cvstat.scaling*x_cvstat.vmultiplier, 2, depth, InputOutput, &visual, CWColormap | CWBorderPixel | CWBackPixel, &wa);
640*x_cvstat.scaling, 400*x_cvstat.scaling, 2, depth, InputOutput, &visual, CWColormap | CWBorderPixel | CWBackPixel, &wa);
classhints=x11.XAllocClassHint();
if (classhints)
......@@ -356,37 +356,44 @@ static int init_window()
*/
static void map_window()
{
XSizeHints *sh;
XSizeHints *sh;
int scaled_height;
int minwidth = bitmap_width;
int minheight = bitmap_height;
sh = x11.XAllocSizeHints();
if (sh == NULL) {
sh = x11.XAllocSizeHints();
if (sh == NULL) {
fprintf(stderr, "Could not get XSizeHints structure");
exit(1);
}
sh->base_width = bitmap_width*x_cvstat.scaling;
sh->base_height = bitmap_height*x_cvstat.scaling*x_cvstat.vmultiplier;
sh->base_width = bitmap_width * x_cvstat.scaling;
sh->base_height = bitmap_height * x_cvstat.scaling;
sh->min_width = sh->width_inc = sh->min_aspect.x = sh->max_aspect.x = bitmap_width;
aspect_correct(&sh->base_width, &sh->base_height, x_cvstat.aspect_width, x_cvstat.aspect_height);
aspect_correct(&minwidth, &minheight, x_cvstat.aspect_width, x_cvstat.aspect_height);
scaled_height = ceil((double)bitmap_height*x_cvstat.vmultiplier / ((double)x_cvstat.scale_numerator / x_cvstat.scale_denominator));
sh->min_height = sh->height_inc = sh->min_aspect.y = sh->max_aspect.y = scaled_height;
sh->flags = USSize | PMinSize | PSize | PResizeInc | PAspect;
sh->min_width = sh->width_inc = sh->min_aspect.x = sh->max_aspect.x = minwidth;
sh->min_height = sh->height_inc = sh->min_aspect.y = sh->max_aspect.y = minheight;
x11.XSetWMNormalHints(dpy, win, sh);
x11.XMapWindow(dpy, win);
sh->flags = USSize | PMinSize | PSize | PResizeInc | PAspect;
x11.XFree(sh);
x11.XSetWMNormalHints(dpy, win, sh);
x11.XMapWindow(dpy, win);
return;
x11.XFree(sh);
return;
}
/* Resize the window. This function is called after a mode change. */
static void resize_window()
{
int scaled_height = ceil((double)bitmap_height*x_cvstat.scaling*x_cvstat.vmultiplier / ((double)x_cvstat.scale_numerator / x_cvstat.scale_denominator));
x11.XResizeWindow(dpy, win, bitmap_width*x_cvstat.scaling, scaled_height);
int width = bitmap_width * x_cvstat.scaling;
int height = bitmap_height * x_cvstat.scaling;
aspect_correct(&width, &height, x_cvstat.aspect_width, x_cvstat.aspect_height);
x11.XResizeWindow(dpy, win, width, height);
resize_xim();
return;
......@@ -415,8 +422,6 @@ static void init_mode_internal(int mode)
}
if(vstat.scaling < 1)
vstat.scaling = 1;
if(vstat.vmultiplier < 1)
vstat.vmultiplier = 1;
x_cvstat = vstat;
pthread_mutex_unlock(&vstatlock);
......@@ -449,8 +454,6 @@ static int video_init()
lot easier. */
if(x_cvstat.scaling<1)
x_setscaling(1);
if(x_cvstat.vmultiplier<1)
x_cvstat.vmultiplier=1;
if(init_window())
return(-1);
......@@ -487,7 +490,7 @@ static void local_draw_rect(struct rectlist *rect)
yoff = 0;
// Scale...
source = do_scale(rect, x_cvstat.scaling, x_cvstat.scaling * x_cvstat.vmultiplier, (double)x_cvstat.scale_numerator / x_cvstat.scale_denominator);
source = do_scale(rect, x_cvstat.scaling, x_cvstat.scaling, x_cvstat.aspect_width, x_cvstat.aspect_height);
bitmap_drv_free_rect(rect);
if (source == NULL)
return;
......@@ -581,10 +584,10 @@ static void handle_resize_event(int width, int height)
{
int newFSH=1;
int newFSW=1;
double ratio = (double)x_cvstat.scale_numerator / x_cvstat.scale_denominator;
newFSH=width/bitmap_width;
newFSW=floor((double)height / bitmap_height * ratio);
aspect_fix(&width, &height, x_cvstat.aspect_width, x_cvstat.aspect_height);
newFSH=width / bitmap_width;
newFSW=height / bitmap_height;
if(newFSW<1)
newFSW=1;
if(newFSH<1)
......@@ -604,11 +607,6 @@ static void handle_resize_event(int width, int height)
*/
if (newFSH != newFSW)
resize_window();
#if 0 // TODO: Is this even worth looking at?
else if((width % (x_cvstat.charwidth * x_cvstat.cols) != 0)
|| (height % (x_cvstat.charheight * x_cvstat.rows) != 0))
resize_window();
#endif
else
resize_xim();
bitmap_drv_request_pixels();
......@@ -636,7 +634,7 @@ static void expose_rect(int x, int y, int width, int height)
}
sx=(x-xoff)/x_cvstat.scaling;
sy=(y-yoff)/(x_cvstat.scaling*x_cvstat.vmultiplier);
sy=(y-yoff)/(x_cvstat.scaling);
if (sx < 0)
sx = 0;
if (sy < 0)
......@@ -651,11 +649,11 @@ static void expose_rect(int x, int y, int width, int height)
if((ex+1)%x_cvstat.scaling) {
ex += x_cvstat.scaling-(ex%x_cvstat.scaling);
}
if((ey+1)%(x_cvstat.scaling*x_cvstat.vmultiplier)) {
ey += x_cvstat.scaling*x_cvstat.vmultiplier-(ey%(x_cvstat.scaling*x_cvstat.vmultiplier));
if((ey+1)%(x_cvstat.scaling)) {
ey += x_cvstat.scaling-(ey%(x_cvstat.scaling));
}
ex=ex/x_cvstat.scaling;
ey=ey/(x_cvstat.scaling*x_cvstat.vmultiplier);
ey=ey/(x_cvstat.scaling);
/* Since we're exposing, we *have* to redraw */
if (last) {
......@@ -710,7 +708,9 @@ static int x11_event(XEvent *ev)
}
break;
/* Graphics related events */
case ConfigureNotify:
case ConfigureNotify: {
int width, height;
if (x11_window_xpos != ev->xconfigure.x || x11_window_ypos != ev->xconfigure.y
|| x11_window_width != ev->xconfigure.width || x11_window_height != ev->xconfigure.height) {
x11_window_xpos=ev->xconfigure.x;
......@@ -718,8 +718,39 @@ static int x11_event(XEvent *ev)
x11_window_width=ev->xconfigure.width;
x11_window_height=ev->xconfigure.height;
handle_resize_event(ev->xconfigure.width, ev->xconfigure.height);
break;
}
width = bitmap_width * x_cvstat.scaling;
height = bitmap_height * x_cvstat.scaling;
aspect_correct(&width, &height, x_cvstat.aspect_width, x_cvstat.aspect_height);
if (ev->xconfigure.width != width || ev->xconfigure.height != height) {
// We can't have the size we requested... accept the size we got.
int newFSH=1;
int newFSW=1;
width = ev->xconfigure.width;
height = ev->xconfigure.height;
aspect_fix(&width, &height, x_cvstat.aspect_width, x_cvstat.aspect_height);
newFSH=width / bitmap_width;
newFSW=height / bitmap_height;
if(newFSW<1)
newFSW=1;
if(newFSH<1)
newFSH=1;
if(newFSH<newFSW)
x_setscaling(newFSH);
else
x_setscaling(newFSW);
old_scaling = x_cvstat.scaling;
if(x_cvstat.scaling > 16)
x_setscaling(16);
resize_xim();
bitmap_drv_request_pixels();
}
break;
}
case NoExpose:
break;
case GraphicsExpose:
......
......@@ -1555,6 +1555,8 @@ custom_mode_adjusted(int *cur, char **opt)
vparams[cvmode].cols = settings.custom_cols;
vparams[cvmode].rows = settings.custom_rows;
vparams[cvmode].charheight = settings.custom_fontheight;
vparams[cvmode].aspect_width = settings.custom_aw;
vparams[cvmode].aspect_height = settings.custom_ah;
}
return;
}
......@@ -1566,6 +1568,8 @@ custom_mode_adjusted(int *cur, char **opt)
vparams[cvmode].cols = settings.custom_cols;
vparams[cvmode].rows = settings.custom_rows;
vparams[cvmode].charheight = settings.custom_fontheight;
vparams[cvmode].aspect_width = settings.custom_aw;
vparams[cvmode].aspect_height = settings.custom_ah;
textmode(ti.currmode);
}
init_uifc(TRUE, TRUE);
......@@ -1590,7 +1594,7 @@ void change_settings(int connected)
str_list_t inicontents;
char opts[13][80];
char *opt[14];
char *subopts[8];
char *subopts[10];
int i,j,k,l;
char str[64];
int cur=0;
......@@ -1883,10 +1887,12 @@ void change_settings(int connected)
j = 0;
for (k=0; k==0;) {
// Beware case 2 below if adding things
asprintf(&subopts[0], "Rows (%d)", settings.custom_rows);
asprintf(&subopts[1], "Columns (%d)", settings.custom_cols);
asprintf(&subopts[2], "Font Size (%s)", settings.custom_fontheight == 8 ? "8x8" : settings.custom_fontheight == 14 ? "8x14" : "8x16");
subopts[3] = NULL;
asprintf(&subopts[0], "Rows (%d)", settings.custom_rows);
asprintf(&subopts[1], "Columns (%d)", settings.custom_cols);
asprintf(&subopts[2], "Font Size (%s)", settings.custom_fontheight == 8 ? "8x8" : settings.custom_fontheight == 14 ? "8x14" : "8x16");
asprintf(&subopts[3], "Aspect Ratio Width (%d)", settings.custom_aw);
asprintf(&subopts[4], "Aspect Ratio Height (%d)", settings.custom_ah);
subopts[5] = NULL;
switch (uifc.list(WIN_SAV,0,0,0,&j,NULL,"Video Output Mode",subopts)) {
case -1:
check_exit(FALSE);
......@@ -1930,10 +1936,10 @@ void change_settings(int connected)
case 2:
uifc.helpbuf= "`Font Size`\n\n"
"Choose the font size for the custom mode.";
subopts[4] = "8x8";
subopts[5] = "8x14";
subopts[6] = "8x16";
subopts[7] = NULL;
subopts[6] = "8x8";
subopts[7] = "8x14";
subopts[8] = "8x16";
subopts[9] = NULL;
switch(settings.custom_fontheight) {
case 8:
l = 0;
......@@ -1965,10 +1971,46 @@ void change_settings(int connected)
custom_mode_adjusted(&cur, opt);
break;
}
case 3:
uifc.helpbuf= "`Aspect Ratio Width`\n\n"
"Width part of the aspect ratio. Historically, this has been 4";
sprintf(str,"%d",settings.custom_aw);
if (uifc.input(WIN_SAV|WIN_MID, 0, 0, "Aspect Ratio Width", str, 9, K_NUMBER|K_EDIT)!=-1) {
l = atoi(str);
if (l <= 0) {
uifc.msg("Aspec Ratio Width must be greater than zero");
check_exit(FALSE);
}
else {
settings.custom_aw = l;
iniSetInteger(&inicontents, "SyncTERM", "CustomAspectWidth", settings.custom_aw, &ini_style);
custom_mode_adjusted(&cur, opt);
}
}
break;
case 4:
uifc.helpbuf= "`Aspect Ratio Height`\n\n"
"Height part of the aspect ratio. Historically, this has been 3";
sprintf(str,"%d",settings.custom_ah);
if (uifc.input(WIN_SAV|WIN_MID, 0, 0, "Aspect Ratio Height", str, 9, K_NUMBER|K_EDIT)!=-1) {
l = atoi(str);
if (l <= 0) {
uifc.msg("Aspec Ratio Height must be greater than zero");
check_exit(FALSE);
}
else {
settings.custom_ah = l;
iniSetInteger(&inicontents, "SyncTERM", "CustomAspectHeight", settings.custom_ah, &ini_style);
custom_mode_adjusted(&cur, opt);
}
}
break;
}
free(subopts[0]);
free(subopts[1]);
free(subopts[2]);
free(subopts[3]);
free(subopts[4]);
}
}
}
......
......@@ -10420,12 +10420,12 @@ do_rip_command(int level, int sublevel, int cmd, const char *rawargs)
GET_XY2();
arg1 = parse_mega(&args[8], 2);
pthread_mutex_lock(&vstatlock);
if (vstat.scale_numerator == 729 && vstat.scale_denominator == 1000) {
if (vstat.scrnwidth == 640 && vstat.scrnheight == 350) {
// Detect EGA mode and use the same value as RIPterm did.
arg3 = (arg1 * 7750 / 10000);
}
else {
arg3 = arg1 * vstat.scale_numerator / vstat.scale_denominator;
arg3 = arg1 * ((double)vstat.scrnwidth / vstat.scrnheight) / ((double)vstat.aspect_width / vstat.aspect_height);
}
pthread_mutex_unlock(&vstatlock);
full_ellipse(x1, y1, x2, y2, arg1, arg3, false, map_rip_color(rip.color));
......@@ -10470,12 +10470,12 @@ do_rip_command(int level, int sublevel, int cmd, const char *rawargs)
GET_XY();
arg1 = parse_mega(&args[4], 2);
pthread_mutex_lock(&vstatlock);
if (vstat.scale_numerator == 729 && vstat.scale_denominator == 1000) {
if (vstat.scrnwidth == 640 && vstat.scrnheight == 350) {
// Detect EGA mode and use the same value as RIPterm did.
arg3 = (arg1 * 7750 / 10000);
}
else {
arg3 = arg1 * vstat.scale_numerator / vstat.scale_denominator;
arg3 = arg1 * ((double)vstat.scrnwidth / vstat.scrnheight) / ((double)vstat.aspect_width / vstat.aspect_height);
}
pthread_mutex_unlock(&vstatlock);
if (arg1 == 1)
......@@ -10574,12 +10574,12 @@ do_rip_command(int level, int sublevel, int cmd, const char *rawargs)
GET_XY2();
arg1 = parse_mega(&args[8], 2);
pthread_mutex_lock(&vstatlock);
if (vstat.scale_numerator == 729 && vstat.scale_denominator == 1000) {
if (vstat.scrnwidth == 640 && vstat.scrnheight == 350) {
// Detect EGA mode and use the same value as RIPterm did.
arg3 = (arg1 * 7750 / 10000);
}
else {
arg3 = arg1 * vstat.scale_numerator / vstat.scale_denominator;
arg3 = arg1 * ((double)vstat.scrnwidth / vstat.scrnheight) / ((double)vstat.aspect_width / vstat.aspect_height);
}
pthread_mutex_unlock(&vstatlock);
fg = map_rip_color(rip.color) | 0x40000000;
......
......@@ -59,6 +59,7 @@ static const KNOWNFOLDERID FOLDERID_ProgramData = {0x62AB5D82,0xFDC1,0x4DC3,{0x
#include "term.h"
#include "uifcinit.h"
#include "window.h"
#include "scale.h"
char* syncterm_version = "SyncTERM 1.2a"
#define ALPHA
......@@ -1248,6 +1249,8 @@ void load_settings(struct syncterm_settings *set)
set->custom_cols = iniReadInteger(inifile, "SyncTERM", "CustomCols", 80);
set->custom_rows = iniReadInteger(inifile, "SyncTERM", "CustomRows", 25);
set->custom_fontheight = iniReadInteger(inifile, "SyncTERM", "CustomFontHeight", 16);
set->custom_aw = iniReadInteger(inifile, "SyncTERM", "CustomAspectWidth", 4);
set->custom_ah = iniReadInteger(inifile, "SyncTERM", "CustomAspectHeight", 3);
get_syncterm_filename(set->list_path, sizeof(set->list_path), SYNCTERM_PATH_LIST, FALSE);
iniReadString(inifile, "SyncTERM", "ListPath", set->list_path, set->list_path);
set->scaling_factor=iniReadInteger(inifile,"SyncTERM","ScalingFactor",0);
......@@ -1465,8 +1468,11 @@ int main(int argc, char **argv)
vparams[cvmode].cols = settings.custom_cols;
vparams[cvmode].rows = settings.custom_rows;
vparams[cvmode].charheight = settings.custom_fontheight;
vparams[cvmode].aspect_width = settings.custom_aw;
vparams[cvmode].aspect_height = settings.custom_ah;
ciolib_initial_window_height = settings.window_height;
ciolib_initial_window_width = settings.window_width;
aspect_correct(&ciolib_initial_window_width, &ciolib_initial_window_height, settings.custom_aw, settings.custom_ah);
ciolib_mode=settings.output_mode;
if(settings.startup_mode != SCREEN_MODE_CURRENT)
text_mode=screen_to_ciolib(settings.startup_mode);
......
......@@ -62,6 +62,8 @@ struct syncterm_settings {
int custom_cols;
int custom_rows;
int custom_fontheight;
int custom_aw;
int custom_ah;
int window_width;
int window_height;
int left_just;
......