/tools/pack-pbp.c

https://github.com/sidealice/pspsdk · C · 189 lines · 114 code · 33 blank · 42 comment · 29 complexity · 7b4bed607ee8876ba0eff6765d8ef2e4 MD5 · raw file

  1. /*
  2. # _____ ___ ____ ___ ____
  3. # ____| | ____| | | |____|
  4. # | ___| | ___| ____| | \ PSPDEV Open Source Project.
  5. #-----------------------------------------------------------------------
  6. # (c) 2005 Dan Peori <peori@oopo.net>
  7. # Licenced under Academic Free License version 2.0
  8. # Review pspsdk README & LICENSE files for further details.
  9. #
  10. # 2006-12-30 - Andrew Whatson <whatson@gmail.com>
  11. # - rewrote for easier reading
  12. # - gave "correct" names to UNKNOWN.* files
  13. # - improved memory efficiency with large PBPs
  14. # - output name of each file as it's added
  15. #
  16. # $Id: pack-pbp.c 2228 2007-05-01 05:22:03Z oopo $
  17. */
  18. #ifdef HAVE_CONFIG_H
  19. #include "config.h"
  20. #endif
  21. #ifdef WORDS_BIGENDIAN
  22. // Swap the bytes of an int for big-endian machines
  23. static int swap_int(int n)
  24. {
  25. return ((n>>24)&0xff)|((n>>8)&0xff00)|((n<<8)&0xff0000)|((n<<24)&0xff000000);
  26. }
  27. #endif
  28. #include <stdio.h>
  29. #include <string.h>
  30. #include <stdlib.h>
  31. #ifdef HAVE_MALLOC_H
  32. #include <malloc.h>
  33. #endif
  34. // Struct to describe the header of a PBP file
  35. struct {
  36. char signature[4];
  37. char version[4];
  38. int offset[8];
  39. } header = {
  40. { 0x00, 0x50, 0x42, 0x50 },
  41. { 0x00, 0x00, 0x01, 0x00 },
  42. { 40, 0, 0, 0, 0, 0, 0, 0 }
  43. };
  44. // Maximum size of read buffer
  45. int maxbuffer = 16 * 1024 * 1024;
  46. int main(int argc, char *argv[]) { int loop0, result;
  47. FILE *infile;
  48. FILE *outfile;
  49. int filesize[8];
  50. // Check for the correct number of arguments
  51. if (argc != 10) {
  52. printf("USAGE: %s <output.pbp> <param.sfo> <icon0.png> <icon1.pmf> <pic0.png> <pic1.png> <snd0.at3> <data.psp> <data.psar>\n", argv[0]);
  53. return -1;
  54. }
  55. // For each file in the PBP
  56. for (loop0 = 0; loop0 < 8; loop0++) {
  57. // If the specificed filename is NULL or -, skip the file.
  58. if (strncmp(argv[2 + loop0], "NULL", 4) == 0 || strncmp(argv[2 + loop0], "-", 4) == 0) {
  59. filesize[loop0] = 0;
  60. } else {
  61. // Open the file
  62. infile = fopen(argv[2 + loop0], "rb");
  63. if (infile == NULL) {
  64. printf("ERROR: Could not open the file. (%s)\n", argv[2 + loop0]);
  65. return -1;
  66. }
  67. // Read in the file size
  68. fseek(infile, 0, SEEK_END);
  69. filesize[loop0] = ftell(infile);
  70. fseek(infile, 0, SEEK_SET);
  71. if (filesize[loop0] < 0) {
  72. printf("ERROR: Could not read in the file size. (%s)\n", argv[2 + loop0]);
  73. return -1;
  74. }
  75. // Close the file
  76. result = fclose(infile);
  77. if (result < 0) {
  78. printf("ERROR: Could not close the file. (%s)\n", argv[2 + loop0]);
  79. return -1;
  80. }
  81. }
  82. }
  83. // Set the header offset values for each file
  84. for (loop0 = 1; loop0 < 8; loop0++) {
  85. header.offset[loop0] = header.offset[loop0 - 1] + filesize[loop0 - 1];
  86. }
  87. #ifdef WORDS_BIGENDIAN
  88. // Swap the bytes of the offsets for big-endian machines
  89. for (loop0 = 0; loop0 < 8; loop0++) {
  90. header.offset[loop0] = swap_int(header.offset[loop0]);
  91. }
  92. #endif
  93. // Open the output file
  94. outfile = fopen(argv[1], "wb");
  95. if (outfile == NULL) {
  96. printf("ERROR: Could not open the output file. (%s)\n", argv[1]);
  97. return -1;
  98. }
  99. // Write out the header
  100. result = fwrite(&header, sizeof(header), 1, outfile);
  101. if (result < 0) {
  102. printf("ERROR: Could not write out the file header. (%s)\n", argv[1]);
  103. return -1;
  104. }
  105. // For each file in the PBP
  106. for (loop0 = 0; loop0 < 8; loop0++) {
  107. void *buffer;
  108. int readsize;
  109. // Print out the file details
  110. printf("[%d] %10d bytes | %s\n", loop0, filesize[loop0], argv[2 + loop0]);
  111. // If this file is empty, skip it
  112. if (!filesize[loop0]) continue;
  113. // Open the file
  114. infile = fopen(argv[2 + loop0], "rb");
  115. if (infile == NULL) {
  116. printf("ERROR: Could not open the file. (%s)\n", argv[2 + loop0]);
  117. return -1;
  118. }
  119. do {
  120. // Make sure we don't exceed the maximum buffer size
  121. if (filesize[loop0] > maxbuffer) {
  122. readsize = maxbuffer;
  123. } else {
  124. readsize = filesize[loop0];
  125. }
  126. filesize[loop0] -= readsize;
  127. // Create the read buffer
  128. buffer = malloc(readsize);
  129. if (buffer == NULL) {
  130. printf("ERROR: Could not allocate the file data space. (%s)\n", argv[2 + loop0]);
  131. return -1;
  132. }
  133. // Read in the data from the file
  134. if (fread(buffer, readsize, 1, infile) < 0) {
  135. printf("ERROR: Could not read in the file data. (%s)\n", argv[2 + loop0]);
  136. return -1;
  137. }
  138. // Write the contents of the buffer to the PBP
  139. if (fwrite(buffer, readsize, 1, outfile) < 0) {
  140. printf("ERROR: Could not write out the file data. (%s)\n", argv[1]);
  141. return -1;
  142. }
  143. // Clean up the buffer
  144. free(buffer);
  145. // Repeat if we haven't finished writing the file
  146. } while (filesize[loop0]);
  147. }
  148. // Close the output file.
  149. result = fclose(outfile);
  150. if (result < 0) {
  151. printf("ERROR: Could not close the output file. (%s)\n", argv[1]);
  152. return -1;
  153. }
  154. // Exit successful
  155. return 0;
  156. }