Merge pull request #1533 from 86Box/master
Bring the branch up to par with master.
This commit is contained in:
@@ -123,7 +123,7 @@ typedef struct tgui_t
|
||||
uint16_t ger22;
|
||||
|
||||
int16_t err, top, left, bottom, right;
|
||||
int x, y;
|
||||
int x, y, dx, dy;
|
||||
uint32_t src, dst, src_old, dst_old;
|
||||
int pat_x, pat_y;
|
||||
int use_src;
|
||||
@@ -650,9 +650,10 @@ void tgui_recalctimings(svga_t *svga)
|
||||
case 8:
|
||||
svga->render = svga_render_8bpp_highres;
|
||||
if (tgui->type >= TGUI_9680) {
|
||||
if (svga->dispend == 512) {
|
||||
if (svga->dispend == 512)
|
||||
svga->hdisp = 1280;
|
||||
}
|
||||
else if (svga->dispend == 1200)
|
||||
svga->hdisp = 1600;
|
||||
}
|
||||
break;
|
||||
case 15:
|
||||
@@ -1222,9 +1223,7 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui)
|
||||
}
|
||||
|
||||
if (count == -1)
|
||||
{
|
||||
tgui->accel.x = tgui->accel.y = 0;
|
||||
}
|
||||
|
||||
if (tgui->accel.flags & TGUI_SOLIDFILL) {
|
||||
for (y = 0; y < 8; y++)
|
||||
@@ -1274,7 +1273,7 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui)
|
||||
pattern_data = tgui->accel.pattern_32;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
switch (tgui->accel.command)
|
||||
{
|
||||
case TGUI_BITBLT:
|
||||
@@ -1287,6 +1286,22 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui)
|
||||
|
||||
tgui->accel.pat_x = tgui->accel.dst_x;
|
||||
tgui->accel.pat_y = tgui->accel.dst_y;
|
||||
|
||||
tgui->accel.dx = tgui->accel.dst_x & 0xfff;
|
||||
tgui->accel.dy = tgui->accel.dst_y & 0xfff;
|
||||
|
||||
tgui->accel.left = tgui->accel.src_x_clip & 0xfff;
|
||||
tgui->accel.right = tgui->accel.dst_x_clip & 0xfff;
|
||||
tgui->accel.top = tgui->accel.src_y_clip & 0xfff;
|
||||
tgui->accel.bottom = tgui->accel.dst_y_clip & 0xfff;
|
||||
|
||||
if (tgui->accel.bpp == 1) {
|
||||
tgui->accel.left >>= 1;
|
||||
tgui->accel.right >>= 1;
|
||||
} else if (tgui->accel.bpp == 3) {
|
||||
tgui->accel.left >>= 2;
|
||||
tgui->accel.right >>= 2;
|
||||
}
|
||||
}
|
||||
|
||||
switch (tgui->accel.flags & (TGUI_SRCMONO|TGUI_SRCDISP))
|
||||
@@ -1301,39 +1316,43 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui)
|
||||
count >>= 3;
|
||||
|
||||
while (count) {
|
||||
if (tgui->accel.bpp == 0) {
|
||||
src_dat = cpu_dat >> 24;
|
||||
cpu_dat <<= 8;
|
||||
count--;
|
||||
} else if (tgui->accel.bpp == 1) {
|
||||
src_dat = (cpu_dat >> 24) | ((cpu_dat >> 8) & 0xff00);
|
||||
cpu_dat <<= 16;
|
||||
count -= 2;
|
||||
} else {
|
||||
src_dat = (cpu_dat >> 24) | ((cpu_dat >> 8) & 0x0000ff00) | ((cpu_dat << 8) & 0x00ff0000);
|
||||
cpu_dat <<= 16;
|
||||
count -= 4;
|
||||
}
|
||||
|
||||
READ(tgui->accel.dst, dst_dat);
|
||||
if ((tgui->type == TGUI_9440) || (tgui->type >= TGUI_9680 && tgui->accel.dx >= tgui->accel.left && tgui->accel.dx <= tgui->accel.right &&
|
||||
tgui->accel.dy >= tgui->accel.top && tgui->accel.dy <= tgui->accel.bottom)) {
|
||||
if (tgui->accel.bpp == 0) {
|
||||
src_dat = cpu_dat >> 24;
|
||||
cpu_dat <<= 8;
|
||||
} else if (tgui->accel.bpp == 1) {
|
||||
src_dat = (cpu_dat >> 24) | ((cpu_dat >> 8) & 0xff00);
|
||||
cpu_dat <<= 16;
|
||||
count--;
|
||||
} else {
|
||||
src_dat = (cpu_dat >> 24) | ((cpu_dat >> 8) & 0x0000ff00) | ((cpu_dat << 8) & 0x00ff0000);
|
||||
cpu_dat <<= 16;
|
||||
count -= 3;
|
||||
}
|
||||
|
||||
READ(tgui->accel.dst, dst_dat);
|
||||
|
||||
pat_dat = pattern_data[((tgui->accel.pat_y & 7)*8) + (tgui->accel.pat_x & 7)];
|
||||
pat_dat = pattern_data[((tgui->accel.pat_y & 7)*8) + (tgui->accel.pat_x & 7)];
|
||||
|
||||
if (tgui->accel.bpp == 0)
|
||||
pat_dat &= 0xff;
|
||||
else if (tgui->accel.bpp == 1)
|
||||
pat_dat &= 0xffff;
|
||||
|
||||
if ((((tgui->accel.flags & (TGUI_PATMONO|TGUI_TRANSENA)) == (TGUI_TRANSENA|TGUI_PATMONO)) && (pat_dat != trans_col)) || !(tgui->accel.flags & TGUI_PATMONO) ||
|
||||
((tgui->accel.flags & (TGUI_PATMONO|TGUI_TRANSENA)) == TGUI_PATMONO)) {
|
||||
MIX();
|
||||
|
||||
if (tgui->accel.bpp == 0)
|
||||
pat_dat &= 0xff;
|
||||
else if (tgui->accel.bpp == 1)
|
||||
pat_dat &= 0xffff;
|
||||
|
||||
if ((((tgui->accel.flags & (TGUI_PATMONO|TGUI_TRANSENA)) == (TGUI_TRANSENA|TGUI_PATMONO)) && (pat_dat != trans_col)) || !(tgui->accel.flags & TGUI_PATMONO) ||
|
||||
((tgui->accel.flags & (TGUI_PATMONO|TGUI_TRANSENA)) == TGUI_PATMONO)) {
|
||||
MIX();
|
||||
|
||||
WRITE(tgui->accel.dst, out);
|
||||
WRITE(tgui->accel.dst, out);
|
||||
}
|
||||
}
|
||||
|
||||
tgui->accel.src += xdir;
|
||||
tgui->accel.dst += xdir;
|
||||
tgui->accel.pat_x += xdir;
|
||||
if (tgui->type >= TGUI_9680)
|
||||
tgui->accel.dx += xdir;
|
||||
|
||||
tgui->accel.x++;
|
||||
if (tgui->accel.x > tgui->accel.size_x) {
|
||||
@@ -1341,6 +1360,11 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui)
|
||||
|
||||
tgui->accel.pat_x = tgui->accel.dst_x;
|
||||
tgui->accel.pat_y += ydir;
|
||||
|
||||
if (tgui->type >= TGUI_9680) {
|
||||
tgui->accel.dx = tgui->accel.dst_x & 0xfff;
|
||||
tgui->accel.dy += ydir;
|
||||
}
|
||||
|
||||
tgui->accel.src_old += (ydir * tgui->accel.pitch);
|
||||
tgui->accel.dst_old += (ydir * tgui->accel.pitch);
|
||||
@@ -1358,6 +1382,7 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui)
|
||||
if (tgui->accel.use_src)
|
||||
return;
|
||||
}
|
||||
count--;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1425,12 +1450,12 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui)
|
||||
READ(tgui->accel.dst, dst_dat);
|
||||
|
||||
pat_dat = pattern_data[((tgui->accel.pat_y & 7)*8) + (tgui->accel.pat_x & 7)];
|
||||
|
||||
|
||||
if (tgui->accel.bpp == 0)
|
||||
pat_dat &= 0xff;
|
||||
else if (tgui->accel.bpp == 1)
|
||||
pat_dat &= 0xffff;
|
||||
|
||||
|
||||
if (!(tgui->accel.flags & TGUI_TRANSENA) || (src_dat != trans_col)) {
|
||||
MIX();
|
||||
|
||||
@@ -1479,7 +1504,7 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui)
|
||||
READ(tgui->accel.dst, dst_dat);
|
||||
|
||||
pat_dat = pattern_data[((tgui->accel.pat_y & 7)*8) + (tgui->accel.pat_x & 7)];
|
||||
|
||||
|
||||
if (tgui->accel.bpp == 0)
|
||||
pat_dat &= 0xff;
|
||||
else if (tgui->accel.bpp == 1)
|
||||
@@ -1545,7 +1570,7 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui)
|
||||
tgui->accel.right >>= 1;
|
||||
} else if (tgui->accel.bpp == 3) {
|
||||
tgui->accel.left >>= 2;
|
||||
tgui->accel.right >>= 2;
|
||||
tgui->accel.right >>= 2;
|
||||
}
|
||||
|
||||
err = tgui->accel.size_x + tgui->accel.src_y;
|
||||
@@ -1867,19 +1892,31 @@ tgui_accel_out(uint16_t addr, uint8_t val, void *p)
|
||||
static void
|
||||
tgui_accel_out_w(uint16_t addr, uint16_t val, void *p)
|
||||
{
|
||||
tgui_t *tgui = (tgui_t *)p;
|
||||
tgui_accel_out(addr, val, tgui);
|
||||
tgui_accel_out(addr + 1, val >> 8, tgui);
|
||||
tgui_t *tgui = (tgui_t *)p;
|
||||
tgui_accel_out(addr, val, tgui);
|
||||
tgui_accel_out(addr + 1, val >> 8, tgui);
|
||||
}
|
||||
|
||||
static void
|
||||
tgui_accel_out_l(uint16_t addr, uint32_t val, void *p)
|
||||
{
|
||||
tgui_t *tgui = (tgui_t *)p;
|
||||
tgui_t *tgui = (tgui_t *)p;
|
||||
|
||||
switch (addr) {
|
||||
case 0x2124: /*Long version of Command and ROP together*/
|
||||
tgui->accel.command = val & 0xff;
|
||||
tgui->accel.rop = val >> 24;
|
||||
tgui->accel.use_src = (tgui->accel.rop & 0x33) ^ ((tgui->accel.rop >> 2) & 0x33);
|
||||
tgui_accel_command(-1, 0, tgui);
|
||||
break;
|
||||
|
||||
default:
|
||||
tgui_accel_out(addr, val, tgui);
|
||||
tgui_accel_out(addr + 1, val >> 8, tgui);
|
||||
tgui_accel_out(addr + 2, val >> 16, tgui);
|
||||
tgui_accel_out(addr + 3, val >> 24, tgui);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
@@ -2318,7 +2355,8 @@ tgui_accel_write(uint32_t addr, uint8_t val, void *p)
|
||||
static void
|
||||
tgui_accel_write_w(uint32_t addr, uint16_t val, void *p)
|
||||
{
|
||||
tgui_t *tgui = (tgui_t *)p;
|
||||
tgui_t *tgui = (tgui_t *)p;
|
||||
|
||||
tgui_accel_write(addr, val, tgui);
|
||||
tgui_accel_write(addr + 1, val >> 8, tgui);
|
||||
}
|
||||
@@ -2326,9 +2364,29 @@ tgui_accel_write_w(uint32_t addr, uint16_t val, void *p)
|
||||
static void
|
||||
tgui_accel_write_l(uint32_t addr, uint32_t val, void *p)
|
||||
{
|
||||
tgui_t *tgui = (tgui_t *)p;
|
||||
tgui_accel_write_w(addr, val, tgui);
|
||||
tgui_accel_write_w(addr + 2, val >> 16, tgui);
|
||||
tgui_t *tgui = (tgui_t *)p;
|
||||
svga_t *svga = &tgui->svga;
|
||||
|
||||
switch (addr & 0xff) {
|
||||
case 0x24: /*Long version of Command and ROP together*/
|
||||
if ((svga->crtc[0x36] & 0x03) == 0x02) {
|
||||
if ((addr & ~0xff) != 0xbff00)
|
||||
return;
|
||||
} else if ((svga->crtc[0x36] & 0x03) == 0x01) {
|
||||
if ((addr & ~0xff) != 0xb7f00)
|
||||
return;
|
||||
}
|
||||
tgui->accel.command = val & 0xff;
|
||||
tgui->accel.rop = val >> 24;
|
||||
tgui->accel.use_src = ((val >> 24) & 0x33) ^ (((val >> 24) >> 2) & 0x33);
|
||||
tgui_accel_command(-1, 0, tgui);
|
||||
break;
|
||||
|
||||
default:
|
||||
tgui_accel_write_w(addr, val, tgui);
|
||||
tgui_accel_write_w(addr + 2, val >> 16, tgui);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
|
||||
@@ -451,14 +451,10 @@ static void opengl_fail()
|
||||
_endthread();
|
||||
}
|
||||
|
||||
/*
|
||||
static void __stdcall opengl_debugmsg_callback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, const void* userParam)
|
||||
{
|
||||
OutputDebugStringA("OpenGL: ");
|
||||
OutputDebugStringA(message);
|
||||
OutputDebugStringA("\n");
|
||||
pclog("OpenGL: %s\n", message);
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Main OpenGL thread proc.
|
||||
@@ -478,13 +474,19 @@ static void opengl_main(void* param)
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG);
|
||||
//SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG | SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG);
|
||||
|
||||
if (GLAD_GL_ARB_debug_output)
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG | SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG);
|
||||
else
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG);
|
||||
|
||||
window = SDL_CreateWindow("86Box OpenGL Renderer", 0, 0, resize_info.width, resize_info.height, SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS);
|
||||
|
||||
if (window == NULL)
|
||||
{
|
||||
pclog("OpenGL: failed to create OpenGL window.\n");
|
||||
opengl_fail();
|
||||
}
|
||||
|
||||
/* Keep track of certain parameters, only changed in this thread to avoid race conditions */
|
||||
int fullscreen = resize_info.fullscreen, video_width = INIT_WIDTH, video_height = INIT_HEIGHT,
|
||||
@@ -495,7 +497,10 @@ static void opengl_main(void* param)
|
||||
SDL_GetWindowWMInfo(window, &wmi);
|
||||
|
||||
if (wmi.subsystem != SDL_SYSWM_WINDOWS)
|
||||
{
|
||||
pclog("OpenGL: subsystem is not SDL_SYSWM_WINDOWS.\n");
|
||||
opengl_fail();
|
||||
}
|
||||
|
||||
window_hwnd = wmi.info.win.window;
|
||||
|
||||
@@ -507,29 +512,37 @@ static void opengl_main(void* param)
|
||||
SDL_GLContext context = SDL_GL_CreateContext(window);
|
||||
|
||||
if (context == NULL)
|
||||
{
|
||||
pclog("OpenGL: failed to create OpenGL context.\n");
|
||||
opengl_fail();
|
||||
}
|
||||
|
||||
SDL_GL_SetSwapInterval(options.vsync);
|
||||
|
||||
if (!gladLoadGLLoader(SDL_GL_GetProcAddress))
|
||||
{
|
||||
pclog("OpenGL: failed to set OpenGL loader.\n");
|
||||
SDL_GL_DeleteContext(context);
|
||||
opengl_fail();
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
if (GLAD_GL_ARB_debug_output)
|
||||
{
|
||||
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
|
||||
glDebugMessageControlARB(GL_DONT_CARE, GL_DEBUG_TYPE_PERFORMANCE_ARB, GL_DONT_CARE, 0, 0, GL_FALSE);
|
||||
glDebugMessageCallbackARB(opengl_debugmsg_callback, NULL);
|
||||
}
|
||||
*/
|
||||
|
||||
pclog("OpenGL vendor: %s\n", glGetString(GL_VENDOR));
|
||||
pclog("OpenGL renderer: %s\n", glGetString(GL_RENDERER));
|
||||
pclog("OpenGL version: %s\n", glGetString(GL_VERSION));
|
||||
pclog("OpenGL shader language version: %s\n", glGetString(GL_SHADING_LANGUAGE_VERSION));
|
||||
|
||||
gl_identifiers gl = { 0 };
|
||||
|
||||
if (!initialize_glcontext(&gl))
|
||||
{
|
||||
pclog("OpenGL: failed to initialize.\n");
|
||||
finalize_glcontext(&gl);
|
||||
SDL_GL_DeleteContext(context);
|
||||
opengl_fail();
|
||||
|
||||
@@ -63,6 +63,16 @@ void main() {\n\
|
||||
color = texture(texsampler, tex);\n\
|
||||
}\n";
|
||||
|
||||
/**
|
||||
* @brief OpenGL shader program build targets
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
OPENGL_BUILD_TARGET_VERTEX,
|
||||
OPENGL_BUILD_TARGET_FRAGMENT,
|
||||
OPENGL_BUILD_TARGET_LINK
|
||||
} opengl_build_target_t;
|
||||
|
||||
/**
|
||||
* @brief Reads a whole file into a null terminated string.
|
||||
* @param Path Path to the file relative to executable path.
|
||||
@@ -98,11 +108,11 @@ static char* read_file_to_string(const char* path)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int check_status(GLuint id, int is_shader)
|
||||
static int check_status(GLuint id, opengl_build_target_t build_target, const char* shader_path)
|
||||
{
|
||||
GLint status = GL_FALSE;
|
||||
|
||||
if (is_shader)
|
||||
if (build_target != OPENGL_BUILD_TARGET_LINK)
|
||||
glGetShaderiv(id, GL_COMPILE_STATUS, &status);
|
||||
else
|
||||
glGetProgramiv(id, GL_LINK_STATUS, &status);
|
||||
@@ -111,19 +121,37 @@ static int check_status(GLuint id, int is_shader)
|
||||
{
|
||||
int info_log_length;
|
||||
|
||||
if (is_shader)
|
||||
if (build_target != OPENGL_BUILD_TARGET_LINK)
|
||||
glGetShaderiv(id, GL_INFO_LOG_LENGTH, &info_log_length);
|
||||
else
|
||||
glGetProgramiv(id, GL_INFO_LOG_LENGTH, &info_log_length);
|
||||
|
||||
GLchar* info_log_text = (GLchar*)malloc(sizeof(GLchar) * info_log_length);
|
||||
|
||||
if (is_shader)
|
||||
if (build_target != OPENGL_BUILD_TARGET_LINK)
|
||||
glGetShaderInfoLog(id, info_log_length, NULL, info_log_text);
|
||||
else
|
||||
glGetProgramInfoLog(id, info_log_length, NULL, info_log_text);
|
||||
|
||||
/* TODO: error logging */
|
||||
const char* reason = NULL;
|
||||
|
||||
switch (build_target)
|
||||
{
|
||||
case OPENGL_BUILD_TARGET_VERTEX:
|
||||
reason = "compiling vertex shader";
|
||||
break;
|
||||
case OPENGL_BUILD_TARGET_FRAGMENT:
|
||||
reason = "compiling fragment shader";
|
||||
break;
|
||||
case OPENGL_BUILD_TARGET_LINK:
|
||||
reason = "linking shader program";
|
||||
break;
|
||||
}
|
||||
|
||||
/* Shader compilation log can be lengthy, mark begin and end */
|
||||
const char* line = "--------------------";
|
||||
|
||||
pclog("OpenGL: Error when %s in %s:\n%sBEGIN%s\n%s\n%s END %s\n", reason, shader_path, line, line, info_log_text, line, line);
|
||||
|
||||
free(info_log_text);
|
||||
|
||||
@@ -153,11 +181,11 @@ GLuint load_custom_shaders(const char* path)
|
||||
|
||||
glShaderSource(vertex_id, 2, vertex_sources, NULL);
|
||||
glCompileShader(vertex_id);
|
||||
success *= check_status(vertex_id, 1);
|
||||
success *= check_status(vertex_id, OPENGL_BUILD_TARGET_VERTEX, path);
|
||||
|
||||
glShaderSource(fragment_id, 2, fragment_sources, NULL);
|
||||
glCompileShader(fragment_id);
|
||||
success *= check_status(fragment_id, 1);
|
||||
success *= check_status(fragment_id, OPENGL_BUILD_TARGET_FRAGMENT, path);
|
||||
|
||||
free(shader);
|
||||
|
||||
@@ -170,7 +198,7 @@ GLuint load_custom_shaders(const char* path)
|
||||
glAttachShader(prog_id, vertex_id);
|
||||
glAttachShader(prog_id, fragment_id);
|
||||
glLinkProgram(prog_id);
|
||||
check_status(prog_id, 0);
|
||||
check_status(prog_id, OPENGL_BUILD_TARGET_LINK, path);
|
||||
|
||||
glDetachShader(prog_id, vertex_id);
|
||||
glDetachShader(prog_id, fragment_id);
|
||||
|
||||
Reference in New Issue
Block a user