static void event_init_autosave(void) { unsigned i; settings_t *settings = config_get_ptr(); global_t *global = global_get_ptr(); if (settings->autosave_interval < 1 || !global->savefiles) return; if (!(global->autosave = (autosave_t**)calloc(global->savefiles->size, sizeof(*global->autosave)))) return; global->num_autosave = global->savefiles->size; for (i = 0; i < global->savefiles->size; i++) { const char *path = global->savefiles->elems[i].data; unsigned type = global->savefiles->elems[i].attr.i; if (pretro_get_memory_size(type) <= 0) continue; global->autosave[i] = autosave_new(path, pretro_get_memory_data(type), pretro_get_memory_size(type), settings->autosave_interval); if (!global->autosave[i]) RARCH_WARN(RETRO_LOG_INIT_AUTOSAVE_FAILED); } }
/** * load_ram_file: * @path : path of RAM state that will be loaded from. * @type : type of memory * * Load a RAM state from disk to memory. */ void load_ram_file(const char *path, int type) { ssize_t rc; bool ret = false; void *buf = NULL; size_t size = pretro_get_memory_size(type); void *data = pretro_get_memory_data(type); if (size == 0 || !data) return; ret = read_file(path, &buf, &rc); if (!ret) return; if (rc > 0) { if (rc > (ssize_t)size) { RARCH_WARN("SRAM is larger than implementation expects, doing partial load (truncating %u %s %s %u).\n", (unsigned)rc, msg_hash_to_str(MSG_BYTES), msg_hash_to_str(MSG_TO), (unsigned)size); rc = size; } memcpy(data, buf, rc); } if (buf) free(buf); }
bool d3d_init_imports(void *data) { d3d_video_t *d3d = (d3d_video_t*)data; if (!d3d->shader.variables) return true; state_tracker_info tracker_info = {0}; tracker_info.wram = (uint8_t*)pretro_get_memory_data(RETRO_MEMORY_SYSTEM_RAM); tracker_info.info = d3d->shader.variable; tracker_info.info_elem = d3d->shader.variables; #ifdef HAVE_PYTHON if (*d3d->shader.script_path) { tracker_info.script = d3d->shader.script_path; tracker_info.script_is_file = true; } tracker_info.script_class = *d3d->shader.script_class ? d3d->shader.script_class : NULL; #endif state_tracker_t *state_tracker = state_tracker_init(&tracker_info); if (!state_tracker) { RARCH_ERR("Failed to initialize state tracker.\n"); return false; } renderchain_add_state_tracker(d3d->chain, state_tracker); return true; }
static bool get_info(netplay_t *handle) { uint32_t header[3]; if (!recv_all(handle->fd, header, sizeof(header))) { RARCH_ERR("Failed to receive header from client.\n"); return false; } if (g_extern.cart_crc != ntohl(header[0])) { RARCH_ERR("Cart CRC32s differ. Cannot use different games.\n"); return false; } if (implementation_magic_value() != ntohl(header[1])) { RARCH_ERR("Implementations differ, make sure you're using exact same libretro implementations and RetroArch version.\n"); return false; } if (pretro_get_memory_size(RETRO_MEMORY_SAVE_RAM) != ntohl(header[2])) { RARCH_ERR("Cartridge SRAM sizes do not correspond.\n"); return false; } if (!get_nickname(handle, handle->fd)) { RARCH_ERR("Failed to get nickname from client.\n"); return false; } // Send SRAM data to our Player 2. const void *sram = pretro_get_memory_data(RETRO_MEMORY_SAVE_RAM); unsigned sram_size = pretro_get_memory_size(RETRO_MEMORY_SAVE_RAM); if (!send_all(handle->fd, sram, sram_size)) { RARCH_ERR("Failed to send SRAM data to client.\n"); return false; } if (!send_nickname(handle, handle->fd)) { RARCH_ERR("Failed to send nickname to client.\n"); return false; } #ifndef HAVE_SOCKET_LEGACY log_connection(&handle->other_addr, 0, handle->other_nick); #endif return true; }
static bool gl_cg_load_imports(cg_shader_data_t *cg) { unsigned i; struct state_tracker_info tracker_info = {0}; if (!cg->cg_shader->variables) return true; for (i = 0; i < cg->cg_shader->variables; i++) { unsigned memtype; switch (cg->cg_shader->variable[i].ram_type) { case RARCH_STATE_WRAM: memtype = RETRO_MEMORY_SYSTEM_RAM; break; default: memtype = -1u; } if ((memtype != -1u) && (cg->cg_shader->variable[i].addr >= pretro_get_memory_size(memtype))) { RARCH_ERR("Address out of bounds.\n"); return false; } } tracker_info.wram = (uint8_t*) pretro_get_memory_data(RETRO_MEMORY_SYSTEM_RAM); tracker_info.info = cg->cg_shader->variable; tracker_info.info_elem = cg->cg_shader->variables; #ifdef HAVE_PYTHON if (*cg->cg_shader->script_path) { tracker_info.script = cg->cg_shader->script_path; tracker_info.script_is_file = true; } tracker_info.script_class = *cg->cg_shader->script_class ? cg->cg_shader->script_class : NULL; #endif cg->state_tracker = state_tracker_init(&tracker_info); if (!cg->state_tracker) RARCH_WARN("Failed to initialize state tracker.\n"); return true; }
void load_ram_file(const char *path, int type) { size_t size = pretro_get_memory_size(type); void *data = pretro_get_memory_data(type); if (size == 0 || !data) return; void *buf = NULL; ssize_t rc = read_file(path, &buf); if (rc > 0 && rc <= (ssize_t)size) memcpy(data, buf, rc); free(buf); }
void save_ram_file(const char *path, int type) { size_t size = pretro_get_memory_size(type); void *data = pretro_get_memory_data(type); if (data && size > 0) { if (!dump_to_file(path, data, size)) { RARCH_ERR("Failed to save SRAM.\n"); RARCH_WARN("Attempting to recover ...\n"); dump_to_file_desperate(data, size, type); } } }
void save_ram_file(const char *path, int type) { size_t size = pretro_get_memory_size(type); void *data = pretro_get_memory_data(type); if (data && size > 0) { if (!write_file(path, data, size)) { RARCH_ERR("Failed to save SRAM.\n"); RARCH_WARN("Attempting to recover ...\n"); dump_to_file_desperate(data, size, type); } else RARCH_LOG("Saved successfully to \"%s\".\n", path); } }
static bool send_info(netplay_t *handle) { uint32_t header[3] = { htonl(g_extern.cart_crc), htonl(implementation_magic_value()), htonl(pretro_get_memory_size(RETRO_MEMORY_SAVE_RAM)) }; if (!send_all(handle->fd, header, sizeof(header))) return false; if (!send_nickname(handle, handle->fd)) { RARCH_ERR("Failed to send nick to host.\n"); return false; } // Get SRAM data from Player 1. void *sram = pretro_get_memory_data(RETRO_MEMORY_SAVE_RAM); unsigned sram_size = pretro_get_memory_size(RETRO_MEMORY_SAVE_RAM); if (!recv_all(handle->fd, sram, sram_size)) { RARCH_ERR("Failed to receive SRAM data from host.\n"); return false; } if (!get_nickname(handle, handle->fd)) { RARCH_ERR("Failed to receive nick from host.\n"); return false; } char msg[512]; snprintf(msg, sizeof(msg), "Connected to: \"%s\"", handle->other_nick); RARCH_LOG("%s\n", msg); msg_queue_push(g_extern.msg_queue, msg, 1, 180); return true; }
void load_ram_file(const char *path, int type) { size_t size = pretro_get_memory_size(type); void *data = pretro_get_memory_data(type); if (size == 0 || !data) return; void *buf = NULL; ssize_t rc = read_file(path, &buf); if (rc > 0) { if (rc > (ssize_t)size) { RARCH_WARN("SRAM is larger than implementation expects, doing partial load (truncating %u bytes to %u).\n", (unsigned)rc, (unsigned)size); rc = size; } memcpy(data, buf, rc); } free(buf); }
/** * save_ram_file: * @path : path of RAM state that shall be written to. * @type : type of memory * * Save a RAM state from memory to disk. * * In case the file could not be written to, a fallback function * 'dump_to_file_desperate' will be called. */ void save_ram_file(const char *path, int type) { size_t size = pretro_get_memory_size(type); void *data = pretro_get_memory_data(type); if (!data) return; if (size == 0) return; if (!retro_write_file(path, data, size)) { RARCH_ERR("%s.\n", msg_hash_to_str(MSG_FAILED_TO_SAVE_SRAM)); RARCH_WARN("Attempting to recover ...\n"); dump_to_file_desperate(data, size, type); return; } RARCH_LOG("%s \"%s\".\n", msg_hash_to_str(MSG_SAVED_SUCCESSFULLY_TO), path); }
static PyObject* py_read_vram(PyObject *self, PyObject *args) { (void)self; const uint8_t *data = (const uint8_t*)pretro_get_memory_data(RETRO_MEMORY_VIDEO_RAM); if (!data) { Py_INCREF(Py_None); return Py_None; } size_t max = pretro_get_memory_size(RETRO_MEMORY_VIDEO_RAM); unsigned addr; if (!PyArg_ParseTuple(args, "I", &addr)) return NULL; if (addr >= max) { Py_INCREF(Py_None); return Py_None; } return PyLong_FromLong(data[addr]); }
static bool gl_glsl_init(void *data, const char *path) { unsigned i; (void)data; #ifndef HAVE_OPENGLES2 RARCH_LOG("Checking GLSL shader support ...\n"); bool shader_support = glCreateProgram && glUseProgram && glCreateShader && glDeleteShader && glShaderSource && glCompileShader && glAttachShader && glDetachShader && glLinkProgram && glGetUniformLocation && glUniform1i && glUniform1f && glUniform2fv && glUniform4fv && glUniformMatrix4fv && glGetShaderiv && glGetShaderInfoLog && glGetProgramiv && glGetProgramInfoLog && glDeleteProgram && glGetAttachedShaders && glGetAttribLocation && glEnableVertexAttribArray && glDisableVertexAttribArray && glVertexAttribPointer && glGenBuffers && glBufferData && glDeleteBuffers && glBindBuffer; if (!shader_support) { RARCH_ERR("GLSL shaders aren't supported by your OpenGL driver.\n"); return false; } #endif glsl_shader = (struct gfx_shader*)calloc(1, sizeof(*glsl_shader)); if (!glsl_shader) return false; if (path) { bool ret; if (strcmp(path_get_extension(path), "glsl") == 0) { strlcpy(glsl_shader->pass[0].source.cg, path, sizeof(glsl_shader->pass[0].source.cg)); glsl_shader->passes = 1; glsl_shader->modern = true; ret = true; } else if (strcmp(path_get_extension(path), "glslp") == 0) { config_file_t *conf = config_file_new(path); if (conf) { ret = gfx_shader_read_conf_cgp(conf, glsl_shader); glsl_shader->modern = true; config_file_free(conf); } else ret = false; } else ret = gfx_shader_read_xml(path, glsl_shader); if (!ret) { RARCH_ERR("[GL]: Failed to parse GLSL shader.\n"); return false; } } else { RARCH_WARN("[GL]: Stock GLSL shaders will be used.\n"); glsl_shader->passes = 1; glsl_shader->pass[0].source.xml.vertex = strdup(glsl_core ? stock_vertex_core : stock_vertex_modern); glsl_shader->pass[0].source.xml.fragment = strdup(glsl_core ? stock_fragment_core : stock_fragment_modern); glsl_shader->modern = true; } gfx_shader_resolve_relative(glsl_shader, path); const char *stock_vertex = glsl_shader->modern ? stock_vertex_modern : stock_vertex_legacy; const char *stock_fragment = glsl_shader->modern ? stock_fragment_modern : stock_fragment_legacy; if (glsl_core) { stock_vertex = stock_vertex_core; stock_fragment = stock_fragment_core; } #ifdef HAVE_OPENGLES2 if (!glsl_shader->modern) { RARCH_ERR("[GL]: GLES context is used, but shader is not modern. Cannot use it.\n"); goto error; } #else if (glsl_core && !glsl_shader->modern) { RARCH_ERR("[GL]: GL core context is used, but shader is not core compatible. Cannot use it.\n"); goto error; } #endif if (!(gl_program[0] = compile_program(stock_vertex, stock_fragment, 0))) { RARCH_ERR("GLSL stock programs failed to compile.\n"); goto error; } if (!compile_programs(&gl_program[1])) goto error; if (!gl_load_luts(glsl_shader, gl_teximage)) { RARCH_ERR("[GL]: Failed to load LUTs.\n"); goto error; } for (i = 0; i <= glsl_shader->passes; i++) find_uniforms(i, gl_program[i], &gl_uniforms[i]); #ifdef GLSL_DEBUG if (!gl_check_error()) RARCH_WARN("Detected GL error in GLSL.\n"); #endif if (glsl_shader->variables) { struct state_tracker_info info = {0}; info.wram = (uint8_t*)pretro_get_memory_data(RETRO_MEMORY_SYSTEM_RAM); info.info = glsl_shader->variable; info.info_elem = glsl_shader->variables; #ifdef HAVE_PYTHON info.script = glsl_shader->script; info.script_class = *glsl_shader->script_class ? glsl_shader->script_class : NULL; #endif gl_state_tracker = state_tracker_init(&info); if (!gl_state_tracker) RARCH_WARN("Failed to init state tracker.\n"); } glsl_enable = true; gl_program[glsl_shader->passes + 1] = gl_program[0]; gl_uniforms[glsl_shader->passes + 1] = gl_uniforms[0]; if (glsl_shader->modern) { gl_program[GL_SHADER_STOCK_BLEND] = compile_program(glsl_core ? stock_vertex_core_blend : stock_vertex_modern_blend, glsl_core ? stock_fragment_core_blend : stock_fragment_modern_blend, GL_SHADER_STOCK_BLEND); find_uniforms(0, gl_program[GL_SHADER_STOCK_BLEND], &gl_uniforms[GL_SHADER_STOCK_BLEND]); } else { gl_program[GL_SHADER_STOCK_BLEND] = gl_program[0]; gl_uniforms[GL_SHADER_STOCK_BLEND] = gl_uniforms[0]; } gl_glsl_reset_attrib(); for (i = 0; i < GFX_MAX_SHADERS; i++) { glGenBuffers(1, &glsl_vbo[i].vbo_primary); glGenBuffers(1, &glsl_vbo[i].vbo_secondary); } return true; error: gl_glsl_deinit(); return false; }
static bool gl_glsl_init(const char *path) { #if !defined(HAVE_OPENGLES2) && !defined(HAVE_OPENGL_MODERN) && !defined(__APPLE__) // Load shader functions. LOAD_GL_SYM(CreateProgram); LOAD_GL_SYM(UseProgram); LOAD_GL_SYM(CreateShader); LOAD_GL_SYM(DeleteShader); LOAD_GL_SYM(ShaderSource); LOAD_GL_SYM(CompileShader); LOAD_GL_SYM(AttachShader); LOAD_GL_SYM(DetachShader); LOAD_GL_SYM(LinkProgram); LOAD_GL_SYM(GetUniformLocation); LOAD_GL_SYM(Uniform1i); LOAD_GL_SYM(Uniform1f); LOAD_GL_SYM(Uniform2fv); LOAD_GL_SYM(Uniform4fv); LOAD_GL_SYM(UniformMatrix4fv); LOAD_GL_SYM(GetShaderiv); LOAD_GL_SYM(GetShaderInfoLog); LOAD_GL_SYM(GetProgramiv); LOAD_GL_SYM(GetProgramInfoLog); LOAD_GL_SYM(DeleteProgram); LOAD_GL_SYM(GetAttachedShaders); LOAD_GL_SYM(GetAttribLocation); LOAD_GL_SYM(EnableVertexAttribArray); LOAD_GL_SYM(DisableVertexAttribArray); LOAD_GL_SYM(VertexAttribPointer); RARCH_LOG("Checking GLSL shader support ...\n"); bool shader_support = pglCreateProgram && pglUseProgram && pglCreateShader && pglDeleteShader && pglShaderSource && pglCompileShader && pglAttachShader && pglDetachShader && pglLinkProgram && pglGetUniformLocation && pglUniform1i && pglUniform1f && pglUniform2fv && pglUniform4fv && pglUniformMatrix4fv && pglGetShaderiv && pglGetShaderInfoLog && pglGetProgramiv && pglGetProgramInfoLog && pglDeleteProgram && pglGetAttachedShaders && pglGetAttribLocation && pglEnableVertexAttribArray && pglDisableVertexAttribArray && pglVertexAttribPointer; if (!shader_support) { RARCH_ERR("GLSL shaders aren't supported by your OpenGL driver.\n"); return false; } #endif glsl_shader = (struct gfx_shader*)calloc(1, sizeof(*glsl_shader)); if (!glsl_shader) return false; if (path) { bool ret; if (strcmp(path_get_extension(path), "glsl") == 0) { strlcpy(glsl_shader->pass[0].source.cg, path, sizeof(glsl_shader->pass[0].source.cg)); glsl_shader->passes = 1; glsl_shader->modern = true; ret = true; } else if (strcmp(path_get_extension(path), "glslp") == 0) { config_file_t *conf = config_file_new(path); if (conf) { ret = gfx_shader_read_conf_cgp(conf, glsl_shader); glsl_shader->modern = true; config_file_free(conf); } else ret = false; } else ret = gfx_shader_read_xml(path, glsl_shader); if (!ret) { RARCH_ERR("[GL]: Failed to parse GLSL shader.\n"); return false; } } else { RARCH_WARN("[GL]: Stock GLSL shaders will be used.\n"); glsl_shader->passes = 1; glsl_shader->pass[0].source.xml.vertex = strdup(stock_vertex_modern); glsl_shader->pass[0].source.xml.fragment = strdup(stock_fragment_modern); glsl_shader->modern = true; } gfx_shader_resolve_relative(glsl_shader, path); #ifdef HAVE_OPENGLES2 if (!glsl_shader->modern) { RARCH_ERR("[GL]: GLES context is used, but shader is not modern. Cannot use it.\n"); return false; } #endif const char *stock_vertex = glsl_shader->modern ? stock_vertex_modern : stock_vertex_legacy; const char *stock_fragment = glsl_shader->modern ? stock_fragment_modern : stock_fragment_legacy; if (!(gl_program[0] = compile_program(stock_vertex, stock_fragment, 0))) { RARCH_ERR("GLSL stock programs failed to compile.\n"); gl_glsl_free_shader(); return false; } if (!compile_programs(&gl_program[1])) { gl_glsl_free_shader(); return false; } if (!load_luts()) { RARCH_ERR("[GL]: Failed to load LUTs.\n"); gl_glsl_free_shader(); return false; } for (unsigned i = 0; i <= glsl_shader->passes; i++) find_uniforms(gl_program[i], &gl_uniforms[i]); #ifdef GLSL_DEBUG if (!gl_check_error()) RARCH_WARN("Detected GL error in GLSL.\n"); #endif if (glsl_shader->variables) { struct state_tracker_info info = {0}; info.wram = (uint8_t*)pretro_get_memory_data(RETRO_MEMORY_SYSTEM_RAM); info.info = glsl_shader->variable; info.info_elem = glsl_shader->variables; #ifdef HAVE_PYTHON info.script = glsl_shader->script; info.script_class = *glsl_shader->script_class ? glsl_shader->script_class : NULL; #endif gl_state_tracker = state_tracker_init(&info); if (!gl_state_tracker) RARCH_WARN("Failed to init state tracker.\n"); } glsl_enable = true; gl_program[glsl_shader->passes + 1] = gl_program[0]; gl_uniforms[glsl_shader->passes + 1] = gl_uniforms[0]; if (glsl_shader->modern) { gl_program[GL_SHADER_STOCK_BLEND] = compile_program(stock_vertex_modern_blend, stock_fragment_modern_blend, GL_SHADER_STOCK_BLEND); find_uniforms(gl_program[GL_SHADER_STOCK_BLEND], &gl_uniforms[GL_SHADER_STOCK_BLEND]); } else { gl_program[GL_SHADER_STOCK_BLEND] = gl_program[0]; gl_uniforms[GL_SHADER_STOCK_BLEND] = gl_uniforms[0]; } gl_glsl_reset_attrib(); return true; }
bool load_state(const char *path) { unsigned i; void *buf = NULL; ssize_t size = read_file(path, &buf); RARCH_LOG("Loading state: \"%s\".\n", path); if (size < 0) { RARCH_ERR("Failed to load state from \"%s\".\n", path); return false; } bool ret = true; RARCH_LOG("State size: %u bytes.\n", (unsigned)size); struct sram_block *blocks = NULL; unsigned num_blocks = 0; if (g_settings.block_sram_overwrite && g_extern.savefiles && g_extern.savefiles->size) { RARCH_LOG("Blocking SRAM overwrite.\n"); blocks = (struct sram_block*) calloc(g_extern.savefiles->size, sizeof(*blocks)); if (blocks) { num_blocks = g_extern.savefiles->size; for (i = 0; i < num_blocks; i++) blocks[i].type = g_extern.savefiles->elems[i].attr.i; } } for (i = 0; i < num_blocks; i++) blocks[i].size = pretro_get_memory_size(blocks[i].type); for (i = 0; i < num_blocks; i++) if (blocks[i].size) blocks[i].data = malloc(blocks[i].size); /* Backup current SRAM which is overwritten by unserialize. */ for (i = 0; i < num_blocks; i++) { if (blocks[i].data) { const void *ptr = pretro_get_memory_data(blocks[i].type); if (ptr) memcpy(blocks[i].data, ptr, blocks[i].size); } } ret = pretro_unserialize(buf, size); /* Flush back. */ for (i = 0; i < num_blocks; i++) { if (blocks[i].data) { void *ptr = pretro_get_memory_data(blocks[i].type); if (ptr) memcpy(ptr, blocks[i].data, blocks[i].size); } } for (i = 0; i < num_blocks; i++) free(blocks[i].data); free(blocks); return ret; }
static bool gl_glsl_init(void *data, const char *path) { unsigned i; config_file_t *conf = NULL; glsl_shader_data_t *glsl = NULL; const char *stock_vertex = NULL; const char *stock_fragment = NULL; driver_t *driver = driver_get_ptr(); (void)data; glsl = (glsl_shader_data_t*)calloc(1, sizeof(glsl_shader_data_t)); if (!glsl) return false; #ifndef HAVE_OPENGLES2 RARCH_LOG("Checking GLSL shader support ...\n"); bool shader_support = glCreateProgram && glUseProgram && glCreateShader && glDeleteShader && glShaderSource && glCompileShader && glAttachShader && glDetachShader && glLinkProgram && glGetUniformLocation && glUniform1i && glUniform1f && glUniform2fv && glUniform4fv && glUniformMatrix4fv && glGetShaderiv && glGetShaderInfoLog && glGetProgramiv && glGetProgramInfoLog && glDeleteProgram && glGetAttachedShaders && glGetAttribLocation && glEnableVertexAttribArray && glDisableVertexAttribArray && glVertexAttribPointer && glGenBuffers && glBufferData && glDeleteBuffers && glBindBuffer; if (!shader_support) { RARCH_ERR("GLSL shaders aren't supported by your OpenGL driver.\n"); free(glsl); return false; } #endif glsl->shader = (struct video_shader*)calloc(1, sizeof(*glsl->shader)); if (!glsl->shader) { free(glsl); return false; } if (path) { bool ret; const char *path_ext = path_get_extension(path); if (!strcmp(path_ext, "glsl")) { strlcpy(glsl->shader->pass[0].source.path, path, sizeof(glsl->shader->pass[0].source.path)); glsl->shader->passes = 1; glsl->shader->modern = true; ret = true; } else if (!strcmp(path_ext, "glslp")) { conf = config_file_new(path); if (conf) { ret = video_shader_read_conf_cgp(conf, glsl->shader); glsl->shader->modern = true; } else ret = false; } else ret = false; if (!ret) { RARCH_ERR("[GL]: Failed to parse GLSL shader.\n"); free(glsl->shader); free(glsl); return false; } } else { RARCH_WARN("[GL]: Stock GLSL shaders will be used.\n"); glsl->shader->passes = 1; glsl->shader->pass[0].source.string.vertex = strdup(glsl_core ? stock_vertex_core : stock_vertex_modern); glsl->shader->pass[0].source.string.fragment = strdup(glsl_core ? stock_fragment_core : stock_fragment_modern); glsl->shader->modern = true; } video_shader_resolve_relative(glsl->shader, path); video_shader_resolve_parameters(conf, glsl->shader); if (conf) { config_file_free(conf); conf = NULL; } stock_vertex = (glsl->shader->modern) ? stock_vertex_modern : stock_vertex_legacy; stock_fragment = (glsl->shader->modern) ? stock_fragment_modern : stock_fragment_legacy; if (glsl_core) { stock_vertex = stock_vertex_core; stock_fragment = stock_fragment_core; } #ifdef HAVE_OPENGLES2 if (!glsl->shader->modern) { RARCH_ERR("[GL]: GLES context is used, but shader is not modern. Cannot use it.\n"); goto error; } #else if (glsl_core && !glsl->shader->modern) { RARCH_ERR("[GL]: GL core context is used, but shader is not core compatible. Cannot use it.\n"); goto error; } #endif /* Find all aliases we use in our GLSLP and add #defines for them so * that a shader can choose a fallback if we are not using a preset. */ *glsl->glsl_alias_define = '\0'; for (i = 0; i < glsl->shader->passes; i++) { if (*glsl->shader->pass[i].alias) { char define[128] = {0}; snprintf(define, sizeof(define), "#define %s_ALIAS\n", glsl->shader->pass[i].alias); strlcat(glsl->glsl_alias_define, define, sizeof(glsl->glsl_alias_define)); } } if (!(glsl->gl_program[0] = compile_program(glsl, stock_vertex, stock_fragment, 0))) { RARCH_ERR("GLSL stock programs failed to compile.\n"); goto error; } if (!compile_programs(glsl, &glsl->gl_program[1])) goto error; if (!gl_load_luts(glsl->shader, glsl->gl_teximage)) { RARCH_ERR("[GL]: Failed to load LUTs.\n"); goto error; } for (i = 0; i <= glsl->shader->passes; i++) find_uniforms(glsl, i, glsl->gl_program[i], &glsl->gl_uniforms[i]); #ifdef GLSL_DEBUG if (!gl_check_error()) RARCH_WARN("Detected GL error in GLSL.\n"); #endif if (glsl->shader->variables) { struct state_tracker_info info = {0}; info.wram = (uint8_t*)pretro_get_memory_data(RETRO_MEMORY_SYSTEM_RAM); info.info = glsl->shader->variable; info.info_elem = glsl->shader->variables; #ifdef HAVE_PYTHON info.script = glsl->shader->script; info.script_class = *glsl->shader->script_class ? glsl->shader->script_class : NULL; #endif glsl->gl_state_tracker = state_tracker_init(&info); if (!glsl->gl_state_tracker) RARCH_WARN("Failed to init state tracker.\n"); } glsl->gl_program[glsl->shader->passes + 1] = glsl->gl_program[0]; glsl->gl_uniforms[glsl->shader->passes + 1] = glsl->gl_uniforms[0]; if (glsl->shader->modern) { glsl->gl_program[GL_SHADER_STOCK_BLEND] = compile_program( glsl, glsl_core ? stock_vertex_core_blend : stock_vertex_modern_blend, glsl_core ? stock_fragment_core_blend : stock_fragment_modern_blend, GL_SHADER_STOCK_BLEND); find_uniforms(glsl, 0, glsl->gl_program[GL_SHADER_STOCK_BLEND], &glsl->gl_uniforms[GL_SHADER_STOCK_BLEND]); } else { glsl->gl_program [GL_SHADER_STOCK_BLEND] = glsl->gl_program[0]; glsl->gl_uniforms[GL_SHADER_STOCK_BLEND] = glsl->gl_uniforms[0]; } gl_glsl_reset_attrib(glsl); for (i = 0; i < GFX_MAX_SHADERS; i++) { glGenBuffers(1, &glsl->glsl_vbo[i].vbo_primary); glGenBuffers(1, &glsl->glsl_vbo[i].vbo_secondary); } driver->video_shader_data = glsl; return true; error: gl_glsl_destroy_resources(glsl); if (glsl) free(glsl); return false; }
bool gl_glsl_init(const char *path) { #ifndef __APPLE__ // Load shader functions. LOAD_GL_SYM(CreateProgram); LOAD_GL_SYM(UseProgram); LOAD_GL_SYM(CreateShader); LOAD_GL_SYM(DeleteShader); LOAD_GL_SYM(ShaderSource); LOAD_GL_SYM(CompileShader); LOAD_GL_SYM(AttachShader); LOAD_GL_SYM(DetachShader); LOAD_GL_SYM(LinkProgram); LOAD_GL_SYM(GetUniformLocation); LOAD_GL_SYM(Uniform1i); LOAD_GL_SYM(Uniform1f); LOAD_GL_SYM(Uniform2fv); LOAD_GL_SYM(Uniform4fv); LOAD_GL_SYM(GetShaderiv); LOAD_GL_SYM(GetShaderInfoLog); LOAD_GL_SYM(GetProgramiv); LOAD_GL_SYM(GetProgramInfoLog); LOAD_GL_SYM(DeleteProgram); LOAD_GL_SYM(GetAttachedShaders); LOAD_GL_SYM(GetAttribLocation); LOAD_GL_SYM(EnableVertexAttribArray); LOAD_GL_SYM(DisableVertexAttribArray); LOAD_GL_SYM(VertexAttribPointer); #endif RARCH_LOG("Checking GLSL shader support ...\n"); #ifdef __APPLE__ const bool shader_support = true; #else bool shader_support = pglCreateProgram && pglUseProgram && pglCreateShader && pglDeleteShader && pglShaderSource && pglCompileShader && pglAttachShader && pglDetachShader && pglLinkProgram && pglGetUniformLocation && pglUniform1i && pglUniform1f && pglUniform2fv && pglUniform4fv && pglGetShaderiv && pglGetShaderInfoLog && pglGetProgramiv && pglGetProgramInfoLog && pglDeleteProgram && pglGetAttachedShaders && pglGetAttribLocation && pglEnableVertexAttribArray && pglDisableVertexAttribArray && pglVertexAttribPointer; #endif if (!shader_support) { RARCH_ERR("GLSL shaders aren't supported by your OpenGL driver.\n"); return false; } struct shader_program stock_prog = {0}; stock_prog.vertex = strdup(stock_vertex); stock_prog.fragment = strdup(stock_fragment); if (!compile_programs(&gl_program[0], &stock_prog, 1)) return false; struct shader_program progs[MAX_PROGRAMS]; unsigned num_progs = get_xml_shaders(path, progs, MAX_PROGRAMS - 1); if (num_progs == 0) { RARCH_ERR("Couldn't find any valid shaders in XML file.\n"); return false; } for (unsigned i = 0; i < num_progs; i++) { gl_filter_type[i + 1] = progs[i].filter; gl_scale[i + 1].type_x = progs[i].type_x; gl_scale[i + 1].type_y = progs[i].type_y; gl_scale[i + 1].scale_x = progs[i].scale_x; gl_scale[i + 1].scale_y = progs[i].scale_y; gl_scale[i + 1].abs_x = progs[i].abs_x; gl_scale[i + 1].abs_y = progs[i].abs_y; gl_scale[i + 1].valid = progs[i].valid_scale; } if (!compile_programs(&gl_program[1], progs, num_progs)) return false; // RetroArch custom two-pass with two different files. if (num_progs == 1 && *g_settings.video.second_pass_shader && g_settings.video.render_to_texture) { unsigned secondary_progs = get_xml_shaders(g_settings.video.second_pass_shader, progs, 1); if (secondary_progs == 1) { compile_programs(&gl_program[2], progs, 1); num_progs++; } else { RARCH_ERR("Did not find valid shader in secondary shader file.\n"); return false; } } //if (!gl_check_error()) // RARCH_WARN("Detected GL error.\n"); if (gl_tracker_info_cnt > 0) { struct state_tracker_info info = {0}; info.wram = (uint8_t*)pretro_get_memory_data(RETRO_MEMORY_SYSTEM_RAM); info.info = gl_tracker_info; info.info_elem = gl_tracker_info_cnt; #ifdef HAVE_PYTHON if (*gl_tracker_script) info.script = gl_tracker_script; else if (gl_script_program) info.script = (const char*)gl_script_program; else info.script = NULL; info.script_class = *gl_tracker_script_class ? gl_tracker_script_class : NULL; info.script_is_file = *gl_tracker_script; #endif gl_state_tracker = state_tracker_init(&info); if (!gl_state_tracker) RARCH_WARN("Failed to init state tracker.\n"); } glsl_enable = true; gl_num_programs = num_progs; gl_program[gl_num_programs + 1] = gl_program[0]; gl_glsl_reset_attrib(); return true; }
/** * load_state: * @path : path that state will be loaded from. * * Load a state from disk to memory. * * Returns: true if successful, false otherwise. **/ bool load_state(const char *path) { unsigned i; ssize_t size; unsigned num_blocks = 0; void *buf = NULL; struct sram_block *blocks = NULL; settings_t *settings = config_get_ptr(); global_t *global = global_get_ptr(); bool ret = read_file(path, &buf, &size); RARCH_LOG("%s: \"%s\".\n", msg_hash_to_str(MSG_LOADING_STATE), path); if (!ret || size < 0) { RARCH_ERR("%s \"%s\".\n", msg_hash_to_str(MSG_FAILED_TO_LOAD_STATE), path); return false; } RARCH_LOG("%s: %u %s.\n", msg_hash_to_str(MSG_STATE_SIZE), (unsigned)size, msg_hash_to_str(MSG_BYTES)); if (settings->block_sram_overwrite && global->savefiles && global->savefiles->size) { RARCH_LOG("%s.\n", msg_hash_to_str(MSG_BLOCKING_SRAM_OVERWRITE)); blocks = (struct sram_block*) calloc(global->savefiles->size, sizeof(*blocks)); if (blocks) { num_blocks = global->savefiles->size; for (i = 0; i < num_blocks; i++) blocks[i].type = global->savefiles->elems[i].attr.i; } } for (i = 0; i < num_blocks; i++) blocks[i].size = pretro_get_memory_size(blocks[i].type); for (i = 0; i < num_blocks; i++) if (blocks[i].size) blocks[i].data = malloc(blocks[i].size); /* Backup current SRAM which is overwritten by unserialize. */ for (i = 0; i < num_blocks; i++) { if (blocks[i].data) { const void *ptr = pretro_get_memory_data(blocks[i].type); if (ptr) memcpy(blocks[i].data, ptr, blocks[i].size); } } ret = pretro_unserialize(buf, size); /* Flush back. */ for (i = 0; i < num_blocks; i++) { if (blocks[i].data) { void *ptr = pretro_get_memory_data(blocks[i].type); if (ptr) memcpy(ptr, blocks[i].data, blocks[i].size); } } for (i = 0; i < num_blocks; i++) free(blocks[i].data); free(blocks); free(buf); return ret; }
bool gl_glsl_init(const char *path) { #if !defined(HAVE_OPENGLES2) && !defined(HAVE_OPENGL_MODERN) && !defined(__APPLE__) // Load shader functions. LOAD_GL_SYM(CreateProgram); LOAD_GL_SYM(UseProgram); LOAD_GL_SYM(CreateShader); LOAD_GL_SYM(DeleteShader); LOAD_GL_SYM(ShaderSource); LOAD_GL_SYM(CompileShader); LOAD_GL_SYM(AttachShader); LOAD_GL_SYM(DetachShader); LOAD_GL_SYM(LinkProgram); LOAD_GL_SYM(GetUniformLocation); LOAD_GL_SYM(Uniform1i); LOAD_GL_SYM(Uniform1f); LOAD_GL_SYM(Uniform2fv); LOAD_GL_SYM(Uniform4fv); LOAD_GL_SYM(UniformMatrix4fv); LOAD_GL_SYM(GetShaderiv); LOAD_GL_SYM(GetShaderInfoLog); LOAD_GL_SYM(GetProgramiv); LOAD_GL_SYM(GetProgramInfoLog); LOAD_GL_SYM(DeleteProgram); LOAD_GL_SYM(GetAttachedShaders); LOAD_GL_SYM(GetAttribLocation); LOAD_GL_SYM(EnableVertexAttribArray); LOAD_GL_SYM(DisableVertexAttribArray); LOAD_GL_SYM(VertexAttribPointer); RARCH_LOG("Checking GLSL shader support ...\n"); bool shader_support = pglCreateProgram && pglUseProgram && pglCreateShader && pglDeleteShader && pglShaderSource && pglCompileShader && pglAttachShader && pglDetachShader && pglLinkProgram && pglGetUniformLocation && pglUniform1i && pglUniform1f && pglUniform2fv && pglUniform4fv && pglUniformMatrix4fv && pglGetShaderiv && pglGetShaderInfoLog && pglGetProgramiv && pglGetProgramInfoLog && pglDeleteProgram && pglGetAttachedShaders && pglGetAttribLocation && pglEnableVertexAttribArray && pglDisableVertexAttribArray && pglVertexAttribPointer; if (!shader_support) { RARCH_ERR("GLSL shaders aren't supported by your OpenGL driver.\n"); return false; } #endif unsigned num_progs = 0; struct shader_program progs[RARCH_GLSL_MAX_SHADERS] = {{0}}; if (path) { num_progs = get_xml_shaders(path, progs, RARCH_GLSL_MAX_SHADERS - 1); if (num_progs == 0) { RARCH_ERR("Couldn't find any valid shaders in XML file.\n"); return false; } } else { RARCH_WARN("[GL]: Stock GLSL shaders will be used.\n"); num_progs = 1; progs[0].vertex = strdup(stock_vertex_modern); progs[0].fragment = strdup(stock_fragment_modern); glsl_modern = true; } #ifdef HAVE_OPENGLES2 if (!glsl_modern) { RARCH_ERR("[GL]: GLES context is used, but shader is not modern. Cannot use it.\n"); return false; } #endif struct shader_program stock_prog = {0}; stock_prog.vertex = strdup(glsl_modern ? stock_vertex_modern : stock_vertex_legacy); stock_prog.fragment = strdup(glsl_modern ? stock_fragment_modern : stock_fragment_legacy); if (!compile_programs(&gl_program[0], &stock_prog, 1)) { RARCH_ERR("GLSL stock programs failed to compile.\n"); return false; } for (unsigned i = 0; i < num_progs; i++) { gl_filter_type[i + 1] = progs[i].filter; gl_scale[i + 1].type_x = progs[i].type_x; gl_scale[i + 1].type_y = progs[i].type_y; gl_scale[i + 1].scale_x = progs[i].scale_x; gl_scale[i + 1].scale_y = progs[i].scale_y; gl_scale[i + 1].abs_x = progs[i].abs_x; gl_scale[i + 1].abs_y = progs[i].abs_y; gl_scale[i + 1].valid = progs[i].valid_scale; } if (!compile_programs(&gl_program[1], progs, num_progs)) return false; // RetroArch custom two-pass with two different files. if (num_progs == 1 && *g_settings.video.second_pass_shader && g_settings.video.render_to_texture) { unsigned secondary_progs = get_xml_shaders(g_settings.video.second_pass_shader, progs, 1); if (secondary_progs == 1) { if (!compile_programs(&gl_program[2], progs, 1)) { RARCH_ERR("Failed to compile second pass shader.\n"); return false; } num_progs++; } else { RARCH_ERR("Did not find exactly one valid shader in secondary shader file.\n"); return false; } } for (unsigned i = 0; i <= num_progs; i++) find_uniforms(gl_program[i], &gl_uniforms[i]); #ifdef GLSL_DEBUG if (!gl_check_error()) RARCH_WARN("Detected GL error in GLSL.\n"); #endif if (gl_tracker_info_cnt > 0) { struct state_tracker_info info = {0}; info.wram = (uint8_t*)pretro_get_memory_data(RETRO_MEMORY_SYSTEM_RAM); info.info = gl_tracker_info; info.info_elem = gl_tracker_info_cnt; #ifdef HAVE_PYTHON info.script = gl_script_program; info.script_class = *gl_tracker_script_class ? gl_tracker_script_class : NULL; info.script_is_file = false; #endif gl_state_tracker = state_tracker_init(&info); if (!gl_state_tracker) RARCH_WARN("Failed to init state tracker.\n"); } glsl_enable = true; gl_num_programs = num_progs; gl_program[gl_num_programs + 1] = gl_program[0]; gl_uniforms[gl_num_programs + 1] = gl_uniforms[0]; gl_glsl_reset_attrib(); return true; }
bool load_state(const char *path) { unsigned i; void *buf = NULL; ssize_t size = read_file(path, &buf); RARCH_LOG("Loading state: \"%s\".\n", path); if (size < 0) { RARCH_ERR("Failed to load state from \"%s\".\n", path); return false; } bool ret = true; RARCH_LOG("State size: %u bytes.\n", (unsigned)size); void *block_buf[2] = {NULL, NULL}; int block_type[2] = {-1, -1}; size_t block_size[2] = {0}; if (g_settings.block_sram_overwrite) { RARCH_LOG("Blocking SRAM overwrite.\n"); switch (g_extern.game_type) { case RARCH_CART_NORMAL: block_type[0] = RETRO_MEMORY_SAVE_RAM; block_type[1] = RETRO_MEMORY_RTC; break; case RARCH_CART_BSX: case RARCH_CART_BSX_SLOTTED: block_type[0] = RETRO_MEMORY_SNES_BSX_RAM; block_type[1] = RETRO_MEMORY_SNES_BSX_PRAM; break; case RARCH_CART_SUFAMI: block_type[0] = RETRO_MEMORY_SNES_SUFAMI_TURBO_A_RAM; block_type[1] = RETRO_MEMORY_SNES_SUFAMI_TURBO_B_RAM; break; case RARCH_CART_SGB: block_type[0] = RETRO_MEMORY_SNES_GAME_BOY_RAM; block_type[1] = RETRO_MEMORY_SNES_GAME_BOY_RTC; break; } } for (i = 0; i < 2; i++) if (block_type[i] != -1) block_size[i] = pretro_get_memory_size(block_type[i]); for (i = 0; i < 2; i++) if (block_size[i]) block_buf[i] = malloc(block_size[i]); // Backup current SRAM which is overwritten by unserialize. for (i = 0; i < 2; i++) { if (block_buf[i]) { const void *ptr = pretro_get_memory_data(block_type[i]); if (ptr) memcpy(block_buf[i], ptr, block_size[i]); } } ret = pretro_unserialize(buf, size); // Flush back :D for (i = 0; i < 2 && ret; i++) { if (block_buf[i]) { void *ptr = pretro_get_memory_data(block_type[i]); if (ptr) memcpy(ptr, block_buf[i], block_size[i]); } } for (i = 0; i < 2; i++) if (block_buf[i]) free(block_buf[i]); free(buf); return ret; }