I wanna try to make a class that will be able to print wide character to console with specific RGB color. I know that console has only 16 of them but first take a look.
Every color in console palette can be changed by setting the right buffer, so I wrote something like that:
//ConsolePX
#include <fcntl.h>
#include <io.h>
#include <Windows.h>
#include <iostream>
class ConsolePX
{
public:
wchar_t source;
COLORREF foreground, background;
/* Set at the start ctor */
ConsolePX(wchar_t _what, COLORREF foregroundColor, COLORREF backgroundColor)
{
source = _what;
foreground = foregroundColor;
background = backgroundColor;
}
/* Draws wchar_t with colors to console */
void Draw() {
HANDLE outH = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_SCREEN_BUFFER_INFOEX curr, newBuff;
curr.cbSize = sizeof(CONSOLE_SCREEN_BUFFER_INFOEX);
GetConsoleScreenBufferInfoEx(outH, &curr);
curr.srWindow.Bottom++;
newBuff = curr;
newBuff.ColorTable[0] = background;
newBuff.ColorTable[1] = foreground;
SetConsoleScreenBufferInfoEx(outH, &newBuff);
SetConsoleTextAttribute(outH, 1);
_setmode(_fileno(stdout), _O_U16TEXT); //Sets console mode to 16-bit unicode
std::wcout << source << std::endl;
_setmode(_fileno(stdout), _O_TEXT);
//Restores to defaults
SetConsoleTextAttribute(outH, 7);
SetConsoleScreenBufferInfoEx(outH, &curr);
}
};
//Driver code
#include "ConsolePX.h"
int main()
{
ConsolePX(L'█', RGB(29, 219, 79), RGB(0, 0, 0)).Draw();
return 0;
}
And that worked but the problem is in the last line in ConsolePX(exactly SetConsoleScreenBufferInfoEx(outH, &curr)). After printing wchar_t I restored palette to defaults. Why is that a problem? I noticed that every char in a console isn't pinned to color but to the color palette index, so after restoring to defaults palette, I restored wchar_t color too. After deleting that line, I'll interfere with the rest of the code. Is there any way to block x, y character in the console to avoid color change?
Of important things, I'm using Visual Studio and, as you can guess, I'm using windows.
No.
You said it yourself: there are 16 colours available to you.
When you thought you'd bypassed that restriction, actually all you were doing was changing what those colours "mean", i.e. what RGB values they map to for that console.
The current palette applies to the whole content of the console. If it didn't, we wouldn't be limited to 16 colours.
So, while your attempt is inventive, I'm afraid it fundamentally cannot work.
If you want control over real colours like this, make a GUI application.
Related
I have a work-related C/C++ SDL 2.0 project - originally developed and compiled on Win7 computer for x86 platform (With MS Visual Studio) that was working fine for the whole time. Since the program was meant to run also at newer Win10 x64 devices, I moved the entire solution to a newer Win10 x64 computer, changed all SDL2 libraries, header files etc. for the x64 version and rebuilt the solution for x64 architecture.
The program is basically an advanced diagnostic screen with dials, icons and text information, so it uses variety of colors, fonts, geometry etc.
After the recompilation for x64 platform, I noticed that the colors of some elements are absolutely off. For example - a rectangle that should be grey (used SDL_SetRenderDrawColor one step before drawing the rect.) is suddenly green, despite its given grey RGB numbers as input arguments. Even the function SDL_GetRenderDrawColor called before and/or after drawing of the rectangle returns values 195, 195, 195, but the rectangle is shown green.
Rectangle drawing function:
void DrawRectangle(SDL_Color color, int pozX, int pozY, int width, int height)
{
SDL_Rect Proportions = { pozX, pozY, width, height };
SDL_SetRenderDrawColor(gRenderer, color.r, color.g, color.b, 0xFF);
SDL_RenderFillRect(gRenderer, &Proportions);
}
Rectangle drawing call:
DrawRectangle(grey, pocpozX, 182, width, height);
Later I have noticed that this rectangle inherits its color from a text rendered a few steps earlier. If I change the color of this text, it for some strange reason applies also for the rectangle.
Text drawing function:
void DrawText(std::wstring text, TTF_Font *font, int pozX, int pozY, SDL_Color color)
{
typedef std::basic_string<Uint16, std::char_traits<Uint16>, std::allocator<Uint16> > u16string;
std::wstring text_sf_str = text;
u16string utext_sf_str(text_sf_str.begin(), text_sf_str.end());
SDL_Surface* text_sf = TTF_RenderUNICODE_Blended(font, utext_sf_str.c_str(), color);
SDL_Texture* text_Tx = SDL_CreateTextureFromSurface(gRenderer, text_sf);
int text_TxW;
int text_TxH;
SDL_QueryTexture(text_Tx, NULL, NULL, &text_TxW, &text_TxH);
SDL_Rect textrect = { pozX, pozY, text_TxW, text_TxH };
SDL_RenderCopy(gRenderer, text_Tx, NULL, &textrect);
SDL_FreeSurface(text_sf);
SDL_DestroyTexture(text_Tx);
}
Notice all these conversions needed to display a wstring text with some uncommonly used UNICODE characters. I don't quite understand why SDL needs to be passed each character as Uint16 number, this could have been done better. I also don't understand the need of using SDL_QueryTexture just in order to display the text proportions right. I would expect the user to want to display the text not anyhow stretched by default. This all seems to me unnecessarily complicated.
Funny thing is, that if I remove SDL_DestroyTexture tag, there is of course a huge memory leak, but the problem disappears.
Text drawing call - in a for loop, this draws numeric labels onto speedometer axis:
if (i % 20 == 0)
{
if (i <= 160)
{
DrawText(str2, font, posX, posY, grey);
}
else
{
DrawText(str2, font, posX, posY, green);
}
}
... And this very "green" as the last argument of the call is what causes the rectangle to be green also - despite the fact that more elements are drawn between this text and rectangle so SDL_SetRenderDrawColor is called multiple times.
I have also noticed that some shown numbers are for a little while glitching some senseless values every n-th second, so I guess this is a memory-related problem. Of course there are more color problems, this was just for an example. Due to company policy, I cannot be more specific or post the full code here.
If I switch back to x86 configuration (with the right libraries of course), the problem now remains the same.
I'm using the UI Automation C++ library to get text data from another GUI application.
If the GUI application is developed using a framework that support UI Automation (WinForm, WPF, ...), it is very easy to get the text.
This is an example using the Inspect tool of UI Automation SDK:
Here, test with CCleaner Free application, it can get the text "Microsoft Edge"
We can also using Win32 API to send some message (Send Message) to get text, example: WM_GETTEXT, LVM_GETITEMTEXT, ...
But, I can't get the text from following element:
The whole header area is just an element only, and I can't get the text inside it.
First, I think it is just an image, but it is not. This is the result of using Ranorex Spy:
The plugin that Ranorex using to get text is GDI RawText Plug-In:
For some older technologies like VB6.0, Delphi or MFC based
applications, Ranorex has only limited support in addressing UI
elements in a robust way. With the GDI RawText Plug-In Ranorex
increases object recognition for controls which use the Windows GDI
drawing mechanism to display text on screen.
So, is there any tutorial about getting text from Windows GDI drawing in another application? Currently, I can't found any resource about it
PS: First, I think it use some OCR library to recognize text from image, but it get the text very fast, not look like using OCR library.
Ranorex is a commercial tool, so I think they will not let me know what library that they implement the plugin if I ask them
Update 1:
I capture the header bar of CCleaner application to Paint, and use Ranorex Spy to get text from the image (if it use some OCR library):
There is no RawText inside the selected element, so it does not use OCR to get the text
Update 2:
I write some simple MFC application to test:
void CMFCApplication1Dlg::OnPaint()
{
CPaintDC dc(this);
CRect rcText(20, 20, 300, 300);
wchar_t text[36];
wsprintf(text, L"Hello world");
dc.SetBkColor(RGB(255, 255, 255));
dc.DrawText(text, &rcText, DT_LEFT);
CDialogEx::OnPaint();
}
Using Spy++:
Using Inspect:
Using Ranorex Spy:
Update 3
Try set background color to black as well:
void CMFCApplication1Dlg::OnPaint()
{
CPaintDC dc(this);
CRect rcText(20, 20, 300, 300);
wchar_t text[36];
wsprintf(text, L"Hello world");
dc.SetBkColor(RGB(0, 0, 0));
dc.DrawText(text, &rcText, DT_LEFT);
CDialogEx::OnPaint();
}
So, no OCR engine can be used here. But this is the result of using Ranorex Spy:
Here's how you can quickly figure out if Ranorex uses OCR. Take a screenshot of CCleanerFree and paste it to mspaint and then run Ranorex on mspaint window to see if it can read text.
Here's how to detect if Ranorex uses winapi hooks for DrawText to see what text some app is drawing. Create a simple windows app and DrawText manually (preferably draw black text on black background to eliminate OCR possibility). If Ranorex reads it then they use winapi hooks to read your text.
Here's how read text with OCR.
OCR is pretty fast, it doesn't take seconds to process simple screen text. You could take screenshot of that window and process specific area of interest for you. I used ocrad for similar task and it worked out great.
Here's sample code you could try:
#include <stdint.h>
#include <string>
#include "ocradlib.h"
std::string image_to_text(uint8_t *data, int width, int height)
{
OCRAD_Pixmap pixmap = { 0 };
pixmap.data = data;
pixmap.width = width;
pixmap.height = height;
pixmap.mode = OCRAD_greymap; // OCRAD_greymap --> 1 byte per pixel; 256 level greymap
std::string ret;
OCRAD_Descriptor * const ocrdes = OCRAD_open();
if (!ocrdes || OCRAD_get_errno(ocrdes) != OCRAD_ok)
{
OCRAD_close(ocrdes);
fprintf(stderr, "not enough memory.\n");
return ret;
}
if (OCRAD_set_image(ocrdes, &pixmap, false) < 0)
{
const OCRAD_Errno ocr_errno = OCRAD_get_errno(ocrdes);
OCRAD_close(ocrdes);
return ret;
}
if (OCRAD_set_threshold(ocrdes, -1) < 0 || // auto threshold
OCRAD_recognize(ocrdes, false) < 0) // no layout
{
const OCRAD_Errno ocr_errno = OCRAD_get_errno(ocrdes);
OCRAD_close(ocrdes);
return ret;
}
const int blocks = OCRAD_result_blocks(ocrdes);
for (int b = 0; b < blocks; ++b)
{
const int lines = OCRAD_result_lines(ocrdes, b);
for (int l = 0; l < lines; ++l)
{
const char * s = OCRAD_result_line(ocrdes, b, l);
if (s && s[0])
ret += s;
}
if (b + 1 < blocks)
ret += '\n';
}
OCRAD_close(ocrdes);
return ret;
}
note that this code uses grayscale pixmap, e.g. 1 byte per pixel rectangle. You can try to change the code to use other image types:
/* OCRAD_Pixmap.data is a pointer to image data formed by "height" rows
of "width" pixels each.
The format for each pixel depends on mode like this:
OCRAD_bitmap --> 1 byte per pixel; 0 = white, 1 = black
OCRAD_greymap --> 1 byte per pixel; 256 level greymap (0 = black)
OCRAD_colormap --> 3 bytes per pixel; 16777216 colors RGB (0,0,0 = black) */
enum OCRAD_Pixmap_Mode { OCRAD_bitmap, OCRAD_greymap, OCRAD_colormap };
There are also other libraries that may provide better quality for more complex images, but for simple text like that ocrad was perfect for me.
To read text using WinAPI hooks
Read some tutorials to understand how that works. For example Hooks Overview on MSDN.
Here's a tutorial that shows how that can be done using EasyHook: EasyHook - Installing a remote hook using EasyHook with C++. Note that there are multiple functions that draw text in WinAPI, perhaps you'll need to hook one or all of them depending on your needs: DrawText, TextOut, ExtTextOut, ExtTextOutWarp (and others).
I am writing a program in C. I want to change the text color and background color in the console. My sample program is -
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <dos.h>
#include <dir.h>
int main(int argc,char *argv[])
{
textcolor(25);
printf("\n \n \t This is dummy program for text color ");
getch();
return 0;
}
When I compile this program code::blocks gives me an error - textcolor not defined. Why is this so? I work in a GNU GCC compiler and Windows Vista. If it is not going to work what is the duplicate of textcolor. Like that I want to change the background color of the console. The compiler gives me the same error just the name of the function is different. How to change the color of the console and text. Please help.
I am okay even if the answer is in C++.
Functions like textcolor worked in old compilers like turbo C and Dev C.
In today's compilers these functions would not work. I am going to give two function SetColor and ChangeConsoleToColors. You copy paste these functions code in your program and do the following steps.The code I am giving will not work in some compilers.
The code of SetColor is -
void SetColor(int ForgC)
{
WORD wColor;
HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_SCREEN_BUFFER_INFO csbi;
//We use csbi for the wAttributes word.
if(GetConsoleScreenBufferInfo(hStdOut, &csbi))
{
//Mask out all but the background attribute, and add in the forgournd color
wColor = (csbi.wAttributes & 0xF0) + (ForgC & 0x0F);
SetConsoleTextAttribute(hStdOut, wColor);
}
return;
}
To use this function you need to call it from your program. For example I am taking your sample program -
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <dos.h>
#include <dir.h>
int main(void)
{
SetColor(4);
printf("\n \n \t This text is written in Red Color \n ");
getch();
return 0;
}
void SetColor(int ForgC)
{
WORD wColor;
HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_SCREEN_BUFFER_INFO csbi;
//We use csbi for the wAttributes word.
if(GetConsoleScreenBufferInfo(hStdOut, &csbi))
{
//Mask out all but the background attribute, and add in the forgournd color
wColor = (csbi.wAttributes & 0xF0) + (ForgC & 0x0F);
SetConsoleTextAttribute(hStdOut, wColor);
}
return;
}
When you run the program you will get the text color in RED. Now I am going to give you the code of each color -
Name | Value
|
Black | 0
Blue | 1
Green | 2
Cyan | 3
Red | 4
Magenta | 5
Brown | 6
Light Gray | 7
Dark Gray | 8
Light Blue | 9
Light Green | 10
Light Cyan | 11
Light Red | 12
Light Magenta| 13
Yellow | 14
White | 15
Now I am going to give the code of ChangeConsoleToColors. The code is -
void ClearConsoleToColors(int ForgC, int BackC)
{
WORD wColor = ((BackC & 0x0F) << 4) + (ForgC & 0x0F);
//Get the handle to the current output buffer...
HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
//This is used to reset the carat/cursor to the top left.
COORD coord = {0, 0};
//A return value... indicating how many chars were written
// not used but we need to capture this since it will be
// written anyway (passing NULL causes an access violation).
DWORD count;
//This is a structure containing all of the console info
// it is used here to find the size of the console.
CONSOLE_SCREEN_BUFFER_INFO csbi;
//Here we will set the current color
SetConsoleTextAttribute(hStdOut, wColor);
if(GetConsoleScreenBufferInfo(hStdOut, &csbi))
{
//This fills the buffer with a given character (in this case 32=space).
FillConsoleOutputCharacter(hStdOut, (TCHAR) 32, csbi.dwSize.X * csbi.dwSize.Y, coord, &count);
FillConsoleOutputAttribute(hStdOut, csbi.wAttributes, csbi.dwSize.X * csbi.dwSize.Y, coord, &count );
//This will set our cursor position for the next print statement.
SetConsoleCursorPosition(hStdOut, coord);
}
return;
}
In this function you pass two numbers. If you want normal colors just put the first number as zero and the second number as the color. My example is -
#include <windows.h> //header file for windows
#include <stdio.h>
void ClearConsoleToColors(int ForgC, int BackC);
int main()
{
ClearConsoleToColors(0,15);
Sleep(1000);
return 0;
}
void ClearConsoleToColors(int ForgC, int BackC)
{
WORD wColor = ((BackC & 0x0F) << 4) + (ForgC & 0x0F);
//Get the handle to the current output buffer...
HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
//This is used to reset the carat/cursor to the top left.
COORD coord = {0, 0};
//A return value... indicating how many chars were written
// not used but we need to capture this since it will be
// written anyway (passing NULL causes an access violation).
DWORD count;
//This is a structure containing all of the console info
// it is used here to find the size of the console.
CONSOLE_SCREEN_BUFFER_INFO csbi;
//Here we will set the current color
SetConsoleTextAttribute(hStdOut, wColor);
if(GetConsoleScreenBufferInfo(hStdOut, &csbi))
{
//This fills the buffer with a given character (in this case 32=space).
FillConsoleOutputCharacter(hStdOut, (TCHAR) 32, csbi.dwSize.X * csbi.dwSize.Y, coord, &count);
FillConsoleOutputAttribute(hStdOut, csbi.wAttributes, csbi.dwSize.X * csbi.dwSize.Y, coord, &count );
//This will set our cursor position for the next print statement.
SetConsoleCursorPosition(hStdOut, coord);
}
return;
}
In this case I have put the first number as zero and the second number as 15 so the console color will be white as the code for white is 15. This is working for me in code::blocks. Hope it works for you too.
You can also use rlutil:
cross platform,
header only (rlutil.h),
works for C and C++,
implements setColor(), cls(), getch(), gotoxy(), etc.
License: WTFPL
Your code would become something like this:
#include <stdio.h>
#include "rlutil.h"
int main(int argc, char* argv[])
{
setColor(BLUE);
printf("\n \n \t This is dummy program for text color ");
getch();
return 0;
}
Have a look at example.c and test.cpp for C and C++ examples.
I Know, I am very late but, May be my answer can help someone.
Basically it's very Simple.
Here is my Code.
#include<iostream>
#include<windows.h>
using namespace std;
int main()
{
HANDLE colors=GetStdHandle(STD_OUTPUT_HANDLE);
string text;
int k;
cout<<" Enter your Text : ";
getline(cin,text);
for(int i=0;i<text.length();i++)
{
k>9 ? k=0 : k++;
if(k==0)
{
SetConsoleTextAttribute(colors,1);
}else
{
SetConsoleTextAttribute(colors,k);
}
cout<<text.at(i);
}
}
OUTPUT
This Image will show you how it works
If you want the full tutorial please see my video here: How to change Text color in C++
This is a function online, I created a header file with it, and I use Setcolor(); instead, I hope this helped! You can change the color by choosing any color in the range of 0-256. :) Sadly, I believe CodeBlocks has a later build of the window.h library...
#include <windows.h> //This is the header file for windows.
#include <stdio.h> //C standard library header file
void SetColor(int ForgC);
int main()
{
printf("Test color"); //Here the text color is white
SetColor(30); //Function call to change the text color
printf("Test color"); //Now the text color is green
return 0;
}
void SetColor(int ForgC)
{
WORD wColor;
//This handle is needed to get the current background attribute
HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_SCREEN_BUFFER_INFO csbi;
//csbi is used for wAttributes word
if(GetConsoleScreenBufferInfo(hStdOut, &csbi))
{
//To mask out all but the background attribute, and to add the color
wColor = (csbi.wAttributes & 0xF0) + (ForgC & 0x0F);
SetConsoleTextAttribute(hStdOut, wColor);
}
return;
}
textcolor function is no longer supported in the latest compilers.
This the simplest way to change text color in Code Blocks.
You can use system function.
To change Text Color :
#include<stdio.h>
#include<stdlib.h> //as system function is in the standard library
int main()
{
system("color 1"); //here 1 represents the text color
printf("This is dummy program for text color");
return 0;
}
If you want to change both the text color & console color you just need to add another color code in system function
To change Text Color & Console Color :
system("color 41"); //here 4 represents the console color and 1 represents the text color
N.B: Don't use spaces between color code like these
system("color 4 1");
Though if you do it Code Block will show all the color codes. You can use this tricks to know all supported color codes.
You should define the function textcolor before. Because textcolor is not a standard function in C.
void textcolor(unsigned short color) {
HANDLE hcon = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hcon,color);
}
An Easy Approach...
system("Color F0");
Letter Represents Background Color while the number represents the text color.
0 = Black
1 = Blue
2 = Green
3 = Aqua
4 = Red
5 = Purple
6 = Yellow
7 = White
8 = Gray
9 = Light Blue
A = Light Green
B = Light Aqua
C = Light Red
D = Light Purple
E = Light Yellow
F = Bright White
system("COLOR 0A");'
where 0A is a combination of background and font color
0
I have been attempting to get a simple SDL2 program up to display an image and then exit. I have this code:
/* compile with `gcc -lSDL2 -o main main.c` */
#include <SDL2/SDL.h>
#include <SDL2/SDL_video.h>
#include <SDL2/SDL_render.h>
#include <SDL2/SDL_surface.h>
#include <SDL2/SDL_timer.h>
int main(void){
SDL_Init(SDL_INIT_VIDEO);
SDL_Window * w = SDL_CreateWindow("Hi", 0, 0, 640, 480, 0);
SDL_Renderer * r = SDL_CreateRenderer(w, -1, 0);
SDL_Surface * s = SDL_LoadBMP("../test.bmp");
SDL_Texture * t = SDL_CreateTextureFromSurface(r, s);
SDL_FreeSurface(s);
SDL_RenderClear(r);
SDL_RenderCopy(r, t, 0, 0);
SDL_RenderPresent(r);
SDL_Delay(2000);
SDL_DestroyTexture(t);
SDL_DestroyRenderer(r);
SDL_DestroyWindow(w);
SDL_Quit();
}
I am aware that I have omitted the normal checks that each function succeeds - they all do succeed, they were removed for ease of reading. I am also aware I have used 0 rather than null pointers or the correct enum values, this also is not the cause of the issue (as the same issue occurs when I correctly structure the program, this was a quick test case drawn up to test the simplest case)
The intention is that a window appear and shows the image (which is definitely at that directory), wait for a couple of seconds and exit. The result, however, is that the window appears correctly but the window is filled with black.
An extra note SDL_ShowSimpleMessageBox() appears to work correctly. I don't know how this relates to the rest of the framework though.
I'll just clear this, you wanted to make a texture, do it directly to ease control, plus this gives you better control over the image, try using this code, fully tested, and working, all you wanted was for the window to show the image and close within 2 seconds right?. If the image doesn't load then it's your image's location.
/* compile with `gcc -lSDL2 -o main main.c` */
#include <SDL.h>
#include <SDL_image.h>
#include <iostream> //I included it since I used cout
int main(int argc, char* argv[]){
bool off = false;
int time;
SDL_Init(SDL_INIT_VIDEO);
SDL_Window * w = SDL_CreateWindow("Hi", 0, 0, 640, 480, SDL_WINDOW_SHOWN);
SDL_Renderer * r = SDL_CreateRenderer(w, -1, SDL_RENDERER_ACCELERATED);
SDL_Texture * s = NULL;
s = IMG_LoadTexture(r, "../test.bmp"); // LOADS A TEXTURE DIRECTLY FROM THE IMAGE
if (s == NULL)
{
cout << "FAILED TO FIND THE IMAGE" << endl; //we did this to check if IMG_LoadTexture found the image, if it showed this message in the cmd window (the black system-like one) then it means that the image can't be found
}
SDL_Rect s_rect; // CREATES THE IMAGE'S SPECS
s_rect.x = 100; // just like the window, the x and y values determine it's displacement from the origin which is the top left of your window
s_rect.y = 100;
s_rect.w = 640; //width of the texture
s_rect.h = 480; // height of the texture
time = SDL_GetTicks(); //Gets the current time
while (time + 2000 < SDL_GetTicks()) //adds 2 seconds to the past time you got and waits for the present time to surpass that
{
SDL_RenderClear(r);
SDL_RenderCopy(r, s, NULL, &s_rect); // THE NULL IS THE AREA YOU COULD USE TO CROP THE IMAGE
SDL_RenderPresent(r);
}
SDL_DestroyTexture(s);
SDL_DestroyRenderer(r);
SDL_DestroyWindow(w);
return 0; //returns 0, closes the program.
}
if you wanted to see a close button on the window and want it to take effect then create an event then add it to the while area to check if it's equal to SDL_Quit();, I didn't include it since you wanted it to immediately close within 2 seconds, thus, rendering the close button useless.
HAPPY CODING :D
When using SDL_RENDERER_SOFTWARE for the renderer flags this worked. Also it worked on a different machine. Guess there must be something screwed up with my configuration, although I'm not sure what it is because I'm still getting no errors shown. Ah well, mark as solved.
I believe this to be (not 100% sure, but fairly sure), due to this line of code:
SDL_Renderer * r = SDL_CreateRenderer(w, -1, 0);
According to the SDL wiki article SDL_CreateRenderer, the parameters required for the arguments that you are passing in are as follows:
SDL_Window* window
int index
Uint32 flags
You are passing in the pointer to the window correctly, as well as the index correctly, but the lack of a flag signifies to SDL that SDL should use the default renderer.
Most systems have a default setting for applications for which renderer should be used, and this can be modified on a application by application basis. If no default setting is provided for a specific application, the render look up immediately checks the default render settings list. The SDL wiki briefly refers to this list by the following line at the bottom of the remarks section:
"Note that providing no flags gives priority to available SDL_RENDERER_ACCELERATED renderers."
What's not explained here in the wiki is that the "renderers" the wiki is referring to comes from the default renderer list.
This leads me to believe that you have either changed a setting somewhere in the course of history of your computer, or elsewhere in you visual studio settings that is resulting in no list to be found. Therefore you must explicitly inform SDL which renderer to use because of your machine settings. Otherwise using an argument of 0 should work just fine. In the end this doesn't hurt as it's better to be explicit in your code rather than implicit if at all possible.
(That said, all of my deductions are based off of the fact that I am assuming that everything you said that works, works. If this is not true, then the issue could be because of a vast variety of reasons due to the lack of error checking.)
I Have built a C++ Allegro Map Editor. One of the requests was to have a log so I've put it in the console window for every move that is made... Problem now is that the console window is under the main window (Used GFX_AUTODETECT_WINDOWED), But whenever I try to move that window, it simply crashes the program.. I need to be able to move it and to move the console window to and come back to the map editor. Anybody has any ideas???
Here's the main of my code.
#include <allegro.h>
#include <string>
#include <sstream>
#include "Layout.h"
#include "System.h"
#include "Map.h"
#include <iostream>
#include <fstream>
using namespace std;
// Allegro Functions to stabilize speed
volatile long speed_counter = 0;
void increment_speed_counter() // A function to increment the speed counter
{speed_counter++; }
END_OF_FUNCTION(increment_speed_counter);
int main()
{
System system; // Initialising Allegro
system.Setup();
Map map1; // Creating default map
map1.createMap();
BITMAP *buffer = create_bitmap(24,45); // Double buffering
LOCK_VARIABLE(speed_counter); //Used to set the timer - which regulates the game's
LOCK_FUNCTION(increment_speed_counter);//speed.
install_int_ex(increment_speed_counter, BPS_TO_TIMER(8));//Set our BP
/*game looop */
while( !key[KEY_ESC] )
{
clear_bitmap(buffer); // Clear the contents of the buffer bitmap
while(speed_counter > 0)
{
if(mouse_b &1 ){ // On mouse click
map1.catchMouseEvent(mouse_x, mouse_y);
while(mouse_b & 1){}
}
speed_counter --;
}
rectfill(buffer,0,0,25,45,makecol(135,206,250));
textprintf_ex(buffer, map1.getLayout().getFont(), 0, 0, makecol(255, 255, 255), -1,"%d", map1.getRowVal());
textprintf_ex(buffer, map1.getLayout().getFont(), 0, 20, makecol(255, 255, 255), -1,"%d", map1.getColVal());
blit(buffer, screen, 0, 0, 970, 50, 100, 50);
}
/*Free memory after */
destroy_bitmap( buffer );
return 0;
allegro_exit();
}
END_OF_MAIN();
Also, it does happen that it randomly crashes by itself without moving the window. There is not a specific reason, it just crashes at random times.
Any ideas someone?
Without seeing all of the code, it's impossible to know why or where it's crashing. If you use a debugger it should be obvious what's happening. You should be responding to return codes. e.g., When you load or create a bitmap, make sure it's not NULL.
I'm not really sure what you are trying to do with such a smaller double buffer. Typically you create a single buffer the same size as the window. Note that Allegro 4 will only work properly if the screen width is a multiple of four. Also, you should call set_color_depth(desktop_color_depth()) (before setting the graphics mode) for maximum compatibility.