buffered_reader_t *buffered_reader_open(const char *path, int32_t buffer_size, int32_t seek_mode) { buffered_reader_t *reader = malloc(sizeof(buffered_reader_t)); long long result; if (reader == 0) return 0; memset(reader, 0, sizeof(buffered_reader_t)); reader->cache_enabled = 1; reader->handle = -1; reader->buffer_size = buffer_size; reader->seek_mode = seek_mode; reader->buffer_0 = malloc_64(reader->buffer_size); if (reader->buffer_0 == 0) { buffered_reader_close(reader); return 0; } reader->buffer_1 = malloc_64(reader->buffer_size); if (reader->buffer_1 == 0) { buffered_reader_close(reader); return 0; } reader->buffer_2 = malloc_64(reader->buffer_size); if (reader->buffer_2 == 0) { buffered_reader_close(reader); return 0; } reader->handle = sceIoOpen(path, PSP_O_RDONLY, 0777); if (reader->handle < 0) { buffered_reader_close(reader); return 0; } if (sceIoChangeAsyncPriority(reader->handle, 0x10) < 0) { buffered_reader_close(reader); return 0; } reader->length = sceIoLseek32(reader->handle, 0, PSP_SEEK_END); reader->first_buffer = reader->buffer_0; reader->second_buffer = reader->buffer_1; reader->third_buffer = reader->buffer_2; sceIoLseek32(reader->handle, reader->position_0, PSP_SEEK_SET); sceIoReadAsync(reader->handle, reader->first_buffer, reader->position_1 - reader->position_0); sceIoWaitAsync(reader->handle, &result); sceIoLseek32(reader->handle, reader->position_1, PSP_SEEK_SET); sceIoReadAsync(reader->handle, reader->second_buffer, reader->position_2 - reader->position_1); sceIoWaitAsync(reader->handle, &result); sceIoLseek32(reader->handle, reader->position_2, PSP_SEEK_SET); sceIoReadAsync(reader->handle, reader->third_buffer, reader->position_3 - reader->position_2); return reader; }
int _diva_read(SceUID fd, void *data, SceSize size, int async) { u32 file_offset; cpknode *file_index; SceUID modfd; int res; u32 k1; if (fd == datafd) { // get the current file pointer file_offset = (u32)sceIoLseek(fd, 0, PSP_SEEK_CUR); // and find if the file part that the game is trying to read is in our list // of files to replace file_index = search_exact(file_offset, cpk_table, cpk_count); if(file_index != NULL) { kprintf("index found: %08X\n", *(u32 *)file_index); k1 = pspSdkSetK1(0); modfd = open_file(image_filenames + file_index->filename_offset); if(modfd >= 0) { kprintf("reading offset %08X, size: %08X\n", file_offset, size); // read our modified file instead, fooling the game res = async ? sceIoReadAsync(modfd, data, size) : sceIoRead(modfd, data, size); kprintf("read returned %08X\n", res); // make sure to return the read bytes that the game is expecting if(!async) { res = (int)size; sceIoClose(modfd); } else { wait_size = size; wait_fd = modfd; } // and advance the file pointer so we fully simulated that the read from the // cpk has been done sceIoLseek(fd, size, PSP_SEEK_CUR); pspSdkSetK1(k1); return res; } pspSdkSetK1(k1); } } kprintf("reading %i bytes from fd: %08X, offset: %08X, async: %i\n", size, fd, (u32)sceIoLseek(fd, 0, PSP_SEEK_CUR), async); return async ? sceIoReadAsync(fd, data, size) : sceIoRead(fd, data, size); }
static int myIoReadAsync(int fd, u8 *buf, int size) { int ret; u32 pos; u32 k1; k1 = pspSdkSetK1(0); pos = sceIoLseek32(fd, 0, SEEK_CUR); ret = sceIoReadAsync(fd, buf, size); printk("%s: 0x%08X 0x%08X 0x%08X -> 0x%08X\n", __func__, (uint)fd, (uint)pos, size, ret); pspSdkSetK1(k1); return ret; }
static char *fill_asynchronous_buffer(struct mp4_read_struct *reader, struct mp4_asynchronous_buffer *p, SceUID handle, int track_id, unsigned int trunk_index) { mp4info_track_t* track = reader->file.info->tracks[track_id]; int i, j; for( i = 0; i < track->stsc_entry_count-1; i++ ) { if ( (trunk_index+1) >= track->stsc_first_chunk[i] && (trunk_index+1) < track->stsc_first_chunk[i+1] ) break; } p->first_sample = 0; for( j = 0; j < i; j++ ) { p->first_sample += ( ( track->stsc_first_chunk[j+1] - track->stsc_first_chunk[j] ) * track->stsc_samples_per_chunk[j] ); } p->first_sample += ( ( (trunk_index+1) - track->stsc_first_chunk[i] ) * track->stsc_samples_per_chunk[i] ); p->last_sample = p->first_sample + track->stsc_samples_per_chunk[i] - 1; p->trunk_size = 0; for(i = p->first_sample; i <= p->last_sample; i++) { p->sample_buffer[i-p->first_sample] = p->buffer + p->trunk_size; p->trunk_size += ( track->stsz_sample_size ? track->stsz_sample_size : track->stsz_sample_size_table[i]); } p->trunk_position = track->stco_chunk_offset[trunk_index]; p->trunk_index = trunk_index; if (sceIoLseek32(handle, p->trunk_position, PSP_SEEK_SET) != p->trunk_position) { return("fill_asynchronous_buffer: seek failed"); } if (sceIoReadAsync(handle, p->sample_buffer[0], p->trunk_size) < 0) { return("fill_asynchronous_buffer: read failed"); } return(0); }
static char *fill_asynchronous_buffer(struct pmp_read_struct *reader, struct asynchronous_buffer *p, unsigned int first_packet, unsigned int first_packet_position, unsigned int seek) { p->first_packet = first_packet; p->last_packet = first_packet; p->packets_size = reader->file.packet_index[first_packet] >> 1; p->packet_buffer[0] = p->buffer + (first_packet_position & (64 - 1)); unsigned int number_of_packets = 1; if (seek == 0) { while (1) { if (p->last_packet + 1 == reader->file.header.video.number_of_frames) { break; } if (number_of_packets == maximum_number_of_packets) { break; } unsigned int next_packet_size = reader->file.packet_index[p->last_packet + 1] >> 1; if (p->packets_size + next_packet_size > reader->buffer_size) { break; } p->packet_buffer[number_of_packets] = p->packet_buffer[0] + p->packets_size; p->packets_size += next_packet_size; p->last_packet ++; number_of_packets ++; } } p->first_packet_position = first_packet_position; p->next_packet_position = first_packet_position + p->packets_size; if (sceIoLseek32(reader->f, p->first_packet_position, PSP_SEEK_SET) != p->first_packet_position) { return("fill_asynchronous_buffer: seek failed"); } if (sceIoReadAsync(reader->f, p->packet_buffer[0], p->packets_size) < 0) { return("fill_asynchronous_buffer: read failed"); } return(0); }
int32_t buffered_reader_seek(buffered_reader_t * reader, const int32_t position) { int32_t seek = 0; if (!reader->cache_enabled) { return sceIoLseek32(reader->handle, position, PSP_SEEK_SET); } if (position >= reader->position_0 && position < reader->position_2) { reader->current_position = position; return position; } else { long long result; sceIoWaitAsync(reader->handle, &result); if (position >= reader->position_2 && position < reader->position_3) { uint8_t *temp = reader->first_buffer; reader->first_buffer = reader->second_buffer; reader->second_buffer = reader->third_buffer; reader->third_buffer = temp; reader->position_0 = reader->position_1; reader->position_1 = reader->position_2; reader->position_2 = reader->position_3; reader->current_position = position; reader->position_3 = reader->position_2 + reader->buffer_size; if (reader->position_3 >= reader->length) reader->position_3 = reader->length; sceIoLseek32(reader->handle, reader->position_2, PSP_SEEK_SET); sceIoReadAsync(reader->handle, reader->third_buffer, reader->position_3 - reader->position_2); return position; } else { if (position < reader->position_0) seek = -1; else seek = 1; { int32_t old_position_0 = reader->position_0; int32_t old_position_1 = reader->position_1; int32_t old_position_2 = reader->position_2; reader->position_0 = position & 0xFFFFFFC0; reader->position_1 = reader->position_0 + reader->buffer_size; if (reader->position_1 >= reader->length) reader->position_1 = reader->length; reader->position_2 = reader->position_1 + reader->buffer_size; if (reader->position_2 >= reader->length) reader->position_2 = reader->length; reader->position_3 = reader->position_2 + reader->buffer_size; if (reader->position_3 >= reader->length) reader->position_3 = reader->length; reader->current_position = position; if (seek > 0 || (reader->position_3 <= old_position_0)) { sceIoLseek32(reader->handle, reader->position_0, PSP_SEEK_SET); sceIoRead(reader->handle, reader->first_buffer, reader->position_1 - reader->position_0); sceIoLseek32(reader->handle, reader->position_1, PSP_SEEK_SET); sceIoRead(reader->handle, reader->second_buffer, reader->position_2 - reader->position_1); sceIoLseek32(reader->handle, reader->position_2, PSP_SEEK_SET); sceIoReadAsync(reader->handle, reader->third_buffer, reader->position_3 - reader->position_2); } else { int32_t copy; uint8_t *dest; uint8_t *src; if (old_position_0 >= reader->position_2) { copy = reader->position_3 - old_position_0; dest = reader->third_buffer + (old_position_0 - reader->position_2); src = reader->first_buffer; memcpy(dest, src, copy); sceIoLseek32(reader->handle, reader->position_0, PSP_SEEK_SET); sceIoRead(reader->handle, reader->first_buffer, reader->position_1 - reader->position_0); sceIoLseek32(reader->handle, reader->position_1, PSP_SEEK_SET); sceIoRead(reader->handle, reader->second_buffer, reader->position_2 - reader->position_1); sceIoLseek32(reader->handle, reader->position_2, PSP_SEEK_SET); sceIoReadAsync(reader->handle, reader->third_buffer, old_position_0 - reader->position_2); } else if (old_position_0 >= reader->position_1) { copy = reader->position_3 - old_position_1; dest = reader->third_buffer + (old_position_1 - reader->position_2); src = reader->second_buffer; memcpy(dest, src, copy); copy = old_position_1 - reader->position_2; dest = reader->third_buffer; src = reader->first_buffer + (reader->position_2 - old_position_0); memcpy(dest, src, copy); copy = reader->position_2 - old_position_0; dest = reader->second_buffer + (old_position_0 - reader->position_1); src = reader->first_buffer; memcpy(dest, src, copy); sceIoLseek32(reader->handle, reader->position_0, PSP_SEEK_SET); sceIoRead(reader->handle, reader->first_buffer, reader->position_1 - reader->position_0); sceIoLseek32(reader->handle, reader->position_1, PSP_SEEK_SET); sceIoRead(reader->handle, reader->second_buffer, old_position_0 - reader->position_1); sceIoLseek32(reader->handle, reader->position_2, PSP_SEEK_SET); sceIoReadAsync(reader->handle, reader->third_buffer, 0); } else { copy = reader->position_3 - old_position_2; dest = reader->third_buffer + (old_position_2 - reader->position_2); src = reader->third_buffer; memmove(dest, src, copy); copy = old_position_2 - reader->position_2; dest = reader->third_buffer; src = reader->second_buffer + (reader->position_2 - old_position_1); memcpy(dest, src, copy); copy = reader->position_2 - old_position_1; dest = reader->second_buffer + (old_position_1 - reader->position_1); src = reader->second_buffer; memmove(dest, src, copy); copy = old_position_1 - reader->position_1; dest = reader->second_buffer; src = reader->first_buffer + (reader->position_1 - old_position_0); memcpy(dest, src, copy); copy = reader->position_1 - old_position_0; dest = reader->first_buffer + (old_position_0 - reader->position_0); src = reader->first_buffer; memmove(dest, src, copy); sceIoLseek32(reader->handle, reader->position_0, PSP_SEEK_SET); sceIoRead(reader->handle, reader->first_buffer, old_position_0 - reader->position_0); sceIoLseek32(reader->handle, reader->position_1, PSP_SEEK_SET); sceIoRead(reader->handle, reader->second_buffer, 0); sceIoLseek32(reader->handle, reader->position_2, PSP_SEEK_SET); sceIoReadAsync(reader->handle, reader->third_buffer, 0); } } return position; } } } return 0; }
static int32_t buffered_reader_reset_buffer(buffered_reader_t * reader, const int32_t position) { long long result; sceIoWaitAsync(reader->handle, &result); if (position >= reader->position_2 && position < reader->position_3) { uint8_t *temp = reader->first_buffer; reader->first_buffer = reader->second_buffer; reader->second_buffer = reader->third_buffer; reader->third_buffer = temp; reader->position_0 = reader->position_1; reader->position_1 = reader->position_2; reader->position_2 = reader->position_3; reader->current_position = position; reader->position_3 = reader->position_2 + reader->buffer_size; if (reader->position_3 >= reader->length) reader->position_3 = reader->length; sceIoLseek32(reader->handle, reader->position_2, PSP_SEEK_SET); sceIoReadAsync(reader->handle, reader->third_buffer, reader->position_3 - reader->position_2); return position; } else { if (reader->seek_mode == 0) { reader->position_0 = position; reader->position_1 = reader->position_0 + reader->buffer_size; if (reader->position_1 >= reader->length) reader->position_1 = reader->length; reader->position_2 = reader->position_1 + reader->buffer_size; if (reader->position_2 >= reader->length) reader->position_2 = reader->length; reader->position_3 = reader->position_2 + reader->buffer_size; if (reader->position_3 >= reader->length) reader->position_3 = reader->length; reader->current_position = reader->position_0; } else if (reader->seek_mode == 1) { reader->position_1 = position; reader->position_0 = reader->position_1 - reader->buffer_size; if (reader->position_0 < 0) reader->position_0 = 0; reader->position_2 = reader->position_1 + reader->buffer_size; if (reader->position_2 >= reader->length) reader->position_2 = reader->length; reader->position_3 = reader->position_2 + reader->buffer_size; if (reader->position_3 >= reader->length) reader->position_3 = reader->length; reader->current_position = reader->position_1; } sceIoLseek32(reader->handle, reader->position_0, PSP_SEEK_SET); sceIoRead(reader->handle, reader->first_buffer, reader->position_1 - reader->position_0); sceIoLseek32(reader->handle, reader->position_1, PSP_SEEK_SET); sceIoRead(reader->handle, reader->second_buffer, reader->position_2 - reader->position_1); sceIoLseek32(reader->handle, reader->position_2, PSP_SEEK_SET); sceIoReadAsync(reader->handle, reader->third_buffer, reader->position_3 - reader->position_2); return position; } return 0; }