Author Topic: Windows Console Library (Work In Progress)  (Read 6556 times)

0 Members and 1 Guest are viewing this topic.

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Windows Console Library (Work In Progress)
« on: July 27, 2019, 01:24:55 pm »
Save the following as "Test1.h" in your QB64 main folder:

Code: C++: [Select]
  1.  
  2. CONSOLE_CURSOR_INFO cl_curinfo;
  3. CONSOLE_SCREEN_BUFFER_INFO cl_bufinfo;
  4. SECURITY_ATTRIBUTES SecAttribs = {sizeof(SECURITY_ATTRIBUTES), 0, 1};
  5. HANDLE cl_conout = 0;
  6.  
  7. short CCsrlin(void);
  8. short CPos(void);
  9. int32 CInp (int32 toggle);
  10. void CLocate (int x, int y);
  11. void CColor (int fg, int bg);
  12. void CSize (int width, int height);
  13. void CFont(char* FontName, int FontSize);
  14. void CHideCursor();
  15. void CShowCursor();
  16.  
  17.  
  18. WORD CScreen(short l, short c, BOOL f){
  19.  COORD cp = {--c, --l};
  20.  DWORD t;
  21.  WORD a;
  22.  if (f){
  23.   ReadConsoleOutputAttribute(cl_conout, & a, 1, cp, & t) ;
  24.   return a;
  25.  } else {
  26.   ReadConsoleOutputCharacterA(cl_conout, (char *) & a, 1, cp, & t) ;
  27.   return a & 0xff;
  28.  }
  29. }
  30.  
  31.  
  32. short CCsrlin(void)
  33. {
  34.     cl_conout = CreateFileA("CONOUT$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, & SecAttribs, OPEN_EXISTING, 0, 0);
  35.     GetConsoleScreenBufferInfo(cl_conout, & cl_bufinfo);
  36.  return cl_bufinfo.dwCursorPosition.Y + 1;
  37. }
  38.  
  39. short CPos(void)
  40. {
  41.    cl_conout = CreateFileA("CONOUT$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, & SecAttribs, OPEN_EXISTING, 0, 0);
  42.    GetConsoleScreenBufferInfo(cl_conout, & cl_bufinfo);
  43.  return cl_bufinfo.dwCursorPosition.X + 1;
  44. }
  45.  
  46.  
  47.  
  48.      
  49. int32 CInp (int32 toggle)
  50.     {
  51.       HANDLE hStdin = GetStdHandle (STD_INPUT_HANDLE);
  52.       INPUT_RECORD irInputRecord;
  53.       DWORD dwEventsRead;
  54.       INT32 cChar;
  55.      
  56.       while(ReadConsoleInputA (hStdin, &irInputRecord, 1, &dwEventsRead)) /* Read key press */
  57.         if (irInputRecord.EventType == KEY_EVENT)
  58.         {
  59.           cChar = irInputRecord.Event.KeyEvent.wVirtualScanCode;
  60.           if (toggle) {
  61.               if (!irInputRecord.Event.KeyEvent.bKeyDown) cChar = -cChar;
  62.           }else{
  63.               if (!irInputRecord.Event.KeyEvent.bKeyDown) cChar = cChar +128;
  64.           }
  65.               return cChar;
  66.         }
  67.       return EOF;
  68.     }
  69.      
  70. void CLocate (int x, int y)
  71.     {
  72.         COORD pos = {x-1, y-1};
  73.         HANDLE output = GetStdHandle (STD_OUTPUT_HANDLE);
  74.         SetConsoleCursorPosition(output, pos);
  75.     }
  76.      
  77. void CColor (int fg, int bg)
  78.     {
  79.          HANDLE output = GetStdHandle(STD_OUTPUT_HANDLE);
  80.          int color = bg * 16 + fg;
  81.          SetConsoleTextAttribute(output, color);
  82.       }
  83.      
  84.      
  85. void CSize (int width, int height)
  86.     {
  87.         HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
  88.         COORD bufferSize = {width, height};
  89.         SMALL_RECT rect = {0,0, width-1, height-1};
  90.         SetConsoleScreenBufferSize(hConsole, bufferSize);
  91.         SetConsoleWindowInfo(hConsole, TRUE, &rect);
  92.     }
  93.      
  94. void CFont(char* FontName, int FontSize)
  95.     {
  96.         CONSOLE_FONT_INFOEX info = {0};
  97.         info.cbSize       = sizeof(info);
  98.         info.dwFontSize.Y = FontSize; // leave X as zero
  99.         info.FontWeight   = FW_NORMAL;
  100.         const size_t cSize = strlen(FontName)+1;
  101.         wchar_t* wc = new wchar_t[32];
  102.         mbstowcs (wc, FontName, cSize);
  103.         wcscpy(info.FaceName, wc);
  104.         SetCurrentConsoleFontEx(GetStdHandle(STD_OUTPUT_HANDLE), NULL, &info);
  105.     }
  106.      
  107. void CHideCursor()
  108.     {
  109.        HANDLE consoleHandle = GetStdHandle(STD_OUTPUT_HANDLE);
  110.        CONSOLE_CURSOR_INFO info;
  111.        info.dwSize = 100;
  112.        info.bVisible = FALSE;
  113.        SetConsoleCursorInfo(consoleHandle, &info);
  114.     }
  115.      
  116. void CShowCursor()
  117.     {
  118.        HANDLE consoleHandle = GetStdHandle(STD_OUTPUT_HANDLE);
  119.        CONSOLE_CURSOR_INFO info;
  120.        info.dwSize = 100;
  121.        info.bVisible = TRUE;
  122.        SetConsoleCursorInfo(consoleHandle, &info);
  123.     }    
  124.          
  125.  

Now, using DECLARE LIBRARY as shown below, you now have a lot more control over the console than QB64 normally provides:

Code: QB64: [Select]
  1.  
  2.     FUNCTION CInp (BYVAL Toggle AS LONG) 'Get the INP scan code for keypresses from the console
  3.     SUB CLocate (BYVAL x AS INTEGER, BYVAL y AS INTEGER) 'Move the Cursor position in the console
  4.     SUB CColor (BYVAL fg AS INTEGER, BYVAL bg AS INTEGER) 'Set the text color used in the console
  5.     SUB CSize (BYVAL w AS INTEGER, BYVAL h AS INTEGER) 'Set the size of the console
  6.     SUB CFont (FontNamr$, BYVAL FontSize AS INTEGER)
  7.     SUB CHideCursor
  8.     SUB CShowCursor
  9.  
  10.  
  11. TYPE Coord
  12.     x AS INTEGER
  13.     y AS INTEGER
  14.  
  15. DIM Hero AS Coord
  16.  
  17. CSize 80, 30
  18. CFont "Courier New", 20
  19. CColor 15, 4
  20. FOR y = 0 TO 29
  21.     CLocate 0, y: PRINT " ";: CLocate 79, y: PRINT " ";
  22. FOR x = 1 TO 78
  23.     CLocate x, 0: PRINT " ";: CLocate x, 29: PRINT " ";
  24.  
  25. Hero.x = INT(RND * 78) + 1: Hero.y = INT(RND * 28) + 1
  26. CColor 15, 0
  27. CHideCursor 'Hide the cursor as otherwise it'll look goofy.
  28. CLocate Hero.x, Hero.y: PRINT CHR$(1); 'Place hero at starting positon
  29. CColor 14, 4
  30. CLocate 29, 29: PRINT "Color: 14"; 'Display starting color
  31. bg = 14
  32.  
  33.     UserInput = CInp(1)
  34.  
  35.     SELECT CASE UserInput
  36.         CASE 1: SYSTEM 'Escape to quit
  37.         CASE 72 'up
  38.             IF Hero.y > 1 THEN
  39.                 GOSUB EraseRoutine
  40.                 Hero.y = Hero.y - 1
  41.             END IF
  42.         CASE 75 'left
  43.             IF Hero.x > 1 THEN
  44.                 GOSUB EraseRoutine
  45.                 Hero.x = Hero.x - 1
  46.             END IF
  47.         CASE 80 'down
  48.             IF Hero.y < 28 THEN
  49.                 GOSUB EraseRoutine
  50.                 Hero.y = Hero.y + 1
  51.             END IF
  52.         CASE 77 'right
  53.             IF Hero.x < 78 THEN
  54.                 GOSUB EraseRoutine
  55.                 Hero.x = Hero.x + 1
  56.             END IF
  57.         CASE 57 'space
  58.             eraser = NOT eraser
  59.         CASE 2 TO 17 '1-backspace, tab - e  (first row, second row of keys for quick color changes)
  60.             bg = UserInput - 2
  61.     END SELECT
  62.     CColor 15, 0
  63.     CLocate Hero.x, Hero.y
  64.     PRINT CHR$(1);
  65.     CColor 14, 4
  66.     CLocate 29, 29: PRINT "Color:"; bg;
  67.  
  68.  
  69.  
  70. EraseRoutine:
  71. CColor bg, 0
  72. CLocate Hero.x, Hero.y: PRINT CHR$(219); 'eraser the old hero
  73.  
  74.  



Do what does this library do for us so far?

*Allows single character return values from the console, via INP Scan Code style
*Allows us to change the color of text being sent to the console.
*Allows us to change the print position of text being sent to the console (ala LOCATE style).
*Allows us to resize the console to set it to whatever dimensions we want to suit our needs.
*Allows us to change the size of the font we want for the console (great for old fogies like me who strain their eyes staring at the screen sometimes.)
*Allows us to change the font which the console uses.
*Allows us to hide or show the cursor in the console.

Now, I'm not usually one to use the console too often, so I don't know what other capabilities and functionality might be needed for the console, which it doesn't already support.  I added these commands simply because I couldn't manage to get QB64 to do any of these things for me, when I tested them.  If you guys know of other features which the console needs, which I haven't considered, kindly let me know and I'll look into adding them into this library (if I can sort out how to get them to work with us; I don't promise success -- only that I'll give it my best try to sort things out).

It seems to me that what we have here already, is enough for someone to create a "Rogue-like" game and run it via the console, without having to create a OpenGL window for it. 

Test it out, tell me what you think, and let me know what might be wrong, missing, or needed to enhance the console-only experience.
« Last Edit: August 06, 2019, 08:59:49 am by SMcNeill »
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Windows Console Library (Work In Progress)
« Reply #1 on: July 27, 2019, 01:45:10 pm »
*Added font sizing capability to the console library.
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Windows Console Library (Work In Progress)
« Reply #2 on: July 27, 2019, 02:22:24 pm »
*sorted out adding the ability to change the font in the console.
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Windows Console Library (Work In Progress)
« Reply #3 on: July 27, 2019, 03:18:01 pm »
I don't use console but as I recall that is the one mode you can scroll.

So Steve, you have LOCATE working aligning with FONT size on the console? That would be something!

Is it possible to continue with mouse and graphics?

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Windows Console Library (Work In Progress)
« Reply #4 on: July 27, 2019, 03:28:33 pm »
I don't use console but as I recall that is the one mode you can scroll.

So Steve, you have LOCATE working aligning with FONT size on the console? That would be something!

Is it possible to continue with mouse and graphics?

You should be able to change font, and still have CLocate work properly.

Mouse support should be possible via ReadConsoleInput; just changing the Event_Type from KEY_EVENT to MOUSE_EVENT and then go from there.  I’ll play around with it later and see if I can get it working as intended for us.
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Windows Console Library (Work In Progress)
« Reply #5 on: July 27, 2019, 08:19:52 pm »
*added ability to hide or show the cursor in the console.
*changed out the old demo to a new little sort of Etch-A-Sketch style program.


For the new demo, use the 1- backspace and tab-E keys to change the draw colors, Arrow keys to move.
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline Ashish

  • Forum Resident
  • Posts: 630
  • Never Give Up!
    • View Profile
Re: Windows Console Library (Work In Progress)
« Reply #6 on: July 28, 2019, 01:40:45 am »
Thank You for this. It will be going to be useful for me.
if (Me.success) {Me.improve()} else {Me.tryAgain()}


My Projects - https://github.com/AshishKingdom?tab=repositories
OpenGL tutorials - https://ashishkingdom.github.io/OpenGL-Tutorials

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: Windows Console Library (Work In Progress)
« Reply #7 on: July 28, 2019, 03:38:37 am »
Nice work!

Just two questions. Why is there a fine black line when moving a character from right to left, but not when moving from left to right? And what specifically does the spacebar do? I had to switch the keyboard via Alt + Left Shift to English for proper operation.

Thanks for sharing. Output EXE size is 1,610,240 bytes, nice!

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Windows Console Library (Work In Progress)
« Reply #8 on: July 28, 2019, 05:52:10 am »
Nice work!

Just two questions. Why is there a fine black line when moving a character from right to left, but not when moving from left to right? And what specifically does the spacebar do? I had to switch the keyboard via Alt + Left Shift to English for proper operation.

Thanks for sharing. Output EXE size is 1,610,240 bytes, nice!

The spacebar was going to lift the “pen” and allow you to move without affecting the background, but I haven’t quite sorted out how to read the pixel information yet.  (Think using POINT to get pixel color.).  The info is there; I just need to sort out how to get it back to us.

As for a black line, I’m not certain.  I didn’t notice one, but I’ll check for it later and see if I can sort out what’s going on there.
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: Windows Console Library (Work In Progress)
« Reply #9 on: July 28, 2019, 07:05:34 am »
I found that if you draw a track from right to left, where the black line is, but then shrink and enlarge window by pulling on the edge of the window, the black line disappears and the window is rendered as it should. That means there will be a problem somewhere in the window rendering?

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Windows Console Library (Work In Progress)
« Reply #10 on: August 06, 2019, 08:27:53 am »
I've now started to work out how to get some of the stored .information back from our console to us.  For your usage, I present POS and CSRLIN for the console:

Code: QB64: [Select]
  1.     FUNCTION CCsrlin
  2.     FUNCTION CPos
  3.     FUNCTION CInp (BYVAL Toggle AS LONG) 'Get the INP scan code for keypresses from the console
  4.     SUB CLocate (BYVAL x AS INTEGER, BYVAL y AS INTEGER) 'Move the Cursor position in the console
  5.     SUB CColor (BYVAL fg AS INTEGER, BYVAL bg AS INTEGER) 'Set the text color used in the console
  6.     SUB CSize (BYVAL w AS INTEGER, BYVAL h AS INTEGER) 'Set the size of the console
  7.     SUB CFont (FontNamr$, BYVAL FontSize AS INTEGER)
  8.     SUB CHideCursor
  9.     SUB CShowCursor
  10.  
  11.  
  12. TYPE Coord
  13.     x AS INTEGER
  14.     y AS INTEGER
  15.  
  16. DIM Hero AS Coord
  17.  
  18. CSize 80, 30
  19. CFont "Courier New", 20
  20. CLocate 5, 10
  21. PRINT "Hello World";
  22. PRINT CPos, CCsrlin 'Current print position should be at 16, 10 (we started at 5, 10, then printed 11 letters with "Hello World", so we're now at 16,10
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Windows Console Library (Work In Progress)
« Reply #11 on: August 06, 2019, 09:02:18 am »
SCREEN information is now available for us, which gives us the color attribute and character at any given point on the console:

Code: QB64: [Select]
  1.     FUNCTION CScreen~& (BYVAL l AS _BYTE, BYVAL c AS _BYTE, BYVAL f AS LONG)
  2.     FUNCTION CCsrlin
  3.     FUNCTION CPos
  4.     FUNCTION CInp (BYVAL Toggle AS LONG) 'Get the INP scan code for keypresses from the console
  5.     SUB CLocate (BYVAL x AS INTEGER, BYVAL y AS INTEGER) 'Move the Cursor position in the console
  6.     SUB CColor (BYVAL fg AS INTEGER, BYVAL bg AS INTEGER) 'Set the text color used in the console
  7.     SUB CSize (BYVAL w AS INTEGER, BYVAL h AS INTEGER) 'Set the size of the console
  8.     SUB CFont (FontNamr$, BYVAL FontSize AS INTEGER)
  9.     SUB CHideCursor
  10.     SUB CShowCursor
  11.  
  12.  
  13. TYPE Coord
  14.     x AS INTEGER
  15.     y AS INTEGER
  16.  
  17. DIM Hero AS Coord
  18.  
  19. CSize 80, 30
  20. CFont "Courier New", 20
  21. CColor 15, 0
  22. PRINT "WHITE ON BLACK"
  23. CLocate 5, 10
  24. PRINT "Hello World";
  25. PRINT CPos, CCsrlin 'Current print position should be at 16, 10 (we started at 5, 10, then printed 11 letters with "Hello World", so we're now at 16,10
  26.  
  27. PRINT CScreen(1, 1, 0), CScreen(1, 1, 1) 'Character for position 1,1 is "W" or 87.  Color for position 1,1 is 15, as we set above.
  28.  

Our available functionality of commands with the console continues to grow and expand rather nicely!  ;D
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline doppler

  • Forum Regular
  • Posts: 241
    • View Profile
Re: Windows Console Library (Work In Progress)
« Reply #12 on: August 07, 2019, 08:39:13 am »
I am sure you are not done tweaking the console extended functions.  I can only imagine what else.
This must all be included in what would be called QB64 V1.4

Would love to see _CSize, _CFont, _CColor, _CLocate and all the others merged in.

Offline doppler

  • Forum Regular
  • Posts: 241
    • View Profile
Re: Windows Console Library (Work In Progress)
« Reply #13 on: August 07, 2019, 09:26:42 pm »
I can only imagine what else.

Well I can imagine after all.  If it's even possible.  Four functions for the console window.

Scroll up one page
Scroll Down one page
Scroll up one line
Scroll Down one line.

These would be nice too.  The cursor location would remain in the same spot on the console window.  Only the content would go up/down.  Much like using the elevators on the scroll bar.