Example #1
0
//////////
//
// Called to play a stream at the indicated frequency using callbacks.
// Returns a handle which can be used to play or terminate the stream.
//
//////
	u64 CALLTYPE oss_soundCreateStream(u32 tnSamplesPerSecond, u64 tnSoundFillerCallbackFunction)
	{
		_isSSound*	lss;
		bool		llResult;


		// Was SDL initialized properly?
		if (glSDL_Initialized)
		{
			// Add this item to the list of sounds
			lss = (_isSSound*)vvm_SEChain_append(&gseRootSounds, gnNextUniqueId++, gnNextUniqueId++, sizeof(_isSSound), 1, &llResult);
			if (lss)
			{
				// Store the relevant information
				lss->isStream					= true;
				lss->stream.filler._callback	= tnSoundFillerCallbackFunction;

				// Create our stream buffer
				lss->samples					= (f32*)malloc(gsdlObtained.samples * sizeof(f32));

				// All done
				return(lss->ll.uniqueId);
			}
		}
		// If we get here, failure
		return(-1);
	}
Example #2
0
//////////
//
// Called to play a tone or set of up to five harmonic tones of a specific frequency for a specified duration.
// Returns a handle which can be used to play or terminate the tone.
//
// Note:  Use -1 for hertz entries to disable that tone channel.
//
//////
	u64 CALLTYPE oss_soundCreateTone(f32 tfHertz1, f32 tfHertz2, f32 tfHertz3, f32 tfHertz4, u32 tnDurationMilliseconds)
	{
		_isSSound*	lss;
		bool		llResult;


		// Was SDL initialized properly?
		if (glSDL_Initialized)
		{
			// Add this item to the list of sounds
			lss = (_isSSound*)vvm_SEChain_append(&gseRootSounds, gnNextUniqueId++, gnNextUniqueId++, sizeof(_isSSound), 1, &llResult);
			if (lss)
			{
				// Store the relevant information
				lss->isStream					= false;
				lss->tone.fHertz1				= tfHertz1;
				lss->tone.fHertz2				= tfHertz2;
				lss->tone.fHertz3				= tfHertz3;
				lss->tone.fHertz4				= tfHertz4;

				// Set our stoppers
				lss->tone.nMilliseconds			= tnDurationMilliseconds;									// How many milliseconds to generate tones for?
				lss->tone.nSamplesToGenerate	= (u32)(gnFrequency * (tnDurationMilliseconds / 1000.0f));	// Based on milliseconds, how many samples to generate?
				lss->tone.nSamplesGenerated		= 0;														// How many samples have been generated thus far?

				// Create our stream buffer
				lss->samples		= (f32*)malloc(gsdlObtained.samples * sizeof(f32));

				// All done
				return(lss->ll.uniqueId);
			}
		}
		// If we get here, failure
		return(-1);
	}
Example #3
0
//////////
//
// Loads the indicated resource string from the localization file
//
//////
	s8* CALLTYPE mc_loadResourceAsciiText(u32 tnResourceNumber)
	{
		u32					lnLength;
		SVvmmcResourceText*	lr;
		s8					buffer[1024];
		SStartEndCallback	cb;


		// Try to find the resource we've already loaded
		cb._func	= (u64)&iimc_loadResourceAsciiTextCallback;
		cb.extra	= tnResourceNumber;
		lr = (SVvmmcResourceText*)vvm_SEChain_searchByCallback(&gseRootResourceTexts, &cb);
		if (lr)
			return(lr->text);		// It's already been loaded

		// Try to locate it
		if (!LoadStringA(ghResourceDll, tnResourceNumber, buffer, sizeof(buffer)))
			return((s8*)cgcUnableToLocateResource);		// Use the default failure string

		// Allocate the new item
		lr = (SVvmmcResourceText*)vvm_SEChain_append(&gseRootResourceTexts, vvm_getNextUniqueId(), vvm_getNextUniqueId(), sizeof(SVvmmcResourceText), _COMMON_START_END_BLOCK_SIZE, NULL);
		if (lr)
		{
			// Store the resource information
			lr->resourceNumber	= tnResourceNumber;

			// Duplicate the loaded string
			lnLength			= strlen(buffer) + 1;
			lr->text			= (s8*)oss_alloc(lnLength, true);
			if (lr->text)		memcpy(lr->text, buffer, lnLength - 1);

			// All done
			return(lr->text);
		}
		// If we get here, failure
		return(NULL);
	}
Example #4
0
//////////
//
// Assembles the indicated file.vasm, creating a file.bxml
//
//////
void iAssembleFile(s8* tcPathname)
{
    u32				lnI, lnMachineCodeBytes, lnErrorCount, lnWarningCount;
    s64				lnHandle, lnFileSize, lnNumread;
    s8*				lcData;
    s8*				lcBxmlPathname;
    SStartEnd		prog;
    SProgram*		lp;			// program
    SVvmmcError*	lve;		// error
    SVvmmcWarning*	lvw;		// warning
    SAssembly*		la;			// assembly info
    SSourceFile*	lsf;		// top-level source file


    // Attempt to open the file
    lnHandle = oss_sharedAsciiOpenFile(tcPathname, false, true, false, false, false, false, false, false);
    if (lnHandle < 0)
    {
        // Open file error
        printf(mc_loadResourceAsciiText(IDS_UNABLE_TO_OPEN), tcPathname);
        ++gnErrors;
        return;
    }
    // If we get here, we're good


    // Get file size
    lnFileSize = oss_sharedAsciiFileSize(lnHandle);
    if (lnFileSize > 0xffffffff)
    {
        // Uhhh... what are they trying to do to us? :-)
        printf(mc_loadResourceAsciiText(IDS_FILE_IS_TOO_BIG), tcPathname);
        ++gnErrors;
        return;
    }
    if (lnFileSize == 0)
    {
        printf(mc_loadResourceAsciiText(IDS_FILE_IS_ZERO_BYTES), tcPathname);
        ++gnErrors;
        return;
    }


    // Allocate memory to load
    lcData = (s8*)oss_alloc((u32)lnFileSize, false);
    if (!lcData)
    {
        printf(mc_loadResourceAsciiText(IDS_ERROR_ALLOCATING), lnFileSize, tcPathname);
        ++gnErrors;
        return;
    }
    // If we get here, memory is allocated


    // Read into it
    lnNumread = oss_sharedAsciiReadFile(lnHandle, lcData, (u32)lnFileSize);
    if (lnNumread != lnFileSize)
    {
        printf(mc_loadResourceAsciiText(IDS_UNABLE_TO_READ_BYTES_FROM), (u32)lnFileSize, tcPathname, lnNumread);
        ++gnErrors;
        return;
    }
    // We're good
    oss_sharedAsciiCloseFile(lnHandle);


    // Initialize our variables
    memset(&prog, 0, sizeof(prog));

    // Define this initial program to its default empty state
    lp = (SProgram*)vvm_SEChain_append(&prog, vvm_getNextUniqueId(), vvm_getNextUniqueId(), sizeof(SProgram), _COMMON_START_END_SMALL_BLOCK_SIZE, NULL);
    printf(mc_loadResourceAsciiText(IDS_ASSEMBLING), tcPathname);


    //////////
    // Physically translate into machine code, and the output bxml file
    //////
    lnMachineCodeBytes = mc_assembleSourceCode(tcPathname, lcData, (u32)lnFileSize, lp);



    // When we get here, we've assembled our source file, with warnings, errors, or whatever
    // Free up our processed memory
    oss_free(lcData);


    // See where we sit
    if (!lp->_assembly.root)
    {
        // A fatal, unrecoverable error occurred where we didn't even get the initial startup data allocated
        printf(mc_loadResourceAsciiText(IDS_UNRECOVERABLE_ERROR));
        ++gnErrors;
        return;
    }
    // We're good.
    // Grab the top-level file info
    la		= (SAssembly*)lp->_assembly.root->ptr;			// SAssembly information
    lsf		= (SSourceFile*)la->includeFiles.root->ptr;		// Top-level source file (which contains the master list of all errors, warnings, and source file lines)


    // Report on warnings and errors
    if (!glQuiet)
    {
        // Report warnings
        if (!glIgnoreWarnings)
        {
            lnWarningCount = 0;
            for (lnI = 0; lnI < lsf->warnings.masterCount; lnI++)
            {
                if (lsf->warnings.master[lnI] && lsf->warnings.master[lnI]->used)
                {
                    // Grab the warning data
                    lvw = (SVvmmcWarning*)lsf->warnings.master[lnI]->ptr;
                    printf("--- %s\n---   |W:%u L:%u C:%u - %s\n", lvw->pathName, lvw->code, lvw->lineNumber, lvw->column, lvw->text);
                    ++lnWarningCount;
                }
            }
        }

        // Report errors
        lnErrorCount = 0;
        for (lnI = 0; lnI < lsf->errors.masterCount; lnI++)
        {
            if (lsf->errors.master[lnI] && lsf->errors.master[lnI]->used)
            {
                // Grab the warning data
                lve = (SVvmmcError*)lsf->errors.master[lnI]->ptr;
                printf("--- %s\n---   |E:%u L:%u C:%u - %s\n", lve->pathName, lve->code, lve->lineNumber, lve->column, lve->text);
                ++lnErrorCount;
            }
        }
    }


    // Write the output
    lcBxmlPathname = oss_changePathnameExtension(tcPathname, ".bxml");
    mc_saveSnippetsToBxml(lcBxmlPathname, &prog, true);
    oss_free(lcBxmlPathname);


    // Indicate we've processed another file
    ++gnFilesProcessed;


    // Indicate our final status
    printf("---\n");
    printf(mc_loadResourceAsciiText(IDS_ERRORS_WARNINGS_FOUND), lsf->errors.masterCount, lsf->warnings.masterCount, tcPathname);
    printf("---\n");

    // Update global totals
    gnErrors	+= lnErrorCount;
    gnWarnings	+= lnWarningCount;
}
Example #5
0
//////////
//
// Takes a VASM-compatible source file, and creates an executable program to be run on the VVM.
//
// Returns:
//		Number of bytes generated in machine code
//		Note:  If 0, did not do any valid processing, however the tseProg structure may still have
//		       been updated.
//
//////
	u32 CALLTYPE mc_assembleSourceCode(s8* tcVasmPathname, s8* tcData, u32 tnFileSize, SProgram* tsProgram)
	{
		u32				lnBytes;
		SAssembly*		la;
		SSourceFile*	lsf;


		// Allocate our assembly data
		la = (SAssembly*)vvm_SEChain_append(&tsProgram->_assembly, vvm_getNextUniqueId(), vvm_getNextUniqueId(), sizeof(SAssembly), _COMMON_START_END_BLOCK_SIZE, NULL);
		if (!la)	return(0);		// This is bad.  Very bad.  Should never happen.
		la->prog	= tsProgram;


		// Make sure our environment is sane
		lnBytes = 0;
		while (1)
		{
			if (!tcData || tnFileSize == 0)
				break;		//  Nothing to do


			//////////
			// Load the raw data, parse out into lines, load any include files
			//////
				lsf = imc_loadSourceFile(tcVasmPathname, tcData, tnFileSize, la, sizeof(_isSLineInfo), false);
				if (lsf->errors.masterCount != 0)
					break;		// Errors at this stage, we're done


			//////////
			// Begin parsing the source code, breaking out all lines to independent quantities that are recognized in later pass parsing
			//////
// For debugging:
//oss_writeSOssLineSequenceCompsDebuggingToDisk("\\libsf\\vvm\\vasm\\test\\testoutcomps.txt", &lsf->lines);
				imc_assemblyPass0(la, lsf);
// For debugging:
//oss_writeSOssLineSequenceCompsDebuggingToDisk("\\libsf\\vvm\\vasm\\test\\testoutcomps2.txt", &lsf->lines);
				if (lsf->errors.masterCount != 0)
					break;		// Errors at this stage, we're done


			//////////
			// Replace any tilde quantities, which are "macro substitutions" (for lack of a better term)
			//////
				imc_assemblyPass1(la, lsf);
// For debugging:
//oss_writeSOssLineSequenceCompsDebuggingToDisk("\\libsf\\vvm\\vasm\\test\\testoutcomps3.txt", &lsf->lines);
				if (lsf->errors.masterCount != 0)
					break;		// Errors at this stage, we're done


			//////////
			// Look for anything that's not currently known (meaning the first comp is one of alpha/alphanumeric/numeric/unknown)
			//////
// TODO:  continuing here
				imc_assemblyPass2(la, lsf);
// For debugging:
//oss_writeSOssLineSequenceCompsDebuggingToDisk("\\libsf\\vvm\\vasm\\test\\testoutcomps3.txt", &lsf->lines);
				if (lsf->errors.masterCount != 0)
					break;		// Errors at this stage, we're done


			// Unconditional break to return to caller
			break;
		}
		// Indicate the number of machine code bytes generated
		return(lnBytes);
	}
Example #6
0
//////////
//
// Initializes the VVM to its power-on state.
// Processes any load commands found on the command line.
//
//////
	bool ivvmtm_initialize(void)
	{
		bool			llResult;
		u32				lnI;
		SThreadMizer*	ltm;


		//////////
		// Find out how many cores we're dealing with
		//////
			oss_getSystemInfo(&gsVvmSysInfo);
			gsVvmSysInfo.cores = min(max(gsVvmSysInfo.cores, 256), 1);			// Range must be 1..256


		//////////
		// For each core, create a thread control structure slot
		//////
			llResult = vvm_SEChain_allocateAdditionalMasterSlots(&gsVvm.gseRootThreadMizer, gsVvmSysInfo.cores);


		// Enter a loop (for breaking out of)
		while (llResult)
		{
			// For each core, spawn a worker thread and have it waiting
			for (lnI = 0; lnI < (u32)gsVvmSysInfo.cores; lnI++)
			{
				//////////
				// Create its entry in the next free slot
				//////
					ltm = (SThreadMizer*)vvm_SEChain_append(&gsVvm.gseRootThreadMizer, vvm_getNextUniqueId(), vvm_getNextUniqueId(), sizeof(SThreadMizer), 1, NULL);
					if (!ltm)
					{
						// Should not happen, but it did
						llResult = false;
						break;
					}

				//////////
				// Tag it as indicated
				//////
					ltm->threadNum = lnI;

				//////////
				// Spawn it as a viable thread, but paused
				//////
					ltm->ossInfo = oss_threadCreate((u64)&ivvmtm_mainLoop, (void*)ltm, true);
					if (!ltm->ossInfo)
					{
						// Failure spawning
						llResult = false;
						break;
					}

				//////////
				// Start it up, get it going, time to move along, move along, nothing to see here
				//////
					oss_threadResume(ltm->ossInfo);

			}
			// When we get here, we're good, every slot's been filled.  There is peace and fullness.
			llResult = true;
			break;
		}

		// Indicate success or failure (Note:  We are praying for success, but will accept failure if need be)
		return(llResult);
	}