Does anyone know what algo XP -> full screen DOS?

Windows specific questions.
Post Reply
angros47
Posts: 2324
Joined: Jun 21, 2005 19:04

Re: Does anyone know what algo XP -> full screen DOS?

Post by angros47 »

CGAMan wrote:Anyways, plz make a +20fps version of counting_pine's natural LCD upscaling exactly the way his algo worked, but at really insane speed...
How much are you willing to pay for that? You are commissioning a work, with that request.
paul doe
Moderator
Posts: 1733
Joined: Jul 25, 2017 17:22
Location: Argentina

Re: Does anyone know what algo XP -> full screen DOS?

Post by paul doe »

angros47 wrote:How much are you willing to pay for that? You are commissioning a work, with that request.
Hahaha take it easy, pal. I simply don't have the time right now. I'm almost finished anyway, it isn't that hard. The required code is pretty much laid out in this thread, just figuring out how to speed it =D

I understand your posture, though. The request did made my eye flick for a moment also ;)
CGAMan
Posts: 31
Joined: Nov 24, 2017 18:23

Re: Does anyone know what algo XP -> full screen DOS?

Post by CGAMan »

angros47 wrote:
CGAMan wrote:Anyways, plz make a +20fps version of counting_pine's natural LCD upscaling exactly the way his algo worked, but at really insane speed...
How much are you willing to pay for that? You are commissioning a work, with that request.
Nil.

Here are my options:

1. Already have it in C# (managed to tweak it up to 3fps just now). Reality is I only need about 1fps to accomplish my task. 20fps is more like "let's develop some silly fun-time games along the way".

2. I can revert to WinXP+QBASIC. It's already native there without even implementing custom algo (SCREEN 12 gives me +30fps of glorious N.L.U. in WinXP)

(2b. Never mind XP being obsolete. I have X number of machines that are XP capable, some of them pretty modern of the Ivy Bridge class, which assures my continued usage of XP for another 2 decades or more.)

3. I can wait until a 21fps FreeBASIC version, but then I will need to rewrite my program again to the FreeBASIC language.


(Sorry for the harsh reply btw. But currently looking at FreeBASIC as an enthusiast IDE only. Also, I don't understand why a project seeks to emulate the DOS environment but can't even provide the basic features like a full screen output... By which I don't mean a full resolution output, but an upscaled 640x400 or 320x200 just like old times.)


UPDATE: I have removed all algos from my system I've downloaded from this site, except the NLU one by counting_pine. Not the 2nd edition that was a bit more complex and difficult to understand, but the much simpler first one. Plz do NOT rewrite this algo for much faster speed. Certainly, the attitude of the FreeBASIC community makes QBASIC+DosBox all the more appealing option... should I ever even feel the need to rewrite my fully functional program that is...
Last edited by CGAMan on Dec 17, 2017 3:32, edited 2 times in total.
paul doe
Moderator
Posts: 1733
Joined: Jul 25, 2017 17:22
Location: Argentina

Re: Does anyone know what algo XP -> full screen DOS?

Post by paul doe »

CGAMan wrote:(Sorry for the harsh reply btw. But currently looking at FreeBASIC as an enthusiast IDE only. Also, I don't understand why a project seeks to emulate the DOS environment but can't even provide the basic features like a full screen output... By which I don't mean a full resolution output, but an upscaled 640x400 or 320x200 just like old times.)
Two things: first, FreeBasic isn't an IDE. Second, who told you that the goal of the project is to 'emulate the DOS environment'? You can emulate any crap you want, and also code cutting-edge software, if you have the knowledge and desire to do so.
CGAMan wrote: 1. Already have it in C# (managed to tweak it up to 3fps just now). Reality is I only need about 1fps to accomplish my task. 20fps is more like "let's develop some silly fun-time games along the way".

2. I can revert to WinXP+QBASIC. It's already native there without even implementing custom algo (SCREEN 12 gives me +30fps of glorious N.L.U. in WinXP)

(2b. Never mind XP being obsolete. I have X number of machines that are XP capable, some of them pretty modern of the Ivy Bridge class, which assures my continued usage of XP for another 2 decades or more.)

3. I can wait until a 21fps FreeBASIC version, but then I will need to rewrite my program again to the FreeBASIC language.
Why bother, then? If you want to basque in obsolescence, you already have all you need...
CGAMan wrote:UPDATE: I have removed all algos from my system I've downloaded from this site, except the NLU one. Not the 2nd edition that was a bit more complex and difficult to understand, but the much simpler first one. Plz do NOT rewrite this algo for much faster speed. Certainly, the attitude of the FreeBASIC community makes QBASIC+DosBox all the more appealing option... should I ever even feel the need to rewrite my fully functional program that is...
Your loss. The attitude of certain members of the community may be a little harsh, but not everyone. I already finished it, but alas, suit yourself...
Last edited by paul doe on Dec 17, 2017 3:31, edited 1 time in total.
CGAMan
Posts: 31
Joined: Nov 24, 2017 18:23

Re: Does anyone know what algo XP -> full screen DOS?

Post by CGAMan »

Repost:
UPDATE: I have removed all algos from my system I've downloaded from this site, except the NLU one by counting_point. Not the 2nd edition that was a bit more complex and difficult to understand, but the much simpler first one. Plz do NOT rewrite this algo for much faster speed. Certainly, the attitude of the FreeBASIC community makes QBASIC+DosBox all the more appealing option... should I ever even feel the need to rewrite my fully functional program that is...
CGAMan
Posts: 31
Joined: Nov 24, 2017 18:23

Re: Does anyone know what algo XP -> full screen DOS?

Post by CGAMan »

paul doe wrote:
CGAMan wrote:(Sorry for the harsh reply btw. But currently looking at FreeBASIC as an enthusiast IDE only. Also, I don't understand why a project seeks to emulate the DOS environment but can't even provide the basic features like a full screen output... By which I don't mean a full resolution output, but an upscaled 640x400 or 320x200 just like old times.)
Two things: first, FreeBasic isn't an IDE. Second, who told you that the goal of the project is to 'emulate the DOS environment'? You can emulate any crap you want, and also code cutting-edge software, if you have the knowledge and desire to do so.
CGAMan wrote: 1. Already have it in C# (managed to tweak it up to 3fps just now). Reality is I only need about 1fps to accomplish my task. 20fps is more like "let's develop some silly fun-time games along the way".

2. I can revert to WinXP+QBASIC. It's already native there without even implementing custom algo (SCREEN 12 gives me +30fps of glorious N.L.U. in WinXP)

(2b. Never mind XP being obsolete. I have X number of machines that are XP capable, some of them pretty modern of the Ivy Bridge class, which assures my continued usage of XP for another 2 decades or more.)

3. I can wait until a 21fps FreeBASIC version, but then I will need to rewrite my program again to the FreeBASIC language.
Why bother, then? If you want to basque in obsolescence, you already have all you need...
CGAMan wrote:UPDATE: I have removed all algos from my system I've downloaded from this site, except the NLU one. Not the 2nd edition that was a bit more complex and difficult to understand, but the much simpler first one. Plz do NOT rewrite this algo for much faster speed. Certainly, the attitude of the FreeBASIC community makes QBASIC+DosBox all the more appealing option... should I ever even feel the need to rewrite my fully functional program that is...
Your loss. The attitude of certain members of the community may be a little harsh, but not everyone. I already finished it, but alas, suit yourself...
No yours.
angros47
Posts: 2324
Joined: Jun 21, 2005 19:04

Re: Does anyone know what algo XP -> full screen DOS?

Post by angros47 »

CGAMan wrote:Here are my options:

1. Already have it in C# (managed to tweak it up to 3fps just now). Reality is I only need about 1fps to accomplish my task. 20fps is more like "let's develop some silly fun-time games along the way".
This solution has nothing to do with FreeBasic. If you want to go for it, you are on the wrong forum
2. I can revert to WinXP+QBASIC. It's already native there without even implementing custom algo (SCREEN 12 gives me +30fps of glorious N.L.U. in WinXP)
This solution, too, has nothing to do with FreeBasic, so you still would be on the wrong forum.
3. I can wait until a 21fps FreeBASIC version, but then I will need to rewrite my program again to the FreeBASIC language.
Waiting until someone else does the real work for you? I fear you missed the point of how collaborative communities work.

(Sorry for the harsh reply btw. But currently looking at FreeBASIC as an enthusiast IDE only. Also, I don't understand why a project seeks to emulate the DOS environment but can't even provide the basic features like a full screen output... By which I don't mean a full resolution output, but an upscaled 640x400 or 320x200 just like old times.)
1) FreeBasic is a compiler, not an IDE.

2) Since it is open source, if you think it misses some features, you are free to edit the source code and add them
UPDATE: I have removed all algos from my system I've downloaded from this site, except the NLU one by counting_pine. Not the 2nd edition that was a bit more complex and difficult to understand, but the much simpler first one. Plz do NOT rewrite this algo for much faster speed. Certainly, the attitude of the FreeBASIC community makes QBASIC+DosBox all the more appealing option... should I ever even feel the need to rewrite my fully functional program that is...
This passive-aggressive attitude would not get you much help. Don't worry, I have no intention to rewrite the algo for you. If you want to use DosBox, feel free to do it, there is no need for you to inform us about your choice.
lizard
Posts: 440
Joined: Oct 17, 2017 11:35
Location: Germany

Re: Does anyone know what algo XP -> full screen DOS?

Post by lizard »

I would like to see that wonderful super-program CGAMan creates with dos-resolution. Must be something gigantic. :-)
counting_pine
Site Admin
Posts: 6323
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

Re: Does anyone know what algo XP -> full screen DOS?

Post by counting_pine »

I must admit I’m disappointed with the speed of the algorithm, since FB should easily be able to do fairly complex calculations per pixel.
I think the second algorithm is closer to what an efficient implementation should look like. There is definitely scope to improve it by replacing the use of point() with pointer access to the image memory.
paul doe
Moderator
Posts: 1733
Joined: Jul 25, 2017 17:22
Location: Argentina

Re: Does anyone know what algo XP -> full screen DOS?

Post by paul doe »

counting_pine wrote:I must admit I’m disappointed with the speed of the algorithm, since FB should easily be able to do fairly complex calculations per pixel.
I think the second algorithm is closer to what an efficient implementation should look like. There is definitely scope to improve it by replacing the use of point() with pointer access to the image memory.
Bah, I'm getting ~22 FPS with both interpolations (the NLU and the NN, performed at once as per the OP request), but there are still some artifacts (because of all the hacks to improve speed):

Code: Select all

#include once "fbgfx.bi"

function avrg( byval src as ulong, byval dst as ulong, byval opacity as ubyte ) as ulong
  return( ( _
    (          src  and &hff00ff ) * opacity + _
    (          dst  and &hff00ff ) * ( 255 - opacity ) ) and &hff00ff00 ) shr 8 or ( _
    ( ( src shr 8 ) and &hff00ff ) * opacity + _
    ( ( dst shr 8 ) and &hff00ff ) * ( 255 - opacity ) ) and &hff00ff00
end function

sub resizeImage( byval img as fb.image ptr )
	/'
		Resizes a buffer with two filters: first, Natural LCD Upscaling is performed, then this is scaled through
		a Nearest Neighbor interpolation to fit the whole screen
	'/
	dim as integer dstWidth, dstHeight, dstBpp, dstPitch
	screenInfo( dstWidth, dstHeight, , dstBpp, dstPitch )
	
	'' gets the destination pixel data pointer (the screen)
	dim as ulong ptr dst = screenPtr()
	dim as ulong ptr src = cast( ulong ptr, img ) + sizeOf( fb.image ) \ sizeOf( ulong )  
	
	'' these calculations take the padding of the screen and the buffer into account
	dim as integer srcPitch = ( img->pitch \ sizeOf( ulong ) )
	dim as integer srcPadding = ( img->pitch \ sizeOf( ulong ) ) - img->width
	dim as integer dstPadding = ( dstPitch \ dstBpp ) - dstWidth
	
	/'	The increments of the DDA
			If you want to preserve the aspect ratio of the image, use the same '/
	dim as const integer FPScale = 1000000000
	dim as integer incX = int( ( img->width / dstWidth ) * FPScale ) 
	dim as integer incY = int( ( img->height / dstHeight ) * FPScale )
	
	dim as integer ddaX, ddaY
	dim as ulong ptr startX

	'' x and y lookups for scaled coordinates and splits
	dim as single ratioXSD = img->width / dstWidth
	dim as single ratioYSD = img->height / dstHeight
	
	dim as single ratioXDS = dstWidth / img->width
	dim as single ratioYDS = dstHeight / img->height

	dim as integer splConst = 10000000
	
	dim as integer ixStride = frac( dstWidth / img->width ) * splConst
	dim as integer iyStride = frac( dstHeight / img->height ) * splConst
	dim as ubyte splitX, splitY
	
	dim as integer splX, splY, iSplitX, iSplitY
	
	'' ugly hack
	dim as integer xx = 0, yy = 0	
	
	'screenLock()
		ddaY = 0
		splY = splConst
		
		for y as integer = 0 to img->height - 1			
			ddaY -= FPScale
			startX = src
						
				'' NLU sampling
			  if( int( ( y + 1 ) * ratioYDS ) = int( y * ratioYDS ) ) then
			  	splitY = 0
			  else
		     	splY = ( ( splY - iyStride ) + splConst ) mod splConst
		     	splitY = ( splY / splConst ) * 255
			  end if
			
			'' nearest neighbor sampling
			do while( ( ddaY < 0 ) andAlso ( yy < dstHeight ) )
				src = startX				
				xx = 0
				
			  if( splitY = 0 ) then '' Y split = 0
					splX = splConst
					
					for x as integer = 0 to img->width - 1
						ddaX -= FPScale
						  '' NLU sampling
						  if( int( ( x + 1 ) * ratioXDS ) = int( x * ratioXDS ) ) then
						  	splitX = 0
						  else
		     				splX = ( ( splX - ixStride ) + splConst ) mod splConst
		     				splitX = ( splX / splConst ) * 255
						  end if
						
						'' nearest neighbor upscale
						do while( ( ddaX < 0 ) andAlso ( xx < dstWidth ) )							
							if( splitX = 0 ) then
								'' X = 0, Y = 0
								*dst = *src
							else
								'' X <> 0, Y = 0
								*dst = avrg( *( src + 1 ), *src, splitX )
							end if
							
							dst += 1
							
							ddaX += incX
							xx += 1
						loop
						
						src += 1
					next			  
			  else '' Y split <> 0
					splX = splConst
					
					for x as integer = 0 to img->width - 1
						ddaX -= FPScale
						
					  '' NLU sampling
					  if( int( ( x + 1 ) * ratioXDS ) = int( x * ratioXDS ) ) then
					  	splitX = 0
					  else
		     			splX = ( ( splX - ixStride ) + splConst ) mod splConst
		     			splitX = ( splX / splConst ) * 255
					  end if
					  
						'' nearest neighbor upscaling
						do while( ( ddaX < 0 ) andAlso ( xx < dstWidth ) )							
							if( splitX = 0 ) then
								'' X = 0, Y <> 0
								*dst = avrg( *( src + srcPitch ), *src, splitY )
							else
								'' X <> 0, Y <> 0
			        	*dst = _
			        		avrg( _
			        		avrg( *( src + 1 ), *src, splitX ), _
			        		avrg( *( src + 1 + srcPitch ), *( src + srcPitch ), splitX ), _
			        		splitY )
							end if														
							
							dst += 1
							
							ddaX += incX
							xx += 1
						loop
						
						src += 1
					next			  			  
			  end if
			  				
				ddaY += incY
				yy += 1				
			loop
			
			src += srcPadding
		next
	'screenUnlock()	
end sub

'dim as integer screenWidth = 960, screenHeight = 500
dim as integer screenWidth = 1280, screenHeight = 800
screenRes( screenWidth, screenHeight, 32 )

/'	Loads an image using bload, so you have to set the width and height of the
		buffer manually, or peek them from the BMP file '/
dim as fb.image ptr img = imageCreate( 426, 320 )
'dim as fb.image ptr img = imageCreate( 256, 208 )
dim as fb.image ptr sv = imageCreate( screenWidth, screenHeight )

bload( "data/test2.bmp", img )

dim as double t, sum
dim as uinteger total

do
	screenLock()
		cls()
		t = timer()
		resizeImage( img )
		t = timer() - t

		locate 10, 1
		? "FPS: " & str( int( 1 / ( sum / total ) ) )
	screenUnlock()
	
	sum += t
	total += 1
	
	'windowTitle( "FPS: " & str( int( 1 / ( sum / total ) ) ) )
	
	sleep( 1 )
loop until( inkey() = chr( 27 ) )

'get( 0, 0 ) - ( screenWidth - 1, screenHeight - 1 ), sv
'bsave( "result_mine.bmp", sv )

imageDestroy( img )
imageDestroy( sv )
Compare it with yours and tell me what you think. The interpolation is still a bit off, no? I think it's because of not interpolating the coordinates and use an integer DDA instead. Compile it with -GCC -Wc -O3, please, don't even bother to run this on GAS.
counting_pine
Site Admin
Posts: 6323
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

Re: Does anyone know what algo XP -> full screen DOS?

Post by counting_pine »

Something definitely seems off.

For ease of use, I'm making the following substitution:

Code: Select all

'bload( "data/test2.bmp", img )
draw string img, (1, 1), "_=+\/[]{}()<>|""'~#"
(For the sake of ergonomics, it's also worth exiting on any keypress, rather than just the Esc key.)

You can see that many rows only appear once as blurred. That shouldn't be possible, assuming the image is being up-scaled there.
paul doe
Moderator
Posts: 1733
Joined: Jul 25, 2017 17:22
Location: Argentina

Re: Does anyone know what algo XP -> full screen DOS?

Post by paul doe »

counting_pine wrote:You can see that many rows only appear once as blurred. That shouldn't be possible, assuming the image is being up-scaled there.
Yeah, but I think that's because of the double interpolation, and also the blending function does give slightly different results. I'll decompose it and see if the results are a little closer then. Of course, I couldn't care less for this, but will finish it, just for the sake of completeness =D
counting_pine
Site Admin
Posts: 6323
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

Re: Does anyone know what algo XP -> full screen DOS?

Post by counting_pine »

It seems like there may still be a bug somewhere, because both nearest-neighbour and my algorithm, when upscaling, should guarantee that every pixel in the source image appears crisply at least once in the upscaled image.
counting_pine
Site Admin
Posts: 6323
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

Re: Does anyone know what algo XP -> full screen DOS?

Post by counting_pine »

My mistake on the above - each pixel appears crisply only if the destination dimensions are at least double that of the source.

I reworked my algorithm. It's a lot faster now, and should be capable of ~100fps:

Code: Select all

#include "crt.bi"
function merge(c1 as ulong, c2 as ulong, w as single) as ulong
    dim as integer r1, g1, b1, r2, g2, b2
    dim as integer m = int(w * 256)

    assert(m >= 0 and m < 256)

    r1 = c1 shr 16 and 255: r2 = c2 shr 16 and 255
    g1 = c1 shr  8 and 255: g2 = c2 shr  8 and 255
    b1 = c1        and 255: b2 = c2        and 255

    r1 += ((r2 - r1) * m) shr 8
    g1 += ((g2 - g1) * m) shr 8
    b1 += ((b2 - b1) * m) shr 8

    return rgb(r1, g1, b1)
end function

sub scalerow(dp as ulong ptr, dw as uinteger, sp as ulong ptr, sw as uinteger)
    dim as uinteger dxsw = 0
    dim as ulong c, c2

    c = *sp
    for dx as uinteger = 0 to dw-1

        dxsw += sw
        select case dxsw
        case is <= dw
            '' output current pixel
            *dp = c
            if dxsw = dw then
                dxsw = 0: sp += 1
                '' move to next pixel
                c = *sp
            end if
        case else 'is > dw
            '' merge with next pixel
            sp += 1: dxsw -= dw
            c2 = *sp

            *dp = merge(c, c2, (dxsw / sw))

            'dp += 1: dx += 1:
            c = c2
        end select
        dp += 1
    next dx
end sub

sub copyrow(dp as ulong ptr, sp as ulong ptr, w as uinteger)
    memcpy(dp, sp, w*4)
end sub

sub mergerow(dp as ulong ptr, sp as ulong ptr, wid as uinteger, w as single)
    dim as integer r1, g1, b1, r2, g2, b2
    dim as integer m = int(w * 256)

    assertwarn(m >= 0 and m < 256)

    for i as integer = 0 to wid-1
        r1 = dp[i] shr 16 and 255: r2 = sp[i] shr 16 and 255
        g1 = dp[i] shr  8 and 255: g2 = sp[i] shr  8 and 255
        b1 = dp[i]        and 255: b2 = sp[i]        and 255

        r1 += ((r2 - r1) * m) shr 8
        g1 += ((g2 - g1) * m) shr 8
        b1 += ((b2 - b1) * m) shr 8
        dp[i] = rgb(r1, g1, b1)
    next i
end sub

sub scaleimg(dp as any ptr, dw as uinteger, dh as uinteger, dpitch as uinteger, _
             sp as any ptr, sw as uinteger, sh as uinteger, spitch as uinteger)

    dim as uinteger dysh = 0

    for dy as integer = 0 to dh-1
        if dysh < sh then
            scalerow(dp, dw, sp, sw)
            if dysh > 0 then
                mergerow(dp - dpitch, dp, dw, dysh / sh)
            end if
        else
            copyrow(dp, dp - dpitch, dw)
        end if

        dysh += sh
        if dysh >= dh then
            dysh -= dh
            sp += spitch
        end if
        dp += dpitch
    next dy

end sub

screenres 1024, 768, 32
dim as any ptr img = imagecreate(320, 200)
for y as integer = 16 to 199
    for x as integer = 0 to 319
        pset img, (x, y), (x + y*1) mod 2 <> 0
    next x
next y
draw string img, (0, 0), "Hello world! |\/|[](){}<>_-=+"

dim as integer dw, dh, dpitch
dim as any ptr dp
screeninfo dw, dh, ,, dpitch

dim as integer sw, sh, spitch
dim as any ptr sp
imageinfo img, sw, sh, , spitch, sp

do
    dim as double t = timer
    screenlock
        dp = screenptr
        scaleimg(dp, dw, dh, dpitch, sp, sw, sh, spitch)
    screenunlock

    windowtitle "Time per frame: " & (timer - t)

    sleep 1
loop until len(inkey)

imagedestroy img
paul doe
Moderator
Posts: 1733
Joined: Jul 25, 2017 17:22
Location: Argentina

Re: Does anyone know what algo XP -> full screen DOS?

Post by paul doe »

counting_pine wrote:My mistake on the above - each pixel appears crisply only if the destination dimensions are at least double that of the source.

I reworked my algorithm. It's a lot faster now, and should be capable of ~100fps:
Nice! Actually ~200 FPS here (64-bit GCC). There's a typo in the code: 'end selisect' =D
Last edited by paul doe on Dec 30, 2017 20:42, edited 1 time in total.
Post Reply