void CtrlDisAsmView::onPaint(WPARAM wParam, LPARAM lParam) { if (!debugger->isAlive()) return; PAINTSTRUCT ps; HDC actualHdc = BeginPaint(wnd, &ps); HDC hdc = CreateCompatibleDC(actualHdc); HBITMAP hBM = CreateCompatibleBitmap(actualHdc, rect.right-rect.left, rect.bottom-rect.top); SelectObject(hdc, hBM); SetBkMode(hdc, TRANSPARENT); HPEN nullPen=CreatePen(0,0,0xffffff); HBRUSH nullBrush=CreateSolidBrush(0xffffff); HBRUSH currentBrush=CreateSolidBrush(0xFFEfE8); HPEN oldPen=(HPEN)SelectObject(hdc,nullPen); HBRUSH oldBrush=(HBRUSH)SelectObject(hdc,nullBrush); HFONT oldFont = (HFONT)SelectObject(hdc,(HGDIOBJ)font); HICON breakPoint = (HICON)LoadIcon(GetModuleHandle(0),(LPCWSTR)IDI_STOP); HICON breakPointDisable = (HICON)LoadIcon(GetModuleHandle(0),(LPCWSTR)IDI_STOPDISABLE); unsigned int address = windowStart; std::map<u32,int> addressPositions; DisassemblyLineInfo line; for (int i = 0; i < visibleRows; i++) { manager.getLine(address,displaySymbols,line); int rowY1 = rowHeight*i; int rowY2 = rowHeight*(i+1); addressPositions[address] = rowY1; // draw background COLORREF backgroundColor = whiteBackground ? 0xFFFFFF : debugger->getColor(address); COLORREF textColor = 0x000000; if (isInInterval(address,line.totalSize,debugger->getPC())) { backgroundColor = scaleColor(backgroundColor,1.05f); } if (address >= selectRangeStart && address < selectRangeEnd && searching == false) { if (hasFocus) { backgroundColor = address == curAddress ? 0xFF8822 : 0xFF9933; textColor = 0xFFFFFF; } else { backgroundColor = 0xC0C0C0; } } HBRUSH backgroundBrush = CreateSolidBrush(backgroundColor); HPEN backgroundPen = CreatePen(0,0,backgroundColor); SelectObject(hdc,backgroundBrush); SelectObject(hdc,backgroundPen); Rectangle(hdc,0,rowY1,rect.right,rowY1+rowHeight); SelectObject(hdc,currentBrush); SelectObject(hdc,nullPen); DeleteObject(backgroundBrush); DeleteObject(backgroundPen); // display address/symbol bool enabled; if (CBreakPoints::IsAddressBreakPoint(address,&enabled)) { if (enabled) textColor = 0x0000FF; int yOffset = max(-1,(rowHeight-14+1)/2); if (!enabled) yOffset++; DrawIconEx(hdc,2,rowY1+1+yOffset,enabled ? breakPoint : breakPointDisable,32,32,0,0,DI_NORMAL); } SetTextColor(hdc,textColor); char addressText[64]; getDisasmAddressText(address,addressText,true,line.type == DISTYPE_OPCODE); TextOutA(hdc,pixelPositions.addressStart,rowY1+2,addressText,(int)strlen(addressText)); if (isInInterval(address,line.totalSize,debugger->getPC())) { TextOut(hdc,pixelPositions.opcodeStart-8,rowY1,L"■",1); } // display whether the condition of a branch is met if (line.info.isConditional && address == debugger->getPC()) { line.params += line.info.conditionMet ? " ; true" : " ; false"; } if (line.params.size() != 0) TextOutA(hdc,pixelPositions.argumentsStart,rowY1+2,line.params.c_str(),(int)line.params.size()); SelectObject(hdc,boldfont); TextOutA(hdc,pixelPositions.opcodeStart,rowY1+2,line.name.c_str(),(int)line.name.size()); SelectObject(hdc,font); address += line.totalSize; } std::vector<BranchLine> branchLines = manager.getBranchLines(windowStart,address-windowStart); for (size_t i = 0; i < branchLines.size(); i++) { drawBranchLine(hdc,addressPositions,branchLines[i]); } SelectObject(hdc,oldFont); SelectObject(hdc,oldPen); SelectObject(hdc,oldBrush); // copy bitmap to the actual hdc BitBlt(actualHdc, 0, 0, rect.right, rect.bottom, hdc, 0, 0, SRCCOPY); DeleteObject(hBM); DeleteDC(hdc); DeleteObject(nullPen); DeleteObject(nullBrush); DeleteObject(currentBrush); DestroyIcon(breakPoint); DestroyIcon(breakPointDisable); EndPaint(wnd, &ps); }
int main(int argc, char *argv[]) { coordinates coord; // Coodinates Structure depth depth; color colorsIn[2048]; // Colors array int numColors = 0; // Number of colors to use in color array float colorPower = .3; // Power exponent to use for color selection int colorStart = 0xFF0000, colorEnd = 0xFFFF00; // Default color gradient settings char *filename = "mandelbrot.png"; // Default PNG output name int i; // Misc variables bool noWindow = false; // Default flag for no-window mode // Set default coordinates before reading in args coord.x = -2; // Default Start Coordinates coord.y = 2; coord.xR = 4; // Default Range Coordinates coord.yR = 4; coord.width = -1; // Invalid pixel size, to be set later coord.height = -1; depth.d = 100; // Default Depth level of Mandelbrot Calculation depth.automatic = true; // Generate default gradient first genGradient(colorsIn, &numColors, colorStart, colorEnd); // Parse Arguments for (i=1; i<argc; i++) { if (strcmp(argv[i], "--width") == 0) { coord.width = arg_check_int(argc, argv, i, 1, 10); i++; } else if (strcmp(argv[i], "--height") == 0) { coord.height = arg_check_int(argc, argv, i, 1, 10); i++; } else if (strcmp(argv[i], "--depth") == 0) { depth.automatic = false; depth.d = arg_check_int(argc, argv, i, 1, 10); i++; } else if (strcmp(argv[i], "--coords") == 0) { coord.x = arg_check_float(argc, argv, i, 1); coord.y = arg_check_float(argc, argv, i, 2); coord.xR = arg_check_float(argc, argv, i, 3); coord.yR = arg_check_float(argc, argv, i, 4); i+=4; } else if (strcmp(argv[i], "--spectrum") == 0) { genSpectrum(colorsIn, &numColors); colorPower = .7; } else if (strcmp(argv[i], "--random") == 0) { genRandom(colorsIn, &numColors); colorPower = 1; } else if (strcmp(argv[i], "--gradient") == 0) { colorStart = arg_check_int(argc, argv, i, 1, 16); colorEnd = arg_check_int(argc, argv, i, 2, 16); genGradient(colorsIn, &numColors, colorStart, colorEnd); i+=2; } else if (strcmp(argv[i], "-o") == 0) { filename = argv[i+1]; i++; } else if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0 ) { help(); } else if (strcmp(argv[i], "-nw") == 0 ) { noWindow = true; } else { errx(EXIT_FAILURE, "Unknown argument, \"%s\".", argv[i]); } } // Make proportional image if only one dimension is specified // Set to default width and height if not specified if (coord.height < 0 && coord.width > 0) coord.height = coord.width / coord.xR * coord.yR; else if (coord.height > 0 && coord.width < 0) coord.width = coord.height / coord.yR * coord.xR; else if (coord.height < 0 && coord.width < 0) coord.width = coord.height = 1024; coord.xS = coord.xR/coord.width; // X Step Value coord.yS = coord.yR/coord.height; // Y Step Value // Create final array of colors to use that is scaled to the depth that is selected color colors[2048]; scaleColor(colorsIn, colors, numColors, depth.d, colorPower); // If no window mode, just output file and exit if (noWindow) { generate_png(coord, depth.d, filename, colors, numColors); return 0; } // Set up SDL SDL_Init(SDL_INIT_VIDEO); SDL_Window* Main_Window; SDL_Renderer* Main_Renderer; Main_Window = SDL_CreateWindow("Mandelbrot", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, coord.width, coord.height, SDL_WINDOW_RESIZABLE); Main_Renderer = SDL_CreateRenderer(Main_Window, -1, SDL_RENDERER_ACCELERATED); SDL_Texture *texture = SDL_CreateTexture(Main_Renderer, SDL_PIXELFORMAT_RGBX8888, SDL_TEXTUREACCESS_STREAMING, coord.width, coord.height); int pitch; void *pixels; if (SDL_LockTexture(texture, NULL, &pixels, &pitch) != 0) errx(EXIT_FAILURE, "SDL_LockTexture: %s", SDL_GetError()); //uint32_t (*pixel)[coord.height][pitch/sizeof(uint32_t)] = pixels; // Set up struct for tracking mouse movement mouse mouseTracker; mouseTracker.down = false; //Main Loop int maxRender = 2; int needsRender = maxRender; while (1) { // Render Loop if (needsRender > 0) { uint32_t (*pixel)[coord.height][pitch/sizeof(uint32_t)] = pixels; //unsigned long long timer = utime(); //DEBUG - Start Timer float pixelSize = pow(2, --needsRender); //printf("%d %d\n", needsRender, pixelSize); coordinates scaledCoord; scaledCoord.width = coord.width / pixelSize; scaledCoord.height = coord.height / pixelSize; scaledCoord.x = coord.x; scaledCoord.xR = coord.xR; scaledCoord.xS = scaledCoord.xR/scaledCoord.width; scaledCoord.y = coord.y; scaledCoord.yR = coord.yR; scaledCoord.yS = scaledCoord.yR/scaledCoord.height; // y step value SDL_Rect srcrect = {0, 0, scaledCoord.width, scaledCoord.height}; for (int y=0; y<scaledCoord.height; y++) for (int x=0; x<scaledCoord.width; x++) { double xValue = scaledCoord.x + (x * scaledCoord.xS); double yValue = scaledCoord.y - (y * scaledCoord.yS); int result = mandel(xValue, yValue, depth.d); int finalColor = 0; if (result != -1) finalColor = colors[result].hex << 8; (*pixel)[y][x] = finalColor; } SDL_UnlockTexture(texture); SDL_RenderCopy(Main_Renderer, texture, &srcrect, NULL); //printf("%llu - Finish Render\n", utime()-timer); //DEBUG - End Timer SDL_RenderPresent(Main_Renderer); } SDL_Event e; //SDL_WaitEvent(&e); if (SDL_WaitEventTimeout(&e, 10) == 0) continue; if (e.type == SDL_MOUSEWHEEL) { if (e.wheel.y > 0) coord_zoom(&coord, 1); else coord_zoom(&coord, -1); if (depth.automatic == true) { adjust_depth(&coord, &depth); scaleColor(colorsIn, colors, numColors, depth.d, colorPower); } needsRender = maxRender; } if (e.type == SDL_WINDOWEVENT) if (e.window.event == SDL_WINDOWEVENT_RESIZED) { // Adjust view to new size coord.width = e.window.data1; coord.height = e.window.data2; coord.xR = coord.width * coord.xS; coord.yR = coord.height * coord.yS; // Destroy old texture SDL_DestroyTexture(texture); // Make New Texture texture = SDL_CreateTexture(Main_Renderer, SDL_PIXELFORMAT_RGBX8888, SDL_TEXTUREACCESS_STREAMING, coord.width, coord.height); // Lock with new texture if (SDL_LockTexture(texture, NULL, &pixels, &pitch) != 0) errx(EXIT_FAILURE, "SDL_LockTexture: %s", SDL_GetError()); // Rerender needsRender = maxRender; } if (e.type == SDL_MOUSEBUTTONDOWN) if (e.button.state == SDL_PRESSED) { mouseTracker.mouseX = e.motion.x; mouseTracker.mouseY = e.motion.y; mouseTracker.coordX = coord.x; mouseTracker.coordY = coord.y; mouseTracker.down = true; } if (e.type == SDL_MOUSEBUTTONUP) if (e.button.state == SDL_RELEASED) mouseTracker.down = false; if (e.type == SDL_MOUSEMOTION && mouseTracker.down == true) { coord.x = mouseTracker.coordX + ((mouseTracker.mouseX - e.motion.x) * coord.xS); coord.y = mouseTracker.coordY - ((mouseTracker.mouseY - e.motion.y) * coord.yS); needsRender = maxRender; } if (e.type == SDL_KEYUP) { if (e.key.keysym.sym == SDLK_p) print_coords(&coord, &depth); if (e.key.keysym.sym == SDLK_s) generate_png(coord, depth.d, filename, colors, numColors); if (e.key.keysym.sym == SDLK_EQUALS || e.key.keysym.sym == SDLK_MINUS) { depth.automatic = false; if (e.key.keysym.sym == SDLK_EQUALS) depth.d += 5; if (e.key.keysym.sym == SDLK_MINUS) if (depth.d > 5) depth.d -= 5; scaleColor(colorsIn, colors, numColors, depth.d, colorPower); needsRender = maxRender; } } if (e.type == SDL_QUIT) { SDL_Log("Program quit after %i ticks", e.quit.timestamp); break; } } return 0; }
void CtrlDisAsmView::onPaint(WPARAM wParam, LPARAM lParam) { if (!debugger->isAlive()) return; PAINTSTRUCT ps; HDC actualHdc = BeginPaint(wnd, &ps); HDC hdc = CreateCompatibleDC(actualHdc); HBITMAP hBM = CreateCompatibleBitmap(actualHdc, rect.right-rect.left, rect.bottom-rect.top); SelectObject(hdc, hBM); SetBkMode(hdc, TRANSPARENT); HPEN nullPen=CreatePen(0,0,0xffffff); HPEN condPen=CreatePen(0,0,0xFF3020); HBRUSH nullBrush=CreateSolidBrush(0xffffff); HBRUSH currentBrush=CreateSolidBrush(0xFFEfE8); HPEN oldPen=(HPEN)SelectObject(hdc,nullPen); HBRUSH oldBrush=(HBRUSH)SelectObject(hdc,nullBrush); HFONT oldFont = (HFONT)SelectObject(hdc,(HGDIOBJ)font); HICON breakPoint = (HICON)LoadIcon(GetModuleHandle(0),(LPCWSTR)IDI_STOP); HICON breakPointDisable = (HICON)LoadIcon(GetModuleHandle(0),(LPCWSTR)IDI_STOPDISABLE); for (int i = 0; i < visibleRows+2; i++) { unsigned int address=windowStart + i*instructionSize; MIPSAnalyst::MipsOpcodeInfo info = MIPSAnalyst::GetOpcodeInfo(debugger,address); int rowY1 = rowHeight*i; int rowY2 = rowHeight*(i+1); // draw background COLORREF backgroundColor = whiteBackground ? 0xFFFFFF : debugger->getColor(address); COLORREF textColor = 0x000000; if (address == debugger->getPC()) { backgroundColor = scaleColor(backgroundColor,1.05f); } if (address >= selectRangeStart && address < selectRangeEnd && searching == false) { if (hasFocus) { backgroundColor = address == curAddress ? 0xFF8822 : 0xFF9933; textColor = 0xFFFFFF; } else { backgroundColor = 0xC0C0C0; } } HBRUSH backgroundBrush = CreateSolidBrush(backgroundColor); HPEN backgroundPen = CreatePen(0,0,backgroundColor); SelectObject(hdc,backgroundBrush); SelectObject(hdc,backgroundPen); Rectangle(hdc,0,rowY1,rect.right,rowY1+rowHeight); SelectObject(hdc,currentBrush); SelectObject(hdc,nullPen); DeleteObject(backgroundBrush); DeleteObject(backgroundPen); // display address/symbol bool enabled; if (CBreakPoints::IsAddressBreakPoint(address,&enabled)) { if (enabled) textColor = 0x0000FF; int yOffset = max(-1,(rowHeight-14+1)/2); DrawIconEx(hdc,2,rowY1+1+yOffset,enabled ? breakPoint : breakPointDisable,32,32,0,0,DI_NORMAL); } SetTextColor(hdc,textColor); char addressText[64]; getDisasmAddressText(address,addressText,true); TextOutA(hdc,pixelPositions.addressStart,rowY1+2,addressText,(int)strlen(addressText)); if (address == debugger->getPC()) { TextOut(hdc,pixelPositions.opcodeStart-8,rowY1,L"■",1); } // display opcode char opcode[64],arguments[256]; const char *dizz = debugger->disasm(address, instructionSize); parseDisasm(dizz,opcode,arguments); // display whether the condition of a branch is met if (info.isConditional && address == debugger->getPC()) { strcat(arguments,info.conditionMet ? " ; true" : " ; false"); } int length = (int) strlen(arguments); if (length != 0) TextOutA(hdc,pixelPositions.argumentsStart,rowY1+2,arguments,length); SelectObject(hdc,boldfont); TextOutA(hdc,pixelPositions.opcodeStart,rowY1+2,opcode,(int)strlen(opcode)); SelectObject(hdc,font); } SelectObject(hdc,condPen); for (size_t i = 0; i < visibleFunctionAddresses.size(); i++) { auto it = functions.find(visibleFunctionAddresses[i]); if (it == functions.end()) continue; DisassemblyFunction& func = it->second; for (size_t l = 0; l < func.lines.size(); l++) { drawBranchLine(hdc,func.lines[l]); } } for (size_t i = 0; i < strayLines.size(); i++) { drawBranchLine(hdc,strayLines[i]); } SelectObject(hdc,oldFont); SelectObject(hdc,oldPen); SelectObject(hdc,oldBrush); // copy bitmap to the actual hdc BitBlt(actualHdc, 0, 0, rect.right, rect.bottom, hdc, 0, 0, SRCCOPY); DeleteObject(hBM); DeleteDC(hdc); DeleteObject(nullPen); DeleteObject(condPen); DeleteObject(nullBrush); DeleteObject(currentBrush); DestroyIcon(breakPoint); DestroyIcon(breakPointDisable); EndPaint(wnd, &ps); }