Merge pull request #10435 from unknownbrackets/debugger

Fix issues with GE debugger prim preview
This commit is contained in:
Henrik Rydgård authored and GitHub committed 2017-12-23 12:09:44 +01:00
commit 46c468f3fe
7 files changed
+248 -150

No files matched your search

+29 -7
View File
@@ -157,16 +157,27 @@ void CGEDebugger::SetupPreviews() {
PrimaryPreviewHover(x, y);
});
primaryWindow->SetRightClickMenu(subMenu, [&] (int cmd) {
HMENU subMenu = GetSubMenu(g_hPopupMenus, POPUP_SUBMENU_ID_GEDBG_PREVIEW);
switch (cmd) {
case 0:
// Setup.
CheckMenuItem(subMenu, ID_GEDBG_ENABLE_PREVIEW, MF_BYCOMMAND | ((previewsEnabled_ & 1) ? MF_CHECKED : MF_UNCHECKED));
break;
case ID_GEDBG_EXPORT_IMAGE:
PreviewExport(primaryBuffer_);
break;
case ID_GEDBG_ENABLE_PREVIEW:
previewsEnabled_ ^= 1;
primaryWindow->Redraw();
default:
break;
}
return true;
});
primaryWindow->SetRedrawCallback([&] {
HandleRedraw(1);
});
primaryWindow->Clear();
}
if (secondWindow == nullptr) {
@@ -178,16 +189,27 @@ void CGEDebugger::SetupPreviews() {
SecondPreviewHover(x, y);
});
secondWindow->SetRightClickMenu(subMenu, [&] (int cmd) {
HMENU subMenu = GetSubMenu(g_hPopupMenus, POPUP_SUBMENU_ID_GEDBG_PREVIEW);
switch (cmd) {
case 0:
// Setup.
CheckMenuItem(subMenu, ID_GEDBG_ENABLE_PREVIEW, MF_BYCOMMAND | ((previewsEnabled_ & 2) ? MF_CHECKED : MF_UNCHECKED));
break;
case ID_GEDBG_EXPORT_IMAGE:
PreviewExport(secondBuffer_);
break;
case ID_GEDBG_ENABLE_PREVIEW:
previewsEnabled_ ^= 2;
secondWindow->Redraw();
default:
break;
}
return true;
});
secondWindow->SetRedrawCallback([&] {
HandleRedraw(2);
});
secondWindow->Clear();
}
}
@@ -258,19 +280,18 @@ void CGEDebugger::UpdatePreviews() {
state = gpuDebug->GetGState();
}
updating_ = true;
UpdateTextureLevel(textureLevel_);
UpdatePrimaryPreview(state);
UpdateSecondPreview(state);
u32 primOp = PrimPreviewOp();
if (primOp != 0) {
UpdatePrimPreview(primOp, 3);
}
DisplayList list;
if (gpuDebug != nullptr && gpuDebug->GetCurrentDisplayList(list)) {
const u32 op = Memory::Read_U32(list.pc);
const u32 cmd = op >> 24;
// TODO: Bezier/spline?
if (cmd == GE_CMD_PRIM && !showClut_) {
UpdatePrimPreview(op);
}
displayList->setDisplayList(list);
}
@@ -282,6 +303,7 @@ void CGEDebugger::UpdatePreviews() {
matrices->Update();
lists->Update();
watch->Update();
updating_ = false;
}
u32 CGEDebugger::TexturePreviewFlags(const GPUgstate &state) {
+5 -1
View File
@@ -70,8 +70,10 @@ private:
void UpdatePreviews();
void UpdatePrimaryPreview(const GPUgstate &state);
void UpdateSecondPreview(const GPUgstate &state);
void UpdatePrimPreview(u32 op);
u32 PrimPreviewOp();
void UpdatePrimPreview(u32 op, int which);
void CleanupPrimPreview();
void HandleRedraw(int which);
void UpdateSize(WORD width, WORD height);
void SavePosition();
void SetBreakNext(BreakNextType type);
@@ -106,6 +108,8 @@ private:
const GPUDebugBuffer *primaryBuffer_ = nullptr;
const GPUDebugBuffer *secondBuffer_ = nullptr;
bool updating_ = false;
int previewsEnabled_ = 3;
int minWidth_;
int minHeight_;
};
+21 -6
View File
@@ -68,8 +68,7 @@ static const char basic_vs[] =
"}\n";
SimpleGLWindow::SimpleGLWindow(HWND wnd)
: hWnd_(wnd), valid_(false), drawProgram_(nullptr), vao_(0), tex_(0), flags_(0), zoom_(false),
dragging_(false), offsetX_(0), offsetY_(0), reformatBuf_(nullptr), hoverCallback_(nullptr) {
: hWnd_(wnd) {
SetWindowLongPtr(wnd, GWLP_USERDATA, (LONG_PTR) this);
}
@@ -365,10 +364,23 @@ void SimpleGLWindow::GetContentSize(float &x, float &y, float &fw, float &fh) {
void SimpleGLWindow::Redraw(bool andSwap) {
DrawChecker();
if (tw_ == 0 && th_ == 0) {
auto swapWithCallback = [andSwap, this]() {
if (andSwap) {
Swap();
swapped_ = false;
if (redrawCallback_ && !inRedrawCallback_) {
inRedrawCallback_ = true;
redrawCallback_();
inRedrawCallback_ = false;
}
// In case the callback swaps, don't do it twice.
if (!swapped_) {
Swap();
}
}
};
if (tw_ == 0 && th_ == 0) {
swapWithCallback();
return;
}
@@ -412,7 +424,7 @@ void SimpleGLWindow::Redraw(bool andSwap) {
glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, vao_ ? 0 : indices);
if (andSwap) {
Swap();
swapWithCallback();
}
}
@@ -423,7 +435,9 @@ void SimpleGLWindow::Clear() {
}
void SimpleGLWindow::Begin() {
Redraw(false);
if (!inRedrawCallback_) {
Redraw(false);
}
if (vao_) {
glBindVertexArray(0);
@@ -549,6 +563,7 @@ bool SimpleGLWindow::RightClick(int mouseX, int mouseY) {
POINT pt{mouseX, mouseY};
ClientToScreen(hWnd_, &pt);
rightClickCallback_(0);
int result = TrackPopupMenuEx(rightClickMenu_, TPM_RIGHTBUTTON | TPM_RETURNCMD, pt.x, pt.y, hWnd_, 0);
if (result != 0) {
rightClickCallback_(result);
+23 -14
View File
@@ -81,6 +81,7 @@ struct SimpleGLWindow {
}
void Swap() {
swapped_ = true;
SwapBuffers(hDC_);
}
@@ -106,10 +107,15 @@ struct SimpleGLWindow {
void GetContentSize(float &x, float &y, float &fw, float &fh);
void SetRedrawCallback(std::function<void()> callback) {
redrawCallback_ = callback;
}
void SetHoverCallback(std::function<void(int, int)> hoverCallback) {
hoverCallback_ = hoverCallback;
}
// Called first with 0 that it's opening, then the selected item.
void SetRightClickMenu(HMENU menu, std::function<void(int)> callback) {
rightClickCallback_ = callback;
rightClickMenu_ = menu;
@@ -134,7 +140,7 @@ protected:
HWND hWnd_;
HDC hDC_;
HGLRC hGLRC_;
bool valid_;
bool valid_ = false;
// Width and height of the window.
int w_;
int h_;
@@ -143,25 +149,28 @@ protected:
int th_;
bool tflipped_;
GLSLProgram *drawProgram_;
GLuint vao_;
GLuint ibuf_;
GLuint vbuf_;
GLuint checker_;
GLuint tex_;
u32 flags_;
GLSLProgram *drawProgram_ = nullptr;
GLuint vao_ = 0;
GLuint ibuf_ = 0;
GLuint vbuf_ = 0;
GLuint checker_ = 0;
GLuint tex_ = 0;
u32 flags_ = 0;
// Disable shrink (toggled by double click.)
bool zoom_;
bool dragging_;
bool zoom_ = false;
bool dragging_ = false;
bool inRedrawCallback_ = false;
bool swapped_ = false;
int dragStartX_;
int dragStartY_;
u32 dragLastUpdate_;
// Offset to position the texture is drawn at.
int offsetX_;
int offsetY_;
u32 *reformatBuf_;
u32 reformatBufSize_;
int offsetX_ = 0;
int offsetY_ = 0;
u32 *reformatBuf_ = nullptr;
u32 reformatBufSize_ = 0;
std::function<void()> redrawCallback_;
std::function<void(int, int)> hoverCallback_;
std::function<void(int)> rightClickCallback_;
HMENU rightClickMenu_;
+167 -121
View File
@@ -151,7 +151,21 @@ static void ExpandRectangles(std::vector<GPUDebugVertex> &vertices, std::vector<
count *= 3;
}
void CGEDebugger::UpdatePrimPreview(u32 op) {
u32 CGEDebugger::PrimPreviewOp() {
DisplayList list;
if (gpuDebug != nullptr && gpuDebug->GetCurrentDisplayList(list)) {
const u32 op = Memory::Read_U32(list.pc);
const u32 cmd = op >> 24;
// TODO: Bezier/spline?
if (cmd == GE_CMD_PRIM && !showClut_) {
return op;
}
}
return 0;
}
void CGEDebugger::UpdatePrimPreview(u32 op, int which) {
const u32 prim_type = (op >> 16) & 0x7;
int count = op & 0xFFFF;
if (prim_type >= 7) {
@@ -162,7 +176,8 @@ void CGEDebugger::UpdatePrimPreview(u32 op) {
ERROR_LOG(G3D, "Invalid debugging environment, shutting down?");
return;
}
if (count == 0) {
which &= previewsEnabled_;
if (count == 0 || which == 0) {
return;
}
@@ -182,17 +197,6 @@ void CGEDebugger::UpdatePrimPreview(u32 op) {
float fw, fh;
float x, y;
primaryWindow->Begin();
primaryWindow->GetContentSize(x, y, fw, fh);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBlendEquation(GL_FUNC_ADD);
glBindTexture(GL_TEXTURE_2D, 0);
glViewport((GLint)x, (GLint)y, (GLsizei)fw, (GLsizei)fh);
glScissor((GLint)x, (GLint)y, (GLsizei)fw, (GLsizei)fh);
BindPreviewProgram(previewProgram);
// TODO: Probably there's a better way and place to do this.
u16 minIndex = 0;
u16 maxIndex = count - 1;
@@ -209,124 +213,155 @@ void CGEDebugger::UpdatePrimPreview(u32 op) {
}
}
const float invTexWidth = 1.0f / gstate_c.curTextureWidth;
const float invTexHeight = 1.0f / gstate_c.curTextureHeight;
auto wrapCoord = [](float &coord) {
if (coord < 0.0f) {
coord += ceilf(-coord);
}
if (coord > 1.0f) {
coord -= floorf(coord);
}
};
const float invTexWidth = 1.0f / gpuDebug->GetGState().getTextureWidth(0);
const float invTexHeight = 1.0f / gpuDebug->GetGState().getTextureHeight(0);
const float invRealTexWidth = 1.0f / gstate_c.curTextureWidth;
const float invRealTexHeight = 1.0f / gstate_c.curTextureHeight;
bool clampS = gpuDebug->GetGState().isTexCoordClampedS();
bool clampT = gpuDebug->GetGState().isTexCoordClampedT();
for (u16 i = minIndex; i <= maxIndex; ++i) {
vertices[i].u *= invTexWidth;
vertices[i].v *= invTexHeight;
if (vertices[i].u > 1.0f || vertices[i].u < 0.0f)
vertices[i].u -= floor(vertices[i].u);
if (vertices[i].v > 1.0f || vertices[i].v < 0.0f)
vertices[i].v -= floor(vertices[i].v);
if (!clampS)
wrapCoord(vertices[i].u);
if (!clampT)
wrapCoord(vertices[i].v);
}
if (previewVao == 0 && gl_extensions.ARB_vertex_array_object) {
glGenVertexArrays(1, &previewVao);
glBindVertexArray(previewVao);
glEnableVertexAttribArray(previewProgram->a_position);
if (which & 1) {
primaryWindow->Begin();
primaryWindow->GetContentSize(x, y, fw, fh);
glGenBuffers(1, &ibuf);
glGenBuffers(1, &vbuf);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibuf);
glBindBuffer(GL_ARRAY_BUFFER, vbuf);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBlendEquation(GL_FUNC_ADD);
glBindTexture(GL_TEXTURE_2D, 0);
// The surface is upside down, so vertical offsets are negated.
glViewport((GLint)x, (GLint)-(y + fh - primaryWindow->Height()), (GLsizei)fw, (GLsizei)fh);
glScissor((GLint)x, (GLint)-(y + fh - primaryWindow->Height()), (GLsizei)fw, (GLsizei)fh);
BindPreviewProgram(previewProgram);
glVertexAttribPointer(previewProgram->a_position, 3, GL_FLOAT, GL_FALSE, sizeof(GPUDebugVertex), (void *)(2 * sizeof(float)));
if (previewVao == 0 && gl_extensions.ARB_vertex_array_object) {
glGenVertexArrays(1, &previewVao);
glBindVertexArray(previewVao);
glEnableVertexAttribArray(previewProgram->a_position);
glGenBuffers(1, &ibuf);
glGenBuffers(1, &vbuf);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibuf);
glBindBuffer(GL_ARRAY_BUFFER, vbuf);
glVertexAttribPointer(previewProgram->a_position, 3, GL_FLOAT, GL_FALSE, sizeof(GPUDebugVertex), (void *)(2 * sizeof(float)));
}
if (vbuf != 0) {
glBindBuffer(GL_ARRAY_BUFFER, vbuf);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(GPUDebugVertex), vertices.data(), GL_STREAM_DRAW);
}
if (ibuf != 0 && !indices.empty()) {
glBindVertexArray(previewVao);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(u16), indices.data(), GL_STREAM_DRAW);
}
float scale[] = {
480.0f / (float)PSP_CoreParameter().renderWidth,
272.0f / (float)PSP_CoreParameter().renderHeight,
};
Matrix4x4 ortho;
ortho.setOrtho(-(float)gstate_c.curRTOffsetX, (primaryWindow->TexWidth() - (int)gstate_c.curRTOffsetX) * scale[0], primaryWindow->TexHeight() * scale[1], 0, -1, 1);
glUniformMatrix4fv(previewProgram->u_viewproj, 1, GL_FALSE, ortho.getReadPtr());
if (previewVao != 0) {
glBindVertexArray(previewVao);
} else {
glEnableVertexAttribArray(previewProgram->a_position);
glVertexAttribPointer(previewProgram->a_position, 3, GL_FLOAT, GL_FALSE, sizeof(GPUDebugVertex), (float *)vertices.data() + 2);
}
if (indices.empty()) {
glDrawArrays(glprim[prim], 0, count);
} else {
glDrawElements(glprim[prim], count, GL_UNSIGNED_SHORT, previewVao != 0 ? 0 : indices.data());
}
if (previewVao == 0) {
glDisableVertexAttribArray(previewProgram->a_position);
}
primaryWindow->End();
}
if (vbuf != 0) {
glBindBuffer(GL_ARRAY_BUFFER, vbuf);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(GPUDebugVertex), vertices.data(), GL_STREAM_DRAW);
if (which & 2) {
secondWindow->Begin();
secondWindow->GetContentSize(x, y, fw, fh);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBlendEquation(GL_FUNC_ADD);
glBindTexture(GL_TEXTURE_2D, 0);
// The surface is upside down, so vertical offsets are flipped.
glViewport((GLint)x, (GLint)-(y + fh - secondWindow->Height()), (GLsizei)fw, (GLsizei)fh);
glScissor((GLint)x, (GLint)-(y + fh - secondWindow->Height()), (GLsizei)fw, (GLsizei)fh);
BindPreviewProgram(texPreviewProgram);
if (texPreviewVao == 0 && gl_extensions.ARB_vertex_array_object) {
glGenVertexArrays(1, &texPreviewVao);
glBindVertexArray(texPreviewVao);
glEnableVertexAttribArray(texPreviewProgram->a_position);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibuf);
glBindBuffer(GL_ARRAY_BUFFER, vbuf);
glVertexAttribPointer(texPreviewProgram->a_position, 2, GL_FLOAT, GL_FALSE, sizeof(GPUDebugVertex), 0);
}
// TODO: For some reason we have to re-upload the data?
if (vbuf != 0) {
glBindBuffer(GL_ARRAY_BUFFER, vbuf);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(GPUDebugVertex), vertices.data(), GL_STREAM_DRAW);
}
if (ibuf != 0 && !indices.empty()) {
glBindVertexArray(texPreviewVao);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(u16), indices.data(), GL_STREAM_DRAW);
}
Matrix4x4 ortho;
ortho.setOrtho(0.0f - (float)gstate_c.curTextureXOffset * invRealTexWidth, 1.0f - (float)gstate_c.curTextureXOffset * invRealTexWidth, 1.0f - (float)gstate_c.curTextureYOffset * invRealTexHeight, 0.0f - (float)gstate_c.curTextureYOffset * invRealTexHeight, -1.0f, 1.0f);
glUniformMatrix4fv(texPreviewProgram->u_viewproj, 1, GL_FALSE, ortho.getReadPtr());
if (texPreviewVao != 0) {
glBindVertexArray(texPreviewVao);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibuf);
glBindBuffer(GL_ARRAY_BUFFER, vbuf);
glEnableVertexAttribArray(texPreviewProgram->a_position);
glVertexAttribPointer(texPreviewProgram->a_position, 2, GL_FLOAT, GL_FALSE, sizeof(GPUDebugVertex), 0);
} else {
glEnableVertexAttribArray(texPreviewProgram->a_position);
glVertexAttribPointer(texPreviewProgram->a_position, 2, GL_FLOAT, GL_FALSE, sizeof(GPUDebugVertex), (float *)vertices.data());
}
if (indices.empty()) {
glDrawArrays(glprim[prim], 0, count);
} else {
glDrawElements(glprim[prim], count, GL_UNSIGNED_SHORT, texPreviewVao != 0 ? 0 : indices.data());
}
if (texPreviewVao == 0) {
glDisableVertexAttribArray(previewProgram->a_position);
}
secondWindow->End();
}
if (ibuf != 0 && !indices.empty()) {
glBindVertexArray(previewVao);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(u16), indices.data(), GL_STREAM_DRAW);
}
float scale[] = {
480.0f / (float)PSP_CoreParameter().renderWidth,
272.0f / (float)PSP_CoreParameter().renderHeight,
};
Matrix4x4 ortho;
ortho.setOrtho(-(float)gstate_c.curRTOffsetX, (primaryWindow->TexWidth() - (int)gstate_c.curRTOffsetX) * scale[0], primaryWindow->TexHeight() * scale[1], 0, -1, 1);
glUniformMatrix4fv(previewProgram->u_viewproj, 1, GL_FALSE, ortho.getReadPtr());
if (previewVao != 0) {
glBindVertexArray(previewVao);
} else {
glEnableVertexAttribArray(previewProgram->a_position);
glVertexAttribPointer(previewProgram->a_position, 3, GL_FLOAT, GL_FALSE, sizeof(GPUDebugVertex), (float *)vertices.data() + 2);
}
if (indices.empty()) {
glDrawArrays(glprim[prim], 0, count);
} else {
glDrawElements(glprim[prim], count, GL_UNSIGNED_SHORT, previewVao != 0 ? 0 : indices.data());
}
if (previewVao == 0) {
glDisableVertexAttribArray(previewProgram->a_position);
}
primaryWindow->End();
secondWindow->Begin();
secondWindow->GetContentSize(x, y, fw, fh);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBlendEquation(GL_FUNC_ADD);
glBindTexture(GL_TEXTURE_2D, 0);
glViewport((GLint)x, (GLint)y, (GLsizei)fw, (GLsizei)fh);
glScissor((GLint)x, (GLint)y, (GLsizei)fw, (GLsizei)fh);
BindPreviewProgram(texPreviewProgram);
if (texPreviewVao == 0 && gl_extensions.ARB_vertex_array_object) {
glGenVertexArrays(1, &texPreviewVao);
glBindVertexArray(texPreviewVao);
glEnableVertexAttribArray(texPreviewProgram->a_position);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibuf);
glBindBuffer(GL_ARRAY_BUFFER, vbuf);
glVertexAttribPointer(texPreviewProgram->a_position, 2, GL_FLOAT, GL_FALSE, sizeof(GPUDebugVertex), 0);
}
// TODO: For some reason we have to re-upload the data?
if (vbuf != 0) {
glBindBuffer(GL_ARRAY_BUFFER, vbuf);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(GPUDebugVertex), vertices.data(), GL_STREAM_DRAW);
}
if (ibuf != 0 && !indices.empty()) {
glBindVertexArray(texPreviewVao);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(u16), indices.data(), GL_STREAM_DRAW);
}
ortho.setOrtho(0.0f - (float)gstate_c.curTextureXOffset * invTexWidth, 1.0f - (float)gstate_c.curTextureXOffset * invTexWidth, 1.0f - (float)gstate_c.curTextureYOffset * invTexHeight, 0.0f - (float)gstate_c.curTextureYOffset * invTexHeight, -1.0f, 1.0f);
glUniformMatrix4fv(texPreviewProgram->u_viewproj, 1, GL_FALSE, ortho.getReadPtr());
if (texPreviewVao != 0) {
glBindVertexArray(texPreviewVao);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibuf);
glBindBuffer(GL_ARRAY_BUFFER, vbuf);
glEnableVertexAttribArray(texPreviewProgram->a_position);
glVertexAttribPointer(texPreviewProgram->a_position, 2, GL_FLOAT, GL_FALSE, sizeof(GPUDebugVertex), 0);
} else {
glEnableVertexAttribArray(texPreviewProgram->a_position);
glVertexAttribPointer(texPreviewProgram->a_position, 2, GL_FLOAT, GL_FALSE, sizeof(GPUDebugVertex), (float *)vertices.data());
}
if (indices.empty()) {
glDrawArrays(glprim[prim], 0, count);
} else {
glDrawElements(glprim[prim], count, GL_UNSIGNED_SHORT, texPreviewVao != 0 ? 0 : indices.data());
}
if (texPreviewVao == 0) {
glDisableVertexAttribArray(previewProgram->a_position);
}
secondWindow->End();
}
void CGEDebugger::CleanupPrimPreview() {
@@ -337,3 +372,14 @@ void CGEDebugger::CleanupPrimPreview() {
glsl_destroy(texPreviewProgram);
}
}
void CGEDebugger::HandleRedraw(int which) {
if (updating_) {
return;
}
u32 op = PrimPreviewOp();
if (op) {
UpdatePrimPreview(op, which);
}
}
+1
View File
@@ -657,6 +657,7 @@ BEGIN
POPUP "gepreviewoptions"
BEGIN
MENUITEM "Export Image...", ID_GEDBG_EXPORT_IMAGE
MENUITEM "Show Prim Preview" ID_GEDBG_ENABLE_PREVIEW
END
END
+2 -1
View File
@@ -335,6 +335,7 @@
#define ID_HELP_GITHUB 40168
#define IDC_GEDBG_RECORD 40169
#define ID_GEDBG_EXPORT_IMAGE 40170
#define ID_GEDBG_ENABLE_PREVIEW 40171
// Dummy option to let the buffered rendering hotkey cycle through all the options.
#define ID_OPTIONS_BUFFEREDRENDERINGDUMMY 40500
@@ -347,7 +348,7 @@
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 256
#define _APS_NEXT_COMMAND_VALUE 40171
#define _APS_NEXT_COMMAND_VALUE 40172
#define _APS_NEXT_CONTROL_VALUE 1200
#define _APS_NEXT_SYMED_VALUE 101
#endif