aboutsummaryrefslogblamecommitdiff
path: root/src/Support.cpp
blob: d070faa24a57738af7bb97015dfe7f0005d40f83 (plain) (tree)
1
2
3
4
5
6
7
8
9

                   
                      
                   
                     
                  

                   
                       
 




                    




                                        

 

                       
                                                    


                                                     



                  



                    






                                        
 


                                          
 
                       
 

                                                     




                                            
 



                                                 
 
                                                
 


                                              
 


                                          
 




                                                             
 



                                                      
 


                                                  
 

                                         
 
                                                                 
                                                                           



                                                                    
 
                                      
 


                                              
 









                                            
 


                                          
 


                 









                                                           
 
                              
 
                                        
 


                                                              

                                                                           

                                         
 





                                       

          

                                                                        
 






                                                                      








                                                       
 
                                          

                                      

 

                                
                                 
 
                                              
 
                                                     







                                 
 

                   
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

#include <GLFW/glfw3.h>

#include "Support.h"
#include "Files.h"

int Random()
{
#if RAND_MAX >= 65535
	return (rand() % 65535) - 32767;
#else
#error please fix this for your platform
#endif
}

bool IsKeyDown(int key)
{
	const auto window = glfwGetCurrentContext();
	return glfwGetKey(window, key) == GLFW_PRESS;
}

#ifndef O_BINARY
#define O_BINARY 0
#endif

#ifndef MAX_PATH
#define MAX_PATH 256
#endif

static int find_filename(char *filename)
{
	char *ptr;
	char *cur;
	char *next;
	DIR *dir;
	struct dirent *dirent;

	if (access(filename, R_OK) == 0) {
		return 1;
	}

	ptr = filename;

	while (*ptr) {
		if (ptr == filename || *ptr == '/') {
			if (*ptr == '/') {
				cur = ptr+1;
			} else {
				cur = ptr;
			}

			if (*cur == 0) {
				/* hit the end */
				break;
			}

			next = strchr(cur, '/');

			if (ptr != filename) {
				*ptr = 0;
			}

			if (next) {
				*next = 0;
			}

			if (ptr == filename && *ptr == '/') {
				dir = opendir("/");
			} else {
				dir = opendir(filename);
			}

			if (dir == NULL) {
				if (ptr != filename) {
					*ptr = '/';
				}

				if (next) {
					*next = 0;
				}

				return 0;
			}

			while ((dirent = readdir(dir)) != NULL) {
				if (strcasecmp(cur, dirent->d_name) == 0) {
					strcpy(cur, dirent->d_name);
					break;
				}
			}

			closedir(dir);

			if (ptr != filename) {
				*ptr = '/';
			}

			if (next) {
				*next = '/';
				ptr = next;
			} else {
				ptr++;
			}
		} else {
			ptr++;
		}
	}

	if (access(filename, R_OK) == 0) {
		return 1;
	}

	return 0;
}

static void fix_filename(const char *original, char *fixed)
{
	const char *start;
	int i;
	int len;

	start = original;
	if (original[0] == ':') {
		start = &original[1];
	}

	fixed[MAX_PATH-1] = 0;

	strncpy(fixed, start, MAX_PATH);

	/* check to see if strncpy overwrote the terminator */
	if (fixed[MAX_PATH-1] != 0) {
		fixed[MAX_PATH-1] = 0;

		fprintf(stderr, "ERROR: file truncation error: %s -> %s\n",
			original, fixed);
	}

	len = strlen(fixed);
	for (i = 0; i < len; i++) {
		if (fixed[i] == ':') {
			fixed[i] = '/';
		}
	}

	/*
	   here we would try to see if the file is available (game dir),
	   else try another dir

	   really, this function also needs a flag to indicate whether
	   it should only go to local (write) or both (read)
	 */

	if (find_filename(fixed) == 0) {
		fprintf(stderr, "find failed: %s\n", fixed);
	}
}

/*
Convenient Filename Hacks
*/

FILE *cfh_fopen(const char *filename, const char *mode)
{
	char filename1[MAX_PATH];

	fix_filename(filename, filename1);

	return fopen(filename1, mode);
}

int Files::OpenFile(Str255 Name)
{
	char filename1[MAX_PATH];

	fix_filename((char *)Name, filename1);

	sFile = open(filename1, O_RDONLY | O_BINARY);
	return sFile;
}

void Files::EndLoad()
{
	if (sFile != -1) {
		FSClose( sFile );
	}

	sFile = -1;
}