int screenshot_dump_png() { int i, index, width, height, stride; char path[MAX_PATH] = ""; unsigned char r, g, b, a = 255; unsigned char* png; size_t pngSize; LodePNGState state; // Get a free screenshot path if ((index = screenshot_get_next_path(path, ".png")) == -1) return -1; lodepng_state_init(&state); state.info_raw.colortype = LCT_PALETTE; // Get image size width = RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, uint16); height = RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_HEIGHT, uint16); stride = (width + 3) & 0xFFFFFFFC; for (i = 0; i < 246; i++) { b = RCT2_ADDRESS(0x01424680, uint8)[i * 4 + 0]; g = RCT2_ADDRESS(0x01424680, uint8)[i * 4 + 1]; r = RCT2_ADDRESS(0x01424680, uint8)[i * 4 + 2]; lodepng_palette_add(&state.info_raw, r, g, b, a); } rct_drawpixelinfo *dpi = RCT2_ADDRESS(RCT2_ADDRESS_SCREEN_DPI, rct_drawpixelinfo); unsigned int error = lodepng_encode(&png, &pngSize, dpi->bits, stride, dpi->height, &state); if (!error) lodepng_save_file(png, pngSize, path); if (error) { fprintf(stderr, "error: %u: %s\n", error, lodepng_error_text(error)); index = -1; } free(png); return index; }
/** * * rct2: 0x00683D20 */ int screenshot_dump_bmp() { BitmapFileHeader header; BitmapInfoHeader info; int i, y, index, width, height, stride; char *buffer, path[MAX_PATH], *row; FILE *fp; unsigned int bytesWritten; // Get a free screenshot path if ((index = screenshot_get_next_path(path, ".bmp")) == -1) return -1; // Open binary file for writing if ((fp = fopen(path, "wb")) == NULL){ return -1; } // Allocate buffer buffer = malloc(0xFFFF); if (buffer == NULL) { //CloseHandle(hFile); fclose(fp); return -1; } // Get image size width = RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, uint16); height = RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_HEIGHT, uint16); stride = (width + 3) & 0xFFFFFFFC; // File header memset(&header, 0, sizeof(header)); header.bfType = 0x4D42; header.bfSize = height * stride + 1038; header.bfOffBits = 1038; bytesWritten = fwrite(&header, sizeof(BitmapFileHeader), 1, fp); if (bytesWritten != 1) { fclose(fp); free(buffer); } // Info header memset(&info, 0, sizeof(info)); info.biSize = sizeof(info); info.biWidth = width; info.biHeight = height; info.biPlanes = 1; info.biBitCount = 8; info.biXPelsPerMeter = 2520; info.biYPelsPerMeter = 2520; info.biClrUsed = 246; bytesWritten=fwrite(&info, sizeof(BitmapInfoHeader), 1, fp); if (bytesWritten != 1) { fclose(fp); free(buffer); } // Palette memset(buffer, 0, 246 * 4); for (i = 0; i < 246; i++) { buffer[i * 4 + 0] = RCT2_ADDRESS(0x01424680, uint8)[i * 4 + 0]; buffer[i * 4 + 1] = RCT2_ADDRESS(0x01424680, uint8)[i * 4 + 1]; buffer[i * 4 + 2] = RCT2_ADDRESS(0x01424680, uint8)[i * 4 + 2]; } bytesWritten = fwrite(buffer, sizeof(char), 246*4, fp); if (bytesWritten != 246*4){ fclose(fp); free(buffer); } // Image, save upside down rct_drawpixelinfo *dpi = RCT2_ADDRESS(RCT2_ADDRESS_SCREEN_DPI, rct_drawpixelinfo); for (y = dpi->height - 1; y >= 0; y--) { row = dpi->bits + y * (dpi->width + dpi->pitch); memset(buffer, 0, stride); memcpy(buffer, row, dpi->width); bytesWritten=fwrite(buffer, sizeof(char), stride, fp); if (bytesWritten != stride){ fclose(fp); free(buffer); } } fclose(fp); free(buffer); return index; }
/** * * rct2: 0x00683D20 */ int screenshot_dump_bmp() { BitmapFileHeader header; BitmapInfoHeader info; int i, y, index, width, height, stride; char *buffer, path[MAX_PATH], *row; HANDLE hFile; DWORD bytesWritten; // Get a free screenshot path if ((index = screenshot_get_next_path(path, ".bmp")) == -1) return -1; // Open file for writing hFile = CreateFile(path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) return -1; // Allocate buffer buffer = malloc(0xFFFF); if (buffer == NULL) { CloseHandle(hFile); return -1; } // Get image size width = RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, uint16); height = RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_HEIGHT, uint16); stride = (width + 3) & 0xFFFFFFFC; // File header memset(&header, 0, sizeof(header)); header.bfType = 0x4D42; header.bfSize = height * stride + 1038; header.bfOffBits = 1038; WriteFile(hFile, &header, sizeof(header), &bytesWritten, NULL); if (bytesWritten != sizeof(header)) { CloseHandle(hFile); free(buffer); } // Info header memset(&info, 0, sizeof(info)); info.biSize = sizeof(info); info.biWidth = width; info.biHeight = height; info.biPlanes = 1; info.biBitCount = 8; info.biXPelsPerMeter = 2520; info.biYPelsPerMeter = 2520; info.biClrUsed = 246; WriteFile(hFile, &info, sizeof(info), &bytesWritten, NULL); if (bytesWritten != sizeof(info)) { CloseHandle(hFile); free(buffer); } // Palette memset(buffer, 0, 246 * 4); for (i = 0; i < 246; i++) { buffer[i * 4 + 0] = RCT2_ADDRESS(0x01424680, uint8)[i * 4 + 0]; buffer[i * 4 + 1] = RCT2_ADDRESS(0x01424680, uint8)[i * 4 + 1]; buffer[i * 4 + 2] = RCT2_ADDRESS(0x01424680, uint8)[i * 4 + 2]; } WriteFile(hFile, buffer, 246 * 4, &bytesWritten, NULL); if (bytesWritten != 246 * 4) { CloseHandle(hFile); free(buffer); } // Image, save upside down rct_drawpixelinfo *dpi = RCT2_ADDRESS(RCT2_ADDRESS_SCREEN_DPI, rct_drawpixelinfo); for (y = dpi->height - 1; y >= 0; y--) { row = dpi->bits + y * (dpi->width + dpi->pitch); memset(buffer, 0, stride); memcpy(buffer, row, dpi->width); WriteFile(hFile, buffer, stride, &bytesWritten, NULL); if (bytesWritten != stride) { CloseHandle(hFile); free(buffer); } } CloseHandle(hFile); free(buffer); return index; }