Пример #1
0
BucketArray<T> BucketArray<T>::initBucketArray(uint32 elementSize, uint32 numElems, uint32 numBuckets, MemoryArena *arena)
{
    elemSize = elementSize;
    elemCount = numElems;
    bucketCount = numBuckets;
    occupancy = PushArray(arena, elemCount * bucketCount, uint8);
}
Пример #2
0
// �D���q�p�r�|���u�� ���q���u�{�� �r �����p�~�y�|�y���u
// �B���x�r���p���p�u�� �s�|���q�p�|���~���z �y�~�t�u�{�� ���q���u�{���p �r �s���������u
uint32 AddEntityToGroup(memory_arena *Arena, entity_group *Group)
{
	uint32 Result = 0;
	entity_group *ActiveGroup = Group;
	while (ActiveGroup->NextGroup)
	{
		Result += ActiveGroup->GroupSize;
		ActiveGroup = ActiveGroup->NextGroup;
	}

	if (ActiveGroup->EntityCount == ActiveGroup->GroupSize)
	{
		// �P�u���u�����|�~�u�~�y�u, �r���t�u�|�y���� �}�u������ �����t �~���r���� �s����������
		entity_group *NextGroup = PushStruct(Arena, entity_group);
		Assert(NextGroup);

		NextGroup->Entities = PushArray(Arena, 4096, entity);
		Assert(NextGroup->Entities);

		NextGroup->GroupSize = 4096;
		NextGroup->EntityCount = 0;
		NextGroup->NextGroup = 0;
		ActiveGroup->NextGroup = NextGroup;
		ActiveGroup = NextGroup;
	}

	Result += ActiveGroup->EntityCount++;
	
	return Result;
}
Пример #3
0
void AllocateTileMap(MemoryArena* arena, TileMap* tilemap, Vec2 map_size, uint32 max_tiles)
{
    tilemap->size = map_size;

// TODO: accurate allocation of sub arena

    tilemap->tiles = PushArray(arena, Tile, max_tiles);
    tilemap->max_tiles = max_tiles;
    tilemap->num_tiles = 0;

    tilemap->quadtree_memory = CreateSubArena(arena, sizeof(TileGroup) * max_tiles);
    tilemap->tile_quadtree = PushStruct(&tilemap->quadtree_memory, TileGroup);
    tilemap->tile_quadtree->aabb = { 0, 0, map_size.x, map_size.y };
}
Пример #4
0
static Scene* PushScene(MemoryArena* arena, uint32 num_entities)
{
    Scene* result = PushStruct(arena, Scene);

    result->max_entities = num_entities;
    result->entities = PushArray(arena, Entity, num_entities);

    // This should be done when loading a level
    // This needs to subarena for a quad tree
    result->tilemap = PushStruct(arena, TileMap);

    Vec2 map_size = { 100.f, 100.f };
    uint32 max_tiles = 1000;
    AllocateTileMap(arena, result->tilemap, map_size, max_tiles);

    return result;
}
Пример #5
0
internal void
SetTileValue(memory_arena *Arena, tile_map *TileMap, uint32 AbsTileX, uint32 AbsTileY, uint32 AbsTileZ, uint32 TileValue)
{
	tile_chunk_position ChunkPos = GetChunkPositionFor(TileMap, AbsTileX, AbsTileY, AbsTileZ);
	tile_chunk *TileChunk = GetTileChunk(TileMap, ChunkPos.TileChunkX, ChunkPos.TileChunkY, ChunkPos.TileChunkZ);

	Assert(TileChunk);

	if(!TileChunk->Tiles)
	{
		uint32 TileCount = TileMap->ChunkDim*TileMap->ChunkDim;
		TileChunk->Tiles = 
			PushArray(Arena, TileCount, uint32);
		for(uint32 TileIndex = 0;
			TileIndex < TileCount;
			++TileIndex)
		{
			TileChunk->Tiles[TileIndex] = 1;
		}
	
	}

	SetTileValue(TileMap, TileChunk, ChunkPos.RelTileX, ChunkPos.RelTileY, TileValue);
}
Пример #6
0
INTERNAL
void SetTileValue(MemoryArena* arena, TileMap* tileMap, uint32 absTileX, uint32 absTileY, uint32 absTileZ,
                  uint32 tileValue)
{
    TileChunkPosition chunkPosition = tileMap->GetChunkPositionFor(absTileX, absTileY, absTileZ);
    TileChunk* tileChunk = tileMap->GetTileChunk(chunkPosition.tileChunkX, chunkPosition.tileChunkY,
                           chunkPosition.tileChunkZ);
    // TODO(Peacock): Create tile chunk if not already there
    ASSERT(tileChunk);

    if (!tileChunk->tiles)
    {
        uint32 tileCount = tileMap->chunkDim * tileMap->chunkDim;
        tileChunk->tiles = PushArray(arena, tileCount, uint32);

        for (uint32 i = 0; i < tileCount; ++i)
        {
            tileChunk->tiles[i] = 1;
        }

    }

    SetTileValue(tileMap, tileChunk, chunkPosition.relTileX, chunkPosition.relTileY, tileValue);
}
Пример #7
0
int NativeInvoker::PushCellByRef(cell_t *cell, int flags)
{
	return PushArray(cell, 1, flags);
}
int CFunction::PushCellByRef(cell_t *cell, int flags)
{
	return PushArray(cell, 1, flags);
}
Пример #9
0
assets_s* AllocateAssets(memoryBlock_s* memoryBlock)
{
	assets_s* assets = PushStruct(memoryBlock, assets_s);
    assets->assetUseQueue = InitLinkedList(memoryBlock, Kilobytes(2));
    assets->dyMemoryBlock = InitDynamicMemoryBlock(memoryBlock, Megabytes(64), Kilobytes(10));
    assets->tagCount = 1;
    assets->assetCount = 1;

    platformFileGroup_s* fileGroup = Platform.getAllFilesOfTypeBegin("wa");
    assets->fileCount = fileGroup->fileCount;
    assets->files = PushArray(memoryBlock, assets->fileCount, assetFile_s);
    for(uint32_t index = 0; index < assets->fileCount; index++)
    {
        assetFile_s* file = assets->files + index;
        file->tagBase = assets->tagCount;
        file->handle = Platform.openNextFile(fileGroup);
        file->header = {};

        Platform.readDataFromFile(file->handle, 0, sizeof(file->header), &file->header);

        uint32_t assetTypeArraySize = file->header.assetTypesCount*sizeof(waAssetType_s);
        file->assetTypeArray = (waAssetType_s*) PushSize(memoryBlock, assetTypeArraySize);
        Platform.readDataFromFile(file->handle, file->header.assetTypes, assetTypeArraySize, 
            file->assetTypeArray);
        if(PlatformNoFileErrors(file->handle))
        {
            if(file->header.magicValue != MAGIC_VALUE)
            {
                Platform.fileError(file->handle, "wa file has an invalid magic value");
            }
            if(file->header.version > WALLACE_ASSET_VERSION)
            {
                Platform.fileError(file->handle, "wa file has a version which exceeds game version");
            } 

            if(PlatformNoFileErrors(file->handle))
            {
                // NOTE: The first asset and tag slot in every
                // .wa is a null (reserved) so we don't count it as
                // something we will need space for!
                assets->tagCount += (file->header.tagCount - 1);
                assets->assetCount += (file->header.assetCount - 1);
            }
        }
        else
        {
            InvalidCodePath;
        }
    }
    Platform.getAllFilesOfTypeEnd(fileGroup);
    assets->assets = PushArray(memoryBlock, assets->assetCount, assetFileData_s);
    assets->slots = PushArray(memoryBlock, assets->assetCount, assetData_s);
    assets->tags = PushArray(memoryBlock, assets->tagCount, waTag_s);

    assets->tags[0] = {};

    for(uint32_t fileIndex = 0; fileIndex < assets->fileCount; fileIndex++)
    {
        assetFile_s* file = assets->files + fileIndex;
        if(PlatformNoFileErrors(file->handle))
        {
            uint32_t tagArraySize = sizeof(waTag_s) * (file->header.tagCount - 1);
            Platform.readDataFromFile(file->handle, file->header.tags + sizeof(waTag_s), tagArraySize, 
                assets->tags + file->tagBase);
        }
    }

    // NOTE: Reserve one null asset at the beginning
    uint32_t assetCount = 0;
    assets->assets[assetCount] = {};
    assetCount++;
    for(uint32_t destTypeId = 0; destTypeId < assetType_last; destTypeId++)
    {
        waAssetType_s* destType = assets->assetTypes + destTypeId;
        destType->firstAssetIndex = assetCount;
        for(uint32_t fileIndex = 0; fileIndex < assets->fileCount; fileIndex++)
        {
            assetFile_s* file = assets->files + fileIndex;
            if(PlatformNoFileErrors(file->handle))
            {
                for(uint32_t sourceIndex = 0; sourceIndex < file->header.assetTypesCount; sourceIndex++)
                {
                    waAssetType_s* sourceType = file->assetTypeArray + sourceIndex;
                    if(sourceType->typeId == destTypeId)
                    {
                        uint32_t assetCountForType = sourceType->onePastLastAssetIndex - 
                            sourceType->firstAssetIndex;
                        temporaryMemory_s tempMem = BeginTemporaryMemory(memoryBlock);
                        waAssetFileData_s* waAssetArray = PushArray(memoryBlock, assetCountForType, waAssetFileData_s);
                        Platform.readDataFromFile(file->handle, file->header.assets +
                                                  sourceType->firstAssetIndex * sizeof(waAssetFileData_s),
                                                  assetCountForType * sizeof(waAssetFileData_s), waAssetArray);
                        for(uint32_t assetIndex = 0; assetIndex < assetCountForType; assetIndex++)
                        {
                            waAssetFileData_s* waAsset = waAssetArray + assetIndex;

                            // Assert(assetCount < assets->assetCount);
                            assetFileData_s* asset = assets->assets + assetCount++;
                            
                            asset->fileIndex = fileIndex;
                            asset->wa = *waAsset;
                            if(asset->wa.firstTagIndex == 0)
                            {
                                asset->wa.firstTagIndex = 0;
                                asset->wa.onePastLastTagIndex = 0;
                            }
                            else
                            {
                                asset->wa.firstTagIndex += (file->tagBase - 1);
                                asset->wa.onePastLastTagIndex += (file->tagBase - 1);
                            }
                        }

                        EndTemporaryMemory(tempMem);
                    }
                }
            }
        }
        destType->onePastLastAssetIndex = assetCount;
    }

    // Assert(assetCount == assets->assetCount);
	return assets;
}
Пример #10
0
void ExecuteCycle(VM* vm)
{
	if(vm->pc == -1) return;
	if(vm->debug)
		printf("pc %i: ", vm->pc);
	
	if(vm->stackSize < vm->numGlobals)
		printf("Global(s) were removed from the stack!\n");
	
	switch(vm->program[vm->pc])
	{
		case OP_PUSH_NULL:
		{
			if(vm->debug)
				printf("push_null\n");
			++vm->pc;
			PushObject(vm, &NullObject);
		} break;
		
		case OP_PUSH_NUMBER:
		{
			if(vm->debug)
				printf("push_number\n");
			++vm->pc;
			int index = ReadInteger(vm);
			PushNumber(vm, vm->numberConstants[index]);
		} break;
		
		case OP_PUSH_STRING:
		{
			if(vm->debug)
				printf("push_string\n");
			++vm->pc;
			int index = ReadInteger(vm);
			PushString(vm, vm->stringConstants[index]);
		} break;
		
		case OP_PUSH_FUNC:
		{
			if(vm->debug)
				printf("push_func\n");
			Word hasEllipsis = vm->program[++vm->pc];
			Word isExtern = vm->program[++vm->pc];
			Word numArgs = vm->program[++vm->pc];
			++vm->pc;
			int index = ReadInteger(vm);
			
			PushFunc(vm, index, hasEllipsis, isExtern, numArgs);
		} break;
		
		case OP_PUSH_DICT:
		{
			if(vm->debug)
				printf("push_dict\n");
			++vm->pc;
			PushDict(vm);
		} break;

		case OP_CREATE_DICT_BLOCK:
		{
			if(vm->debug)
				printf("create_dict_block\n");
			++vm->pc;
			int length = ReadInteger(vm);
			Object* obj = PushDict(vm);
			if(length > 0)
			{
				// stack (before dict) is filled with key-value pairs (backwards, key is higher on stack)
				for(int i = 0; i < length * 2; i += 2)
					DictPut(&obj->dict, vm->stack[vm->stackSize - i - 2]->string.raw, vm->stack[vm->stackSize - i - 3]);
				vm->stackSize -= length * 2;
				vm->stack[vm->stackSize - 1] = obj;
			}
		} break;

		case OP_CREATE_ARRAY:
		{
			if(vm->debug)
				printf("create_array\n");
			++vm->pc;
			int length = (int)PopNumber(vm);
			PushArray(vm, length);
		} break;
		
		case OP_CREATE_ARRAY_BLOCK:
		{
			if(vm->debug)
				printf("create_array_block\n");
			++vm->pc;
			int length = ReadInteger(vm);
			Object* obj = PushArray(vm, length);
			if(length > 0)
			{
				for(int i = 0; i < length; ++i)
					obj->array.members[length - i - 1] = vm->stack[vm->stackSize - 2 - i];
				vm->stackSize -= length;
				vm->stack[vm->stackSize - 1] = obj;
			}
		} break;

		case OP_LENGTH:
		{
			if(vm->debug)
				printf("length\n");
			++vm->pc;
			Object* obj = PopObject(vm);
			if(obj->type == OBJ_STRING)
				PushNumber(vm, strlen(obj->string.raw));
			else if(obj->type == OBJ_ARRAY)
				PushNumber(vm, obj->array.length);
			else
			{
				fprintf(stderr, "Attempted to get length of %s\n", ObjectTypeNames[obj->type]);
				exit(1);
			}
		} break;
		
		case OP_ARRAY_PUSH:
		{
			if(vm->debug)
				printf("array_push\n");
			++vm->pc;
			
			Object* obj = PopArrayObject(vm);
			Object* value = PopObject(vm);

			while(obj->array.length + 1 >= obj->array.capacity)
			{
				obj->array.capacity *= 2;
				obj->array.members = erealloc(obj->array.members, obj->array.capacity * sizeof(Object*));
			}
			
			obj->array.members[obj->array.length++] = value;
		} break;
		
		case OP_ARRAY_POP:
		{
			if(vm->debug)
				printf("array_pop\n");
			++vm->pc;
			Object* obj = PopArrayObject(vm);
			if(obj->array.length <= 0)
			{
				fprintf(stderr, "Cannot pop from empty array\n");
				exit(1);
			}
			
			PushObject(vm, obj->array.members[--obj->array.length]);
		} break;
		
		case OP_ARRAY_CLEAR:
		{
			if(vm->debug)
				printf("array_clear\n");
			++vm->pc;
			Object* obj = PopArrayObject(vm);
			obj->array.length = 0;
		} break;

		case OP_DICT_SET:
		{
			if(vm->debug)
				printf("dict_set\n");
			++vm->pc;
			Object* obj = PopDict(vm);
			const char* key = PopString(vm);
			Object* value = PopObject(vm);
			
			DictPut(&obj->dict, key, value);
		} break;
		
		case OP_DICT_GET:
		{
			if(vm->debug)
				printf("dict_get\n");
			++vm->pc;
			Object* obj = PopDict(vm);
			const char* key = PopString(vm);
			
			Object* value = DictGet(&obj->dict, key);
			if(value)
				PushObject(vm, value);
			else
				PushObject(vm, &NullObject);
		} break;

		case OP_DICT_PAIRS:
		{
			if(vm->debug)
				printf("dict_pairs\n");
			++vm->pc;
			Object* obj = PopDict(vm);
			Object* aobj = PushArray(vm, obj->dict.numEntries);
			
			int len = 0;
			for(int i = 0; i <= obj->dict.capacity; ++i)
			{
				DictNode* node = obj->dict.buckets[i];
				while(node)
				{
					Object* pair = PushArray(vm, 2);
					
					Object* key = NewObject(vm, OBJ_STRING);
					key->string.raw = estrdup(node->key);
					
					pair->array.members[0] = key;
					pair->array.members[1] = node->value;
					
					aobj->array.members[len++] = PopObject(vm);
					
					node = node->next;
				}
			}
		} break;
		
		#define BIN_OP_TYPE(op, operator, type) case OP_##op: { if(vm->debug) printf("%s\n", #op); Object* val2 = PopObject(vm); Object* val1 = PopObject(vm); PushNumber(vm, (type)val1->number operator (type)val2->number); ++vm->pc; } break;
		#define BIN_OP(op, operator) BIN_OP_TYPE(op, operator, double)
		
		BIN_OP(ADD, +)
		BIN_OP(SUB, -)
		BIN_OP(MUL, *)
		BIN_OP(DIV, /)
		BIN_OP_TYPE(MOD, %, int)
		BIN_OP_TYPE(OR, |, int)
		BIN_OP_TYPE(AND, &, int)
		BIN_OP(LT, <)
		BIN_OP(LTE, <=)
		BIN_OP(GT, >)
		BIN_OP(GTE, >=)
		BIN_OP_TYPE(LOGICAL_AND, &&, int)
		BIN_OP_TYPE(LOGICAL_OR, ||, int)
		
		#define CBIN_OP(op, operator) case OP_##op: { ++vm->pc; if(vm->debug) printf("%s\n", #op); Object* b = PopObject(vm); Object* a = PopObject(vm); a->number operator b->number; } break;
		
		CBIN_OP(CADD, +=)
		CBIN_OP(CSUB, -=)
		CBIN_OP(CMUL, *=)
		CBIN_OP(CDIV, /=)
		
		case OP_EQU:
		{
			++vm->pc;
			Object* o2 = PopObject(vm);
			Object* o1 = PopObject(vm);
			
			if(o1->type != o2->type) PushNumber(vm, 0);
			else
			{
				if(o1->type == OBJ_STRING) { PushNumber(vm, strcmp(o1->string.raw, o2->string.raw) == 0); }
				else if(o1->type == OBJ_NUMBER) { PushNumber(vm, o1->number == o2->number); }
				else PushNumber(vm, o1 == o2);
			}
		} break;
		
		case OP_NEQU:
		{
			++vm->pc;
			Object* o2 = PopObject(vm);
			Object* o1 = PopObject(vm);
			
			if(o1->type != o2->type) PushNumber(vm, 1);
			else
			{
				if(o1->type == OBJ_STRING) { PushNumber(vm, strcmp(o1->string.raw, o2->string.raw) != 0); }
				else if(o1->type == OBJ_NUMBER) { PushNumber(vm, o1->number != o2->number); }
				else PushNumber(vm, o1 != o2);
			}
		} break;
		
		case OP_NEG:
		{
			if(vm->debug)
				printf("neg\n");
			
			++vm->pc;
			Object* obj = PopObject(vm);
			PushNumber(vm, -obj->number);
		} break;
		
		case OP_LOGICAL_NOT:
		{
			if(vm->debug)
				printf("not\n");
			
			++vm->pc;
			Object* obj = PopObject(vm);
			PushNumber(vm, !obj->number);
		} break;
		
		case OP_SETINDEX:
		{
			++vm->pc;

			Object* obj = PopObject(vm);
			Object* indexObj = PopObject(vm);
			Object* value = PopObject(vm);
			if(vm->debug)
				printf("setindex\n");
			
			if(obj->type == OBJ_ARRAY)
			{
				if(indexObj->type != OBJ_NUMBER)
				{
					fprintf(stderr, "Attempted to index array with a %s (expected number)\n", ObjectTypeNames[indexObj->type]);
					exit(1);
				}
				
				int index = (int)indexObj->number;
				
				int arrayLength = obj->array.length;
				Object** members = obj->array.members;
				
				if(index >= 0 && index < arrayLength)
					members[index] = value;
				else
				{
					fprintf(stderr, "Invalid array index %i\n", index);
					exit(1);
				}
			}
			else if(obj->type == OBJ_STRING)
			{				
				if(indexObj->type != OBJ_NUMBER)
				{
					fprintf(stderr, "Attempted to index string with a %s (expected number)\n", ObjectTypeNames[indexObj->type]);
					exit(1);
				}
				
				if(value->type != OBJ_NUMBER)
				{
					fprintf(stderr, "Attempted to assign a %s to an index of a string '%s' (expected number/character)\n", ObjectTypeNames[value->type], obj->string.raw);
					exit(1);
				}
				
				obj->string.raw[(int)indexObj->number] = (char)value->number;
			}
			else if(obj->type == OBJ_DICT)
			{
				if(indexObj->type != OBJ_STRING)
				{
					fprintf(stderr, "Attempted to index dict with a %s (expected string)\n", ObjectTypeNames[indexObj->type]);
					exit(1);
				}
				
				DictPut(&obj->dict, indexObj->string.raw, value);
			}
			else
			{
				fprintf(stderr, "Attempted to index a %s\n", ObjectTypeNames[obj->type]);
				exit(1);
			}
		} break;

		case OP_GETINDEX:
		{
			++vm->pc;

			Object* obj = PopObject(vm);
			Object* indexObj = PopObject(vm);

			if(obj->type == OBJ_ARRAY)
			{
				if(indexObj->type != OBJ_NUMBER)
				{
					fprintf(stderr, "Attempted to index array with a %s (expected number)\n", ObjectTypeNames[indexObj->type]);
					exit(1);
				}
				
				int index = (int)indexObj->number;
				
				int arrayLength = obj->array.length;
				Object** members = obj->array.members;
				
				if(index >= 0 && index < arrayLength)
				{
					if(members[index])
						PushObject(vm, members[index]);
					else
					{
						fprintf(stderr, "attempted to index non-existent value in array\n");
						exit(1);
					}
					if(vm->debug)
						printf("getindex %i\n", index);
				}
				else
				{
					fprintf(stderr, "Invalid array index %i\n", index);
					exit(1);
				}
			}
			else if(obj->type == OBJ_STRING)
			{
				if(indexObj->type != OBJ_NUMBER)
				{
					fprintf(stderr, "Attempted to index string with a %s (expected number)\n", ObjectTypeNames[indexObj->type]);
					exit(1);
				}
				
				PushNumber(vm, obj->string.raw[(int)indexObj->number]);
			}
			else if(obj->type == OBJ_DICT)
			{
				if(indexObj->type != OBJ_STRING)
				{
					fprintf(stderr, "Attempted to index dict with a %s (expected string)\n", ObjectTypeNames[indexObj->type]);
					exit(1);
				}
				
				Object* val = (Object*)DictGet(&obj->dict, indexObj->string.raw);
				if(val)
					PushObject(vm, val);
				else
					PushObject(vm, &NullObject);
			}
			else 
			{
				fprintf(stderr, "Attempted to index a %s\n", ObjectTypeNames[obj->type]);
				exit(1);
			}
		} break;

		case OP_SET:
		{
			++vm->pc;
			int index = ReadInteger(vm);
			
			Object* top = PopObject(vm);
			vm->stack[index] = top;
			
			if(vm->debug)
			{
				if(top->type == OBJ_NUMBER) printf("set %i to %g\n", index, top->number);
				else if(top->type == OBJ_STRING) printf("set %i to %s\n", index, top->string);	
			}
		} break;
		
		case OP_GET:
		{
			++vm->pc;
			int index = ReadInteger(vm);
			if(vm->stack[index])
				PushObject(vm, (vm->stack[index]));
			else
				PushObject(vm, &NullObject);
				
			if(vm->debug)
				printf("get %i\n", index);
		} break;
		
		case OP_WRITE:
		{
			if(vm->debug)
				printf("write\n");
			Object* top = PopObject(vm);
			WriteObject(vm, top);
			printf("\n");
			++vm->pc;
		} break;
		
		case OP_READ:
		{
			if(vm->debug)
				printf("read\n");
			char* string = ReadStringFromStdin();
			PushString(vm, string);
			free(string);
			++vm->pc;
		} break;
		
		case OP_GOTO:
		{
			++vm->pc;
			int pc = ReadInteger(vm);
			vm->pc = pc;
		
			if(vm->debug)
				printf("goto %i\n", vm->pc);
		} break;
		
		case OP_GOTOZ:
		{
			++vm->pc;
			int pc = ReadInteger(vm);
			
			Object* top = PopObject(vm);
			if(top->number == 0)
			{
				vm->pc = pc;
				if(vm->debug)
					printf("gotoz %i\n", vm->pc);
			}
		} break;
		
		case OP_CALL:
		{
			Word nargs = vm->program[++vm->pc];
			++vm->pc;
			int index = ReadInteger(vm);

			if(vm->debug)
				printf("call %s\n", vm->functionNames[index]);

			PushIndir(vm, nargs);

			vm->pc = vm->functionPcs[index];
		} break;
		
		case OP_CALLP:
		{
			Word hasEllipsis, isExtern, numArgs;
			Word nargs = vm->program[++vm->pc];
			++vm->pc;
			int id = PopFunc(vm, &hasEllipsis, &isExtern, &numArgs);
			
			if(vm->debug)
				printf("callp %s%s\n", isExtern ? "extern " : "", isExtern ? vm->externNames[id] : vm->functionNames[id]);
			
			if(isExtern)
				vm->externs[id](vm);
			else
			{
				if(!hasEllipsis)
				{
					if(nargs != numArgs)
					{
						fprintf(stderr, "Function '%s' expected %i args but recieved %i args\n", vm->functionNames[id], numArgs, nargs);
						exit(1);
					}
				}
				else
				{
					if(nargs < numArgs)
					{
						fprintf(stderr, "Function '%s' expected at least %i args but recieved %i args\n", vm->functionNames[id], numArgs, nargs);
						exit(1);
					}
				}
				
				if(!hasEllipsis) PushIndir(vm, nargs);
				else
				{
					// runtime collapsing of arguments:
					// the concrete arguments (known during compilation) are on the top of
					// the stack. We create an array (by pushing it and then decrementing the
					// stack pointer) and fill it up with the ellipsed arguments (behind the
					// concrete arguments). We then place this array just before the concrete
					// arguments in the stack so that it can be accessed as an argument "args".
					// The indirection info is pushed onto the indirection stack (the concrete and
					// non-concrete [aside from the one that the 'args' array replaces] are still 
					// present on the stack, so all of the arguments are to be removed)
					
					/*printf("args:\n");
					for(int i = 0; i < nargs; ++i)
					{
						WriteObject(vm, vm->stack[vm->stackSize - i - 1]);
						printf("\n");
					}
					printf("end\n");*/
					
					//printf("members:\n");
					Object* obj = PushArray(vm, nargs - numArgs);
					vm->stackSize -= 1;
					for(int i = 0; i < obj->array.length; ++i)
					{
						obj->array.members[i] = vm->stack[vm->stackSize - numArgs - 1 - i];
						/*WriteObject(vm, obj->array.members[i]);
						printf("\n");*/
					}
					//printf("end\n");
					
					vm->stack[vm->stackSize - numArgs - 1] = obj;
					
					/*printf("final args:\n");
					for(int i = 0; i < numArgs + 1; ++i)
					{
						WriteObject(vm, vm->stack[vm->stackSize - i - 1]);
						printf("\n");
					}
					printf("end\n");*/
					
					PushIndir(vm, nargs);
				}
				
				vm->pc = vm->functionPcs[id];
			}
		} break;
		
		case OP_RETURN:
		{
			if(vm->debug)
				printf("ret\n");
			PopIndir(vm);
		} break;
		
		case OP_RETURN_VALUE:
		{
			if(vm->debug)
				printf("retval\n");
			Object* returnValue = PopObject(vm);
			PopIndir(vm);
			PushObject(vm, returnValue);
		} break;
		
		case OP_CALLF:
		{
			++vm->pc;
			int index = ReadInteger(vm);
			if(vm->debug)
				printf("callf %s\n", vm->externNames[index]);
			vm->externs[index](vm);
		} break;

		case OP_GETLOCAL:
		{
			++vm->pc;
			int index = ReadInteger(vm);
			PushObject(vm, GetLocal(vm, index));
			if(vm->debug)
				printf("getlocal %i (fp: %i, stack size: %i)\n", index, vm->fp, vm->stackSize);
		} break;
		
		case OP_SETLOCAL:
		{
			if(vm->debug)
				printf("setlocal\n");
			++vm->pc;
			int index = ReadInteger(vm);
			SetLocal(vm, index, PopObject(vm));
		} break;
		
		case OP_HALT:
		{
			if(vm->debug)
				printf("halt\n");
			vm->pc = -1;
		} break;
		
		default:
			printf("Invalid instruction %i\n", vm->program[vm->pc]);
			break;
	}
}
Пример #11
0
void InitGameMemory(game_memory *Memory, Canvas &canvas)
{
	// �I�~�y���y�p�|�y�x�p���y��
	game_state* GameState = (game_state*)Memory->PermanentStorage;

	InitializeArena(&GameState->WorldArena, Memory->PermanentStorageSize - sizeof(game_state), (uint8*)Memory->PermanentStorage + sizeof(game_state));

	GameState->World = PushStruct(&GameState->WorldArena, world);
	world *World = GameState->World;
	World->TileMap = PushStruct(&GameState->WorldArena, tile_map);
	tile_map *TileMap = World->TileMap;

	GameState->Tick = 0;
	GameState->TimeElapsedFromLastTick = 0;

	// Camera 
	GameState->CameraPos.Tile = Vec2i(0, 0);
	GameState->CameraPos.TilePos = Vec2f(0, 0);
	GameState->CameraOrigin = GameState->ScreenSize / 2.0f;

	GameState->EntityToCameraIn = Rect(-7, -5, 7, 5);
	GameState->EntityToCameraOut = Rect(-8, -6, 8, 6);

	// �H�p�s�����x�y���� �������p�z����
	GameState->LoadGameSpriteFromImage(canvas, GameState->GameSprites.tmp_sprite, "sand_tile_01.png");
	GameState->LoadGameSpriteFromImage(canvas, GameState->GameSprites.tmp_object_sprite_001, "object_storage_01.png");
	GameState->LoadGameSpriteFromImage(canvas, GameState->GameSprites.tmp_object_sprite_stone1, "object_stone_01.png");
	GameState->LoadGameSpriteFromImage(canvas, GameState->GameSprites.tmp_player_image, "robot_base_horizontal.png");
	GameState->LoadGameSpriteFromImage(canvas, GameState->GameSprites.tmp_player_image_v, "robot_base_vertical.png");
	GameState->LoadGameSpriteFromImage(canvas, GameState->GameSprites.tmp_player_image_ur, "robot_base_diagonal_ur.png");
	GameState->LoadGameSpriteFromImage(canvas, GameState->GameSprites.tmp_player_image_ul, "robot_base_diagonal_ul.png");

	GameState->LoadGameSpriteFromResource(canvas, &GameState->game_resources, GameState->GameSprites.tmp_ground_sprite_01, "ground_concrete_tileset");
	GameState->AddGameSpriteFrameFromImage(canvas, GameState->GameSprites.tmp_ground_sprite_01, "ground_tile_01.png");

	GameState->LoadGameSpriteFromResource(canvas, &GameState->game_resources, GameState->GameSprites.tmp_player_image_torso, "robot_torso");
	GameState->LoadGameSpriteFromResource(canvas, &GameState->game_resources, GameState->GameSprites.tmp_player_image_track_down, "track_v_down");
	GameState->LoadGameSpriteFromResource(canvas, &GameState->game_resources, GameState->GameSprites.tmp_player_image_track_left, "track_h_left");
	GameState->LoadGameSpriteFromResource(canvas, &GameState->game_resources, GameState->GameSprites.tmp_player_image_track_right, "track_h_right");
	GameState->LoadGameSpriteFromResource(canvas, &GameState->game_resources, GameState->GameSprites.tmp_player_image_track_up, "track_v_up");
	GameState->LoadGameSpriteFromResource(canvas, &GameState->game_resources, GameState->GameSprites.tmp_player_image_track_ur, "track_d_ur");
	GameState->LoadGameSpriteFromResource(canvas, &GameState->game_resources, GameState->GameSprites.tmp_player_image_track_ul, "track_d_ul");
	GameState->LoadGameSpriteFromResource(canvas, &GameState->game_resources, GameState->GameSprites.tmp_player_image_track_br, "track_d_br");
	GameState->LoadGameSpriteFromResource(canvas, &GameState->game_resources, GameState->GameSprites.tmp_player_image_track_bl, "track_d_bl");

	GameState->LoadGameSpriteFromResource(canvas, &GameState->game_resources, GameState->GameSprites.tmp_wall_sprite1, "tileset_brick_wall");

	// Player entity
	//
	GameState->PlayerEntity = AddEntity(GameState);
	GameState->PlayerEntity->Position.Tile = Vec2i(0, 0);
	GameState->PlayerEntity->Position.TilePos = Vec2f(0, 0);
	GameState->PlayerEntity->EntityType = EntityType_Robot;
	GameState->PlayerEntity->CollisionType = 1;
	GameState->PlayerEntity->CollisionBox = Rectf(-0.45f, -0.25f, 0.45f, 0.25f);
	GameState->PlayerEntity->Controller.Active = 1;

	GameState->PlayerEntity->Mass = 20000.0f;
	GameState->PlayerEntity->RResistance = 0.008f;

	SetEntityToActive(GameState->PlayerEntity, GameState);

	World->TileSizeMeters = Vec2f(1.0f, 1.0f);
	World->TileSizePixels = Vec2f(100.0f, 100.0f);
	World->MetersToPixels = World->TileSizePixels / World->TileSizeMeters;

	World->g = 4.2f;

	TileMap->TileChunkSize = Vec2ui(16, 16);
	//TileMap->CenterChunkPosition = TileMap->TileChunksCount / (uint32)2;

	GameState->TilesOnHalfScreen.width = (int)((GameState->ScreenSize.width / 2) / World->TileSizePixels.x) + 1;
	GameState->TilesOnHalfScreen.height = (int)((GameState->ScreenSize.height / 2) / World->TileSizePixels.y) + 1;

	Vec2i TilesPerScreen = GameState->TilesOnHalfScreen * 2;

	for (int32 ScreenY = -16; ScreenY < 16; ScreenY++)
	{
		for (int32 ScreenX = -16; ScreenX < 16; ScreenX++)
		{
			for (int32 TY = 0; TY < TilesPerScreen.y; TY++)
			{
				for (int32 TX = 0; TX < TilesPerScreen.x; TX++)
				{
					int32 AbsTileX = ScreenX * TilesPerScreen.x + TX;
					int32 AbsTileY = ScreenY * TilesPerScreen.y + TY;

					SetTileValue(&GameState->WorldArena, TileMap, Vec2i(AbsTileX, AbsTileY), rand() % 16 + 1);
				}
			}
		}
	}
	/*
	for (int32 Y = 1; Y < 4; Y++)
	{
		for (int32 X = 1; X < 5; X++)
		{
			SetTileValue(&GameState->WorldArena, TileMap, Vec2i(X, Y), 5);
			SetTileValue(&GameState->WorldArena, TileMap, Vec2i(X - 7, Y), 5);
			SetTileValue(&GameState->WorldArena, TileMap, Vec2i(X - 5, Y + 6), 4);
		}
	}
	*/

	// Game entities
	GameState->TiledEntities.Entities = PushArray(&GameState->WorldArena, 4096, entity);
	GameState->TiledEntities.GroupSize = 4096;
	GameState->TiledEntities.EntityCount = 0;
	GameState->TiledEntities.NextGroup = 0;
	AddEntityToGroup(&GameState->WorldArena, &GameState->TiledEntities); // �N���|�u�r���z ���q���u�{�� �~�u �y�������|���x���u������

	// Add many stone entities
	world_position EntityPos;
	//Rectf CollisionBox(-0.4f, 0.0f, 0.4f, 0.3f);
	Rectf CollisionBox(-0.5f, -0.5f, 0.5f, 0.5f);
	for (int32 Y = 1; Y < 10; Y++)
	{
		for (int32 X = 1; X < 10; X++)
		{
			EntityPos.Tile = Vec2i(X, Y);
			EntityPos.TilePos = Vec2f(0, 0);

			uint32 StoneIndex = AddEntityToGroup(&GameState->WorldArena, &GameState->TiledEntities);
			entity *Entity = GetEntityFromGroupByIndex(&GameState->TiledEntities, StoneIndex);
			Entity->EntityType = EntityType_Storage;
			Entity->Position = EntityPos;
			Entity->CollisionType = 1;
			Entity->CollisionBox = CollisionBox;
			AddEntityToTile(GameState->World->TileMap, EntityPos.Tile, StoneIndex);
		}
	}

	/*
	EntityPos.Tile = Vec2i(1, 1);
	EntityPos.TilePos = Vec2f(0, 0);
	entity *Entity = AddEntity(GameState);
	Entity->EntityType = EntityType_Stone;
	Entity->Position = EntityPos;
	Entity->CollisionType = 1;
	Entity->CollisionBox = CollisionBox;
	//SetEntityToActive(Entity, GameState);

	/*
	Entity = AddEntity(GameState);
	Entity->EntityType = EntityType_Wall;
	EntityPos.Tile = Vec2i(0, -2);
	Entity->Position = EntityPos;
	Entity->CollisionType = 1;
	Entity->CollisionBox = Rectf(-0.5f, -0.1f, 0.5f, 0.1f);
	Entity->EntityFrame = 0;
	//SetEntityToActive(Entity, GameState);
	*/

	// Call to camera reset to activate entities in camera space
	MapEntitiesInCameraSpace(GameState);

	GameState->IsInitialized = 1;
}
Пример #12
0
// Returns true if it was added to at least one quadtree, false if you are trying to add out of bounds
static bool AddTile(TileGroup* tile_group, MemoryArena* arena, Tile* tile)
{
    if(!Contains(tile_group, tile->aabb))
    {
        // didn't add here, return false;
        return false;
    }

    if(IsLeaf(tile_group))
    {
        if(tile_group->contained_colliders < MAX_LEAF_SIZE)
        {
            tile_group->colliders[tile_group->contained_colliders] = tile;
            ++tile_group->contained_colliders;
        }
        else
        {
            // Split the node into 4
            Tile* temp_colliders[MAX_LEAF_SIZE];
            memcpy(temp_colliders, tile_group->colliders, sizeof(temp_colliders));

            tile_group->child_nodes = PushArray(arena, TileGroup, QUADTREE_CHILDREN);
            tile_group->is_parent = true;

            uint16 new_depth = tile_group->depth + 1;
            TileGroup* new_node = tile_group->child_nodes;

            Rectf r = tile_group->aabb;
            float half_width = r.w / 2.f;
            float half_height = r.h / 2.f;

            Rectf divided_rects[QUADTREE_CHILDREN] = {
                { r.x              , r.y              , half_width, half_height },
                { r.x + half_height, r.y              , half_width, half_height },
                { r.x              , r.y + half_height, half_width, half_height },
                { r.x + half_height, r.y + half_height, half_width, half_height },
            };

            for(uint32 i = 0; i < QUADTREE_CHILDREN; ++i, ++new_node)
            {
                new_node->aabb  = divided_rects[i];
                new_node->depth = new_depth;
                new_node->is_parent = false;
            }

            // Add the original tile that was passed in.
            AddTile(tile_group, arena, tile);

            // re-add the old pointers to the new child nodes.
            for(uint32 i = 0; i < MAX_LEAF_SIZE; ++i)
            {
                AddTile(tile_group, arena, temp_colliders[i]);
            }
        }
    }
    else
    { // Not a leaf, recurse
        TileGroup* child = tile_group->child_nodes;
        for(uint32 j = 0; j < QUADTREE_CHILDREN; ++j, ++child)
        {
            if(Contains(child, tile->aabb))
            {
                AddTile(child, arena, tile);
            }
        }
    }

    // Either added here or in a child
    return true;
}