Advertisement
Guest User

handmade.cpp

a guest
May 4th, 2016
283
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 29.14 KB | None | 0 0
  1. #include "anonhero.h"
  2.  
  3. #include "anontile.cpp"
  4.  
  5.  
  6. extern "C"
  7. GAME_GET_SOUND_SAMPLES(GameGetSoundSamples) {
  8.     game_state *state = (game_state *)memory->permanentStorage;
  9.     GameOutputSound(soundBuffer, state);
  10. }
  11.  
  12. void GameOutputSound(game_sound_buffer *sBuffer, game_state *state) {  
  13.     int16 *sampleOut = sBuffer->samples;
  14.     for(int sampleIndex = 0;
  15.             sampleIndex < sBuffer->sampleCount;
  16.             ++sampleIndex) {
  17.  
  18.             int16 sampleValue = 0;
  19.  
  20.             *sampleOut++ = sampleValue;  
  21.             *sampleOut++ = sampleValue;                            
  22.     }
  23. }
  24.  
  25. internal void
  26. DrawRectangle(game_offscreen_buffer *screen, vector realMin,
  27.                    vector realMax, real32 r, real32 g, real32 b)
  28. {  
  29.     int32 minX = RoundReal32ToInt32(realMin.x);
  30.     int32 minY = RoundReal32ToInt32(realMin.y);
  31.     int32 maxX = RoundReal32ToInt32(realMax.x);
  32.     int32 maxY = RoundReal32ToInt32(realMax.y);
  33.  
  34.     if(minX < 0)                {   minX = 0;    }
  35.     if(minY < 0)                {   minY = 0;    }
  36.     if(maxX > screen->width)    {   maxX = screen->width;   }
  37.     if(maxY > screen->height)   {   maxY = screen->height;  }
  38.  
  39.     uint32 color = (    (RoundReal32ToUInt32(r * 255.0f) << 16) |
  40.                         (RoundReal32ToUInt32(g * 255.0f) << 8 ) |
  41.                         (RoundReal32ToUInt32(b * 255.0f) << 0 )
  42.                    );
  43.  
  44.     uint8 *row = ((uint8 *)screen->memory +
  45.                            minX * screen->bytesPerPixel +
  46.                            minY * screen->pitch);
  47.  
  48.     for(int y = minY; y < maxY; ++y)
  49.     {    
  50.         uint32 *pixel = (uint32 *)row;                    
  51.         for(int x = minX; x < maxX; ++x)      
  52.         {                                                                        
  53.             *pixel++ = color;  
  54.         }      
  55.         row += screen->pitch;
  56.    }
  57. }
  58.  
  59. #pragma pack(push, 1)
  60. struct bitmap_header
  61. {  
  62.     uint16 fileType;
  63.     uint32 fileSize;
  64.     uint16 reservedOne;
  65.     uint16 reservedTwo;
  66.     uint32 bitmapOffset;
  67.     uint32 size;
  68.     int32 width;
  69.     int32 height;
  70.     uint16 planes;
  71.     uint16 bitsPerPixel;
  72.     uint32 compression;
  73.     uint32 sizeOfBitmap;
  74.     int32 horzResolution;
  75.     int32 vertResolution;
  76.     uint32 colorsUsed;
  77.     uint32 colorsImportant;
  78.  
  79.     uint32 redMask;
  80.     uint32 greenMask;
  81.     uint32 blueMask;
  82. };
  83. #pragma pack(pop)
  84.  
  85. internal loaded_bitmap
  86. LoadBitmap(thread_context *thread, debug_platform_read_entire_file *ReadEntireFile, char *fileName)
  87. {
  88.     loaded_bitmap bitmap = {};
  89.    
  90.     debug_read_file_result readResult = ReadEntireFile(thread, fileName);
  91.  
  92.     if(readResult.contentSize != 0)
  93.     {      
  94.         bitmap_header *header = (bitmap_header *)readResult.contents;
  95.         uint32 *pixels = (uint32 *)((uint8 *)readResult.contents + header->bitmapOffset);
  96.         bitmap.pixels = pixels;
  97.         bitmap.width = header->width;
  98.         bitmap.height = header->height;    
  99.  
  100.         if(header->compression == 3)
  101.         {
  102.             uint32 redMask = header->redMask;
  103.             uint32 greenMask = header->greenMask;
  104.             uint32 blueMask = header->blueMask;
  105.             uint32 alphaMask = ~(redMask | greenMask | blueMask);
  106.  
  107.             bit_scan_result redShift = FindLeastSignificantSetBit(redMask);
  108.             bit_scan_result greenShift = FindLeastSignificantSetBit(greenMask);
  109.             bit_scan_result blueShift = FindLeastSignificantSetBit(blueMask);
  110.             bit_scan_result alphaShift = FindLeastSignificantSetBit(alphaMask);    
  111.  
  112.             Assert(redShift.found);
  113.             Assert(greenShift.found);
  114.             Assert(blueShift.found);
  115.             Assert(alphaShift.found);      
  116.  
  117.             uint32 *sourceDest = pixels;
  118.             for(int32 y = 0; y < header->height; ++y)
  119.             {
  120.                 for(int32 x = 0; x < header->width; ++x)
  121.                 {
  122.                     uint32 col = *sourceDest;
  123.                     *sourceDest++ = ((((col >> alphaShift.index) & 0xff) << 24) |
  124.                                     (((col >> redShift.index) & 0xff) << 16)    |
  125.                                     (((col >> greenShift.index) & 0xff) << 8)   |
  126.                                     (((col >> blueShift.index) & 0xff) << 0));  
  127.                 }
  128.             }
  129.         }
  130.     }
  131.  
  132.     return(bitmap);
  133. }
  134.  
  135. internal void
  136. DrawBitmap(game_offscreen_buffer *buffer, loaded_bitmap *bitmap, vector pos, int32 alignX = 0, int32 alignY = 0)
  137. {  
  138.     pos.x -= (real32)alignX;
  139.     pos.y -= (real32)alignY;
  140.  
  141.     int32 minX = RoundReal32ToInt32(pos.x);
  142.     int32 minY = RoundReal32ToInt32(pos.y);
  143.     int32 maxX = minX + bitmap->width;
  144.     int32 maxY = minY + bitmap->height;
  145.  
  146.     int32 sourceOffsetX = 0;  
  147.    
  148.     if(minX < 0)               
  149.     {  
  150.         sourceOffsetX = -minX;
  151.         minX = 0;    
  152.     }
  153.    
  154.     int32 sourceOffsetY = 0;
  155.    
  156.     if(minY < 0)               
  157.     {  
  158.         sourceOffsetY = -minY;
  159.         minY = 0;
  160.     }
  161.  
  162.     if(maxX > buffer->width)    {   maxX = buffer->width;   }
  163.     if(maxY > buffer->height)   {   maxY = buffer->height;  }  
  164.  
  165.  
  166.     uint32 *sourceRow = bitmap->pixels + bitmap->width * (bitmap->height - 1); 
  167.     sourceRow += -sourceOffsetY * bitmap->width + sourceOffsetX;
  168.     uint8 *destRow = ((uint8 *)buffer->memory +
  169.                      minX * buffer->bytesPerPixel +
  170.                      minY * buffer->pitch);
  171.  
  172.     for(int y = minY; y < maxY; ++y)
  173.     {
  174.         uint32 *dest = (uint32 *)destRow;
  175.         uint32 *source = sourceRow;
  176.         for(int x = minX; x < maxX; ++x)
  177.         {
  178.             real32 alpha = (real32)((*source >> 24) & 0xff) /255.0f;
  179.             real32 sourceRed = (real32)((*source >> 16) & 0xff);
  180.             real32 sourceGreen = (real32)((*source >> 8) & 0xff);
  181.             real32 sourceBlue = (real32)((*source >> 0) & 0xff);
  182.            
  183.             real32 destRed = (real32)((*dest >> 16) & 0xff);
  184.             real32 destGreen = (real32)((*dest >> 8) & 0xff);
  185.             real32 destBlue = (real32)((*dest >> 0) & 0xff);
  186.  
  187.             real32 r = alpha + (1.0f - alpha) * destRed + alpha * sourceRed;
  188.             real32 g = alpha + (1.0f - alpha) * destGreen + alpha * sourceGreen;
  189.             real32 b = alpha + (1.0f - alpha) * destBlue + alpha * sourceBlue;
  190.  
  191.             *dest = ( (uint32)(r + 0.5f) << 16 |
  192.                       (uint32)(g + 0.5f) << 8  |
  193.                       (uint32)(b + 0.5f) << 0 );
  194.            
  195.             ++dest;
  196.             ++source;
  197.         }
  198.  
  199.         destRow += buffer->pitch;
  200.         sourceRow -= bitmap->width;
  201.     }
  202. }
  203. internal void
  204. ChangeEntityResidence(game_state* state, uint32 entityIndex, entity_residence residence)
  205. {
  206.     if(residence == EntityResidenceHigh)
  207.     {
  208.         if(state->entityResidence[entityIndex] != EntityResidenceHigh)
  209.         {
  210.             high_entity *highEntity = &state->highEntities[entityIndex];
  211.             dormant_entity *dormantEntity = &state->dormantEntities[entityIndex];
  212.             tile_map_difference diff = SubtractInReal32(state->world->tileMap, &dormantEntity->tilePos, &state->cameraPos);
  213.             highEntity->pos = diff.dxy;
  214.             highEntity->vel = Vector(0);
  215.             highEntity->absTileZ = dormantEntity->tilePos.absTileZ;
  216.             highEntity->facingDirection = 0;
  217.         }
  218.     }
  219.     state->entityResidence[entityIndex] = residence;
  220. }
  221.  
  222. inline entity
  223. GetEntity(game_state *state, entity_residence residence, uint32 index)
  224. {
  225.     entity ent = {};
  226.    
  227.     if((index > 0) && (index < state->entityCount))
  228.     {
  229.         if(state->entityResidence[index] < residence)
  230.         {
  231.             ChangeEntityResidence(state, index, residence);
  232.             Assert(state->entityResidence[index] >= residence);
  233.         }
  234.         ent.residence = residence;
  235.         ent.dormant = &state->dormantEntities[index];
  236.         ent.low = &state->lowEntities[index];
  237.         ent.high = &state->highEntities[index];    
  238.     }
  239.  
  240.     return ent;
  241. }
  242.  
  243. internal void
  244. InitializePlayer(game_state *state, uint32 entityIndex)
  245. {  
  246.     entity ent = GetEntity(state, EntityResidenceDormant, entityIndex);    
  247.  
  248.     ent.dormant->tilePos.absTileX = 2;
  249.     ent.dormant->tilePos.absTileY = 3;     
  250.     ent.dormant->tilePos.offset.x = 0.0f;
  251.     ent.dormant->tilePos.offset.y = 0.0f;  
  252.     ent.dormant->height = 0.5f;
  253.     ent.dormant->width = 1.0f; 
  254.     ent.dormant->collides = true;
  255.     ent.high->facingDirection = 0;
  256.  
  257.     ChangeEntityResidence(state, entityIndex, EntityResidenceHigh);
  258.  
  259.     if(GetEntity(state, EntityResidenceHigh, state->cameraFollowingEntityIndex).residence == EntityResidenceNonexistent)
  260.     {
  261.         state->cameraFollowingEntityIndex = entityIndex;
  262.     }  
  263. }
  264.  
  265. internal uint32
  266. AddEntity(game_state *state, entity_type type){
  267.     uint32 entityIndex = state->entityCount++;
  268.  
  269.     Assert(state->entityCount < ArrayCount(state->dormantEntities));
  270.     Assert(state->entityCount < ArrayCount(state->lowEntities));
  271.     Assert(state->entityCount < ArrayCount(state->highEntities));
  272.  
  273.     state->entityResidence[entityIndex] = EntityResidenceDormant;
  274.     state->dormantEntities[entityIndex] = {};
  275.     state->lowEntities[entityIndex] = {};
  276.     state->highEntities[entityIndex] = {}; 
  277.     state->dormantEntities[entityIndex].type = type;
  278.  
  279.     return entityIndex;
  280. }
  281.  
  282. internal uint32
  283. AddWall(game_state *state, uint32 absTileX, uint32 absTileY, uint32 absTileZ)
  284. {
  285.     uint32 entityIndex = AddEntity(state, EntityType_Wall);
  286.     entity ent = GetEntity(state, EntityResidenceDormant, entityIndex);
  287.     ent.dormant->tilePos.absTileX = absTileX;
  288.     ent.dormant->tilePos.absTileY = absTileY;
  289.     ent.dormant->tilePos.absTileZ = absTileZ;
  290.     ent.dormant->height = state->world->tileMap->tileSideInMeters;
  291.     ent.dormant->width = ent.dormant->height;
  292.     ent.dormant->collides = true;
  293.  
  294.     return entityIndex;
  295. }
  296.  
  297. internal uint32
  298. AddPlayer(game_state *state)
  299. {
  300.     uint32 entityIndex = AddEntity(state, EntityType_Player);
  301.     entity ent = GetEntity(state, EntityResidenceDormant, entityIndex);
  302.     ent.dormant->tilePos.absTileX = 1;
  303.     ent.dormant->tilePos.absTileY = 3;
  304.     ent.dormant->tilePos.offset.x = 0;
  305.     ent.dormant->tilePos.offset.y = 0;
  306.     ent.dormant->height = 0.5f;
  307.     ent.dormant->width = 1.0f;
  308.     ent.dormant->collides = true;
  309.  
  310.     ChangeEntityResidence(state, entityIndex, EntityResidenceHigh);
  311.  
  312.     if(GetEntity(state, EntityResidenceDormant, state->cameraFollowingEntityIndex).residence == EntityResidenceNonexistent)
  313.     {
  314.         state->cameraFollowingEntityIndex = entityIndex;
  315.     }
  316.  
  317.     return entityIndex;
  318. }
  319.  
  320. internal bool
  321. TestWall(real32 wallX,  real32 relX, real32 relY, real32 playerDeltaX, real32 playerDeltaY, real32 *tMin, real32 minY, real32 maxY)
  322. {  
  323.     bool hit = false;
  324.     real32 epsilon = 0.001f;
  325.     if(playerDeltaX != 0.0f)
  326.     {
  327.         real32 tResult = (wallX - relX) / playerDeltaX;
  328.         real32 y = relY + tResult * playerDeltaY;
  329.         if((tResult >= 0.0f) && (*tMin > tResult))
  330.         {                  
  331.             if(y >= minY && y <= maxY)
  332.             {
  333.                 *tMin = Maximum(0.0f, tResult - epsilon);
  334.                 hit = true;
  335.             }
  336.         }
  337.     }
  338.     return hit;
  339. }
  340.  
  341. internal void
  342. MovePlayer(game_state *state, entity ent, real32 dt, vector acceleration)
  343. {
  344.     tile_map *tileMap = state->world->tileMap;
  345.  
  346.     real32 accLen = LengthSquared(acceleration);
  347.     if(accLen > 1.0f)
  348.     {
  349.         acceleration *= (1.0f / SquareRoot(accLen));
  350.     }  
  351.  
  352.     real32 playerSpeed = 50.0f;
  353.     acceleration *= playerSpeed;
  354.            
  355.     high_entity *highEntity = ent.high;
  356.            
  357.     acceleration+= -8.0f * highEntity->vel;
  358.  
  359.     vector oldPlayerPos = highEntity->pos;
  360.     vector playerDelta = 0.5f * acceleration * Square(dt) + highEntity->vel * dt;
  361.     highEntity->vel = acceleration * dt + highEntity->vel;
  362.  
  363.     vector newPlayerPos = oldPlayerPos + playerDelta;
  364.     /*
  365.     uint32 minTileX = Minimum(oldPlayerPos.absTileX, newPlayerPos.absTileX);
  366.     uint32 minTileY = Minimum(oldPlayerPos.absTileY, newPlayerPos.absTileY);
  367.     uint32 maxTileX = Maximum(oldPlayerPos.absTileX, newPlayerPos.absTileX);
  368.     uint32 maxTileY = Maximum(oldPlayerPos.absTileY, newPlayerPos.absTileY);
  369.  
  370.     uint32 entityTileWidth = CeilReal32ToInt32(entity.dormant->width / tileMap->tileSideInMeters);
  371.     uint32 entityTileHeight = CeilReal32ToInt32(entity.dormant->height / tileMap->tileSideInMeters);
  372.  
  373.     minTileX -= entityTileWidth;
  374.     minTileY -= entityTileHeight;
  375.     maxTileX += entityTileWidth;
  376.     maxTileY += entityTileHeight;
  377.  
  378.     uint32 absTileZ = highEntity->pos.absTileZ;
  379.     */
  380.  
  381.     for(uint32 iteration = 0; iteration < 4; iteration++)
  382.     {
  383.         real32 tMin = 1.0f;
  384.         vector wallNormal = Vector(0, 0);  
  385.         uint32 hitEntityIndex = 0;
  386.  
  387.         vector desiredPosition = highEntity->pos + playerDelta;
  388.  
  389.         for(uint32 entityIndex = 1; entityIndex < state->entityCount; ++entityIndex)
  390.         {      
  391.             entity testEntity = GetEntity(state, EntityResidenceDormant, entityIndex);
  392.             if(testEntity.high != ent.high)
  393.             {
  394.                 if(testEntity.dormant->collides)
  395.                 {
  396.                     real32 diameterW = testEntity.dormant->width + ent.dormant->width;
  397.                     real32 diameterH = testEntity.dormant->height + ent.dormant->height;   
  398.  
  399.                     vector minCorner = Vector(diameterW, diameterH) * -0.5f;
  400.                     vector maxCorner = Vector(diameterW, diameterH) * 0.5f;    
  401.  
  402.                     vector rel = highEntity->pos - testEntity.high->pos;
  403.                
  404.                     if(TestWall(minCorner.x, rel.x, rel.y, playerDelta.x, playerDelta.y, &tMin, minCorner.y, maxCorner.y))
  405.                     {
  406.                         wallNormal = Vector(-1, 0);
  407.                         hitEntityIndex = entityIndex;
  408.                     }
  409.                     if(TestWall(maxCorner.x, rel.x, rel.y, playerDelta.x, playerDelta.y, &tMin, minCorner.y, maxCorner.y))
  410.                     {
  411.                         wallNormal = Vector(1, 0);
  412.                         hitEntityIndex = entityIndex;
  413.                     }
  414.                     if(TestWall(minCorner.y, rel.y, rel.x, playerDelta.y, playerDelta.x, &tMin, minCorner.x, maxCorner.x))
  415.                     {
  416.                         wallNormal = Vector(0, -1);
  417.                         hitEntityIndex = entityIndex;
  418.                     }
  419.                     if(TestWall(maxCorner.y, rel.y, rel.x, playerDelta.y, playerDelta.x, &tMin, minCorner.x, maxCorner.x))
  420.                     {
  421.                         wallNormal = Vector(0, 1);
  422.                         hitEntityIndex = entityIndex;
  423.                     }                              
  424.                 }
  425.             }
  426.         }  
  427.  
  428.         highEntity->pos += tMin * playerDelta;
  429.         if(hitEntityIndex)
  430.         {
  431.             highEntity->vel = highEntity->vel - 1 * Dot(highEntity->vel, wallNormal) * wallNormal;
  432.             playerDelta = desiredPosition - highEntity->pos;
  433.             playerDelta = playerDelta - 1 * Dot(playerDelta, wallNormal) * wallNormal;
  434.            
  435.             entity hitEntity = GetEntity(state, EntityResidenceDormant, hitEntityIndex);
  436.             highEntity->absTileZ += hitEntity.dormant->dAbsTileZ;      
  437.         }
  438.         else
  439.         {
  440.             break;
  441.         }              
  442.     }
  443.  
  444.     if((highEntity->vel.x == 0.0f) && (highEntity->vel.y == 0.0f))
  445.     {
  446.  
  447.     }
  448.     else if(AbsoluteValue(highEntity->vel.x) > AbsoluteValue(highEntity->vel.y))
  449.     {
  450.         if(highEntity->vel.x > 0)
  451.         {
  452.             highEntity->facingDirection = 3;
  453.         }
  454.         else
  455.         {
  456.             highEntity->facingDirection = 2;
  457.         }
  458.     }
  459.     else
  460.     {
  461.         if(highEntity->vel.y > 0)
  462.         {
  463.             highEntity->facingDirection = 1;
  464.         }
  465.         else
  466.         {
  467.             highEntity->facingDirection = 0;
  468.         }
  469.     }  
  470.     ent.dormant->tilePos = MapIntoTileSpace(state->world->tileMap, state->cameraPos, ent.high->pos);       
  471. }
  472.  
  473. internal void
  474. SetCamera(game_state *state, tile_map_position newCameraPos)
  475. {
  476.     tile_map *tileMap = state->world->tileMap;
  477.     tile_map_difference dCameraPos = SubtractInReal32(tileMap, &newCameraPos, &state->cameraPos);
  478.     state->cameraPos = newCameraPos;
  479.  
  480.     uint32 tileSpanX = 17 * 3;
  481.     uint32 tileSpanY = 9 * 3;
  482.     rectangle cameraBounds = RectCenterDim(Vector(0, 0),
  483.                                             tileMap->tileSideInMeters * Vector((real32)tileSpanX, (real32)tileSpanY));
  484.    
  485.     vector entityOffsetForFrame = -dCameraPos.dxy;
  486.     for (uint32 entityIndex = 1; entityIndex < ArrayCount(state->highEntities); entityIndex++)
  487.     {
  488.         if(state->entityResidence[entityIndex] == EntityResidenceHigh)
  489.         {
  490.             high_entity *high = state->highEntities + entityIndex;
  491.             high->pos += entityOffsetForFrame;
  492.  
  493.             if(!InRectangle(cameraBounds, high->pos))
  494.             {
  495.                 ChangeEntityResidence(state, entityIndex, EntityResidenceDormant);
  496.             }
  497.         }
  498.     }
  499.  
  500.     uint32 minTileX = newCameraPos.absTileX - tileSpanX / 2;
  501.     uint32 maxTileX = newCameraPos.absTileX + tileSpanX / 2;
  502.     uint32 minTileY = newCameraPos.absTileY - tileSpanY / 2;
  503.     uint32 maxTileY = newCameraPos.absTileY + tileSpanY / 2;
  504.  
  505.     for(uint32 entityIndex = 1; entityIndex < ArrayCount(state->dormantEntities);++entityIndex)
  506.     {
  507.         if(state->entityResidence[entityIndex] == EntityResidenceDormant)
  508.         {
  509.             dormant_entity *dormant = state->dormantEntities + entityIndex;
  510.                
  511.             if((dormant->tilePos.absTileZ == newCameraPos.absTileZ) &&
  512.                     (dormant->tilePos.absTileX >= minTileX) && (dormant->tilePos.absTileX <= maxTileX) &&
  513.                     (dormant->tilePos.absTileY <= minTileY) && (dormant->tilePos.absTileY >= maxTileY))
  514.             {
  515.                 ChangeEntityResidence(state, entityIndex, EntityResidenceHigh);
  516.             }
  517.         }
  518.     }      
  519. }
  520.  
  521. extern "C"
  522. GAME_UPDATE_AND_RENDER(GameUpdateAndRender)
  523. {
  524.     Assert(sizeof(game_state) <= memory->permanentStorageSize);
  525.     game_state *state = (game_state *)memory->permanentStorage;    
  526.    
  527.     if(!memory->isInitialized)
  528.     {  
  529.         AddEntity(state, EntityType_NULL);
  530.  
  531.         state->background = LoadBitmap(thread, memory->DEBUGPlatformReadEntireFile, "../data/test_background.bmp");    
  532.         state->shadow = LoadBitmap(thread, memory->DEBUGPlatformReadEntireFile, "../data/test_hero_shadow.bmp");
  533.  
  534.         player_bitmaps *bitmap;
  535.  
  536.         bitmap = state->playerBitmaps;
  537.  
  538.         bitmap->head = LoadBitmap(thread, memory->DEBUGPlatformReadEntireFile, "../data/test_hero_front_head.bmp");
  539.         bitmap->cape = LoadBitmap(thread, memory->DEBUGPlatformReadEntireFile, "../data/test_hero_front_cape.bmp");
  540.         bitmap->torso = LoadBitmap(thread, memory->DEBUGPlatformReadEntireFile, "../data/test_hero_front_torso.bmp");
  541.         bitmap->alignX = 72;
  542.         bitmap->alignY = 182;
  543.         ++bitmap;
  544.  
  545.         bitmap->head = LoadBitmap(thread, memory->DEBUGPlatformReadEntireFile, "../data/test_hero_back_head.bmp");
  546.         bitmap->cape = LoadBitmap(thread, memory->DEBUGPlatformReadEntireFile, "../data/test_hero_back_cape.bmp");
  547.         bitmap->torso = LoadBitmap(thread, memory->DEBUGPlatformReadEntireFile, "../data/test_hero_back_torso.bmp");
  548.         bitmap->alignX = 72;
  549.         bitmap->alignY = 182;
  550.         ++bitmap;
  551.  
  552.         bitmap->head = LoadBitmap(thread, memory->DEBUGPlatformReadEntireFile, "../data/test_hero_left_head.bmp");
  553.         bitmap->cape = LoadBitmap(thread, memory->DEBUGPlatformReadEntireFile, "../data/test_hero_left_cape.bmp");
  554.         bitmap->torso = LoadBitmap(thread, memory->DEBUGPlatformReadEntireFile, "../data/test_hero_left_torso.bmp");
  555.         bitmap->alignX = 72;
  556.         bitmap->alignY = 182;
  557.         ++bitmap;
  558.  
  559.         bitmap->head = LoadBitmap(thread, memory->DEBUGPlatformReadEntireFile, "../data/test_hero_right_head.bmp");
  560.         bitmap->cape = LoadBitmap(thread, memory->DEBUGPlatformReadEntireFile, "../data/test_hero_right_cape.bmp");
  561.         bitmap->torso = LoadBitmap(thread, memory->DEBUGPlatformReadEntireFile, "../data/test_hero_right_torso.bmp");
  562.         bitmap->alignX = 72;
  563.         bitmap->alignY = 182;      
  564.    
  565.         InitializeArena(&state->worldArena, memory->permanentStorageSize - sizeof(game_state),
  566.                         (uint8 *)memory->permanentStorage + sizeof(game_state));
  567.  
  568.         state->world = PushStruct(&state->worldArena, world_struct);
  569.         world_struct *world = state->world;
  570.         world->tileMap = PushStruct(&state->worldArena, tile_map);
  571.        
  572.         tile_map *tileMap = world->tileMap;
  573.  
  574.         tileMap->tileSideInMeters = 1.4f;
  575.    
  576.         tileMap->chunkShift = 4;
  577.         tileMap->chunkMask = (1 << tileMap->chunkShift) - 1;
  578.         tileMap->chunkDim = (1 << tileMap->chunkShift);
  579.  
  580.         tileMap->tileChunkCountX = 128;
  581.         tileMap->tileChunkCountY = 128;
  582.  
  583.         tileMap->tileChunkCountZ = 2;
  584.  
  585.         tileMap->tileChunks = PushArray(&state->worldArena, tileMap->tileChunkCountX *
  586.                                                             tileMap->tileChunkCountY *
  587.                                                             tileMap->tileChunkCountZ, tile_chunk);
  588.  
  589.         uint32 tilesPerWidth = 17;
  590.         uint32 tilesPerHeight = 9;
  591.  
  592.         //uint32 screenX = INT32_MAX / 2;
  593.         //uint32 screenY = INT32_MAX / 2;
  594.  
  595.         uint32 screenX = 0;
  596.         uint32 screenY = 0;
  597.  
  598.         uint32 randomNumberIndex = 0;
  599.  
  600.         global_var uint32 randomNumberTable[] =
  601.         {
  602.             8314, 44235, 21701, 17516, 43092, 33335, 97299, 22848, 80141,
  603.             61410, 48723, 4181, 24414, 45859, 87211, 65608, 76049, 18534,
  604.             91995, 97499, 33980, 2504, 3073, 34617, 98205, 92770, 19378,
  605.             78030, 68726, 89330, 43046, 27738, 44474, 93254, 73010, 84810,
  606.             27585, 2405, 9268, 47108, 16991, 17851, 50754, 15701, 11624,
  607.             40660, 99603, 90590, 13621, 68696, 54747, 72842, 21912, 3027,
  608.             16186, 60320, 36499, 43653, 82852, 54094, 57380, 90575, 56881,
  609.             54163, 83489, 44859, 37205, 61595, 16961, 4371, 23824, 74254,
  610.             56728, 70177, 15671, 93208, 1722, 43347, 14880, 18458, 54079,
  611.             21744, 20385, 51070, 12731, 6436, 32185, 88909, 77678, 97423,
  612.             49211, 33044, 48921, 94705, 73701, 83474, 25390, 99350, 4287,
  613.             53173, 83389, 44859, 37205, 71595, 17961, 4171, 21824, 74254,
  614.             56728, 70177, 15671, 91208, 1722, 41147, 14880, 18458, 54079,
  615.             21744, 20185, 51070, 12711, 6416, 12185, 8909, 77678, 7423,
  616.             69211, 33066, 68921, 96705, 73601, 83674, 23390, 99350, 12354
  617.         };
  618.  
  619.         uint32 absTileZ = 0;
  620.  
  621.         bool32 doorLeft = false;
  622.         bool32 doorRight = false;
  623.         bool32 doorTop = false;
  624.         bool32 doorBottom = false;
  625.         bool32 doorUp = false;
  626.         bool32 doorDown = false;
  627.  
  628.         for(uint32 screenIndex = 0; screenIndex < 2; ++screenIndex)
  629.         {              
  630.  
  631.             Assert(randomNumberIndex < ArrayCount(randomNumberTable));
  632.             uint32 randomChoice = randomNumberTable[randomNumberIndex++] % 2;
  633.  
  634.             if(doorUp || doorDown)
  635.             {
  636.                 randomChoice = randomNumberTable[randomNumberIndex++] % 2; 
  637.             }
  638. #if 0
  639.             else
  640.             {
  641.                 randomChoice = randomNumberTable[randomNumberIndex++] % 3;
  642.             }
  643. #endif
  644.             bool32 createdZDoor = false;
  645.             if(randomChoice == 2)
  646.             {
  647.                 createdZDoor = true;
  648.                 if(absTileZ == 0)
  649.                 {
  650.                     doorUp = true;
  651.                 }
  652.                 else
  653.                 {
  654.                     doorDown = true;
  655.                 }
  656.             }
  657.             else if(randomChoice == 1)
  658.             {
  659.                 doorRight = true;
  660.             }
  661.             else
  662.             {
  663.                 doorTop = true;
  664.             }
  665.            
  666.             for(uint32 tileY = 0; tileY < tilesPerHeight; ++tileY)
  667.             {
  668.                 for(uint32 tileX = 0; tileX < tilesPerWidth; ++tileX)
  669.                 {                      
  670.                     uint32 absTileX = screenX * tilesPerWidth + tileX;
  671.                     uint32 absTileY = screenY * tilesPerHeight + tileY;
  672.                                        
  673.                     uint32 tileValue = 1;
  674.                     if(tileX == 0 && (!doorLeft || (tileY != tilesPerHeight / 2)))
  675.                     {          
  676.                         tileValue = 2;
  677.                     }                              
  678.                      
  679.                     if(tileX == (tilesPerWidth - 1) && (!doorRight || (tileY != tilesPerHeight / 2)))
  680.                     {                                      
  681.                         tileValue = 2;
  682.                     }                      
  683.                    
  684.                     if(tileY == 0 && (!doorBottom || (tileX != tilesPerWidth / 2)))
  685.                     {          
  686.                         tileValue = 2;
  687.                     }                              
  688.                      
  689.                     if(tileY == (tilesPerHeight - 1) && (!doorTop || (tileX != tilesPerWidth / 2)))
  690.                     {                                      
  691.                         tileValue = 2;
  692.                     }
  693.  
  694.                     if(tileX == 10 && tileY == 6)
  695.                     {
  696.                         if(doorUp)
  697.                         {
  698.                             tileValue = 3;
  699.                         }
  700.                         if(doorDown)
  701.                         {
  702.                             tileValue = 4;
  703.                         }
  704.                     }
  705.  
  706.                     SetTileValue(&state->worldArena, world->tileMap, absTileX, absTileY, absTileZ, tileValue);
  707.                     if(tileValue == 2)
  708.                     {
  709.                         AddWall(state, absTileX, absTileY, absTileZ);
  710.                     }
  711.                 }
  712.             }
  713.                    
  714.             doorLeft = doorRight;
  715.             doorBottom = doorTop;
  716.            
  717.             if(createdZDoor)
  718.             {                  
  719.                 doorDown = !doorDown;
  720.                 doorUp = !doorUp;                          
  721.             }
  722.             else
  723.             {
  724.                 doorUp = false;
  725.                 doorDown = false;
  726.             }
  727.  
  728.             doorRight = false;
  729.             doorTop = false;
  730.            
  731.             if(randomChoice == 2)
  732.             {
  733.                 if(absTileZ == 0)
  734.                 {
  735.                     absTileZ = 1;
  736.                 }
  737.                 else
  738.                 {
  739.                     absTileZ = 0;
  740.                 }
  741.             }                      
  742.             else if(randomChoice == 1)
  743.             {
  744.                 screenX++;
  745.             }  
  746.             else
  747.             {
  748.                 screenY++;
  749.             }      
  750.         }
  751.  
  752.         tile_map_position newCameraPos = {};
  753.         newCameraPos.absTileX = 17/2;
  754.         newCameraPos.absTileY = 9/2;
  755.         SetCamera(state, newCameraPos);
  756.  
  757.         memory->isInitialized = true;      
  758.     }
  759.    
  760.     world_struct *world = state->world;
  761.     tile_map *tileMap = world->tileMap;
  762.  
  763.     int32 tileSideInPixels = 60;   
  764.     real32 metersToPixels = (real32)tileSideInPixels / tileMap->tileSideInMeters;
  765.  
  766.     real32 lowerLeftX = -(real32)tileSideInPixels / 2;
  767.     real32 lowerLeftY = (real32)buffer->height;
  768.    
  769.     for(int controllerIndex = 0; controllerIndex < ArrayCount(input->controllers); ++controllerIndex)
  770.     {
  771.         game_controller_input *controller = GetController(input, controllerIndex);
  772.  
  773.         entity controllingEntity = GetEntity(state, EntityResidenceHigh, state->playerIndexForController[controllerIndex]);
  774.  
  775.         if(controllingEntity.residence != EntityResidenceNonexistent)
  776.         {
  777.             state->cameraFollowingEntityIndex = state->playerIndexForController[controllerIndex];
  778.             vector acceleration = {};       //ddPlayer in handmade
  779.  
  780.             if(controller->isAnalog) {
  781.                 //acceleration = Vector(controller->stickAverageX, controller->stickAverageY)  // No gamepad code yet!
  782.             }
  783.             else
  784.             {
  785.                 if (controller->moveDown.endedDown)
  786.                 {      
  787.                     acceleration.y = -1.0f;
  788.                 }
  789.                 if (controller->moveUp.endedDown)  
  790.                 {      
  791.                     acceleration.y = 1.0f;
  792.                 }
  793.                 if (controller->moveLeft.endedDown)  
  794.                 {      
  795.                     acceleration.x = -1.0f;
  796.                 }
  797.                 if (controller->moveRight.endedDown)
  798.                 {  
  799.                     acceleration.x = 1.0f;
  800.                 }
  801.             }
  802.  
  803.             if(controller->actionUp.endedDown)
  804.             {
  805.                 controllingEntity.high->dz = 3.5f;
  806.             }
  807.  
  808.             MovePlayer(state, controllingEntity, input->dt, acceleration);     
  809.         }
  810.         else
  811.         {
  812.             if(controller->start.endedDown)
  813.             {
  814.                 uint32 entityIndex = AddPlayer(state);
  815.                 // TEST: controllingEntity = GetEntity(state, EntityResidenceDormant, entityIndex);            
  816.                 // TEST: InitializePlayer(state, entityIndex);
  817.                 state->playerIndexForController[controllerIndex] = entityIndex;
  818.             }                                      
  819.         }
  820.     }      
  821.  
  822.     vector entityOffset = {};
  823.     entity cameraFollowingEntity = GetEntity(state, EntityResidenceHigh, state->cameraFollowingEntityIndex);
  824.     if(cameraFollowingEntity.residence != EntityResidenceNonexistent)
  825.     {
  826.         tile_map_position newCameraPos = state->cameraPos;
  827.  
  828.         newCameraPos.absTileZ = cameraFollowingEntity.dormant->tilePos.absTileZ;
  829. #if 1              
  830.         if(cameraFollowingEntity.high->pos.x > (9.0f * tileMap->tileSideInMeters))
  831.         {
  832.             newCameraPos.absTileX += 17;
  833.         }
  834.         if(cameraFollowingEntity.high->pos.x < -(9.0f * tileMap->tileSideInMeters))
  835.         {
  836.             newCameraPos.absTileX -= 17;
  837.         }
  838.         if(cameraFollowingEntity.high->pos.y > (5.0f * tileMap->tileSideInMeters))
  839.         {
  840.             newCameraPos.absTileY += 9;
  841.         }
  842.         if(cameraFollowingEntity.high->pos.y < -(5.0f * tileMap->tileSideInMeters))
  843.         {
  844.             newCameraPos.absTileY -= 9;
  845.         }  
  846. #else
  847.         if(cameraFollowingEntity.high->pos.X > (1.0f*TileMap->TileSideInMeters))
  848.         {
  849.             newCameraPos.absTileX += 1;
  850.         }
  851.         if(cameraFollowingEntity.high->pos.X < -(1.0f*TileMap->TileSideInMeters))
  852.         {
  853.             newCameraPos.absTileX -= 1;
  854.         }
  855.         if(cameraFollowingEntity.high->pos.Y > (1.0f*TileMap->TileSideInMeters))
  856.         {
  857.             newCameraPos.absTileY += 1;
  858.         }
  859.         if(cameraFollowingEntity.high->pos.Y < -(1.0f*TileMap->TileSideInMeters))
  860.         {
  861.             newCameraPos.absTileY -= 1;
  862.         }
  863. #endif
  864.         SetCamera(state, newCameraPos);
  865.     }
  866.  
  867.     DrawBitmap(buffer, &state->background, Vector(0));
  868.  
  869.     //DrawRectangle(buffer, 0.0f, 0.0f, (real32)buffer->width, (real32)buffer->height, 1.0f, 0.0f, 1.0f);   //Clear
  870.  
  871.     vector screenCenter = { (real32)buffer->width * 0.5f,
  872.                             (real32)buffer->height * 0.5f };
  873.  
  874. #if 0  
  875.     for(int32 relRow = -10; relRow < 10; ++relRow)
  876.     {
  877.         for(int32 relColumn = -20; relColumn < 20; ++relColumn)
  878.         {          
  879.             uint32 column = state->cameraPos.absTileX + relColumn;
  880.             uint32 row = state->cameraPos.absTileY + relRow;
  881.             uint32 layer = state->cameraPos.absTileZ;
  882.             uint32 tileId = GetTileValue(tileMap, column, row, layer);
  883.            
  884.             if(tileId > 1)
  885.             {
  886.                 real32 gray = 0.5f;
  887.                 if(tileId == 2)
  888.                 {                  
  889.                     gray = 1.0f;
  890.                 }
  891.                 if(tileId > 2)
  892.                 {
  893.                     gray = 0.75f;
  894.                 }
  895.  
  896.                 if((row == state->cameraPos.absTileY) && (column == state->cameraPos.absTileX))
  897.                 {
  898.                     gray = 0.0f;
  899.                 }
  900.                
  901.                 vector center = { screenCenter.x - metersToPixels * state->cameraPos.offset.x + ((real32)relColumn) * tileSideInPixels,
  902.                                   screenCenter.y + metersToPixels * state->cameraPos.offset.y - ((real32)relRow) * tileSideInPixels };             
  903.                
  904.                 real32 halfTileSideInPixels = 0.5f * tileSideInPixels;
  905.                 vector min =  center - Vector(halfTileSideInPixels);               
  906.                 vector max = center + Vector(halfTileSideInPixels);
  907.                                
  908.  
  909.                 DrawRectangle(buffer, min, max, gray, gray, gray); 
  910.             }          
  911.         }
  912.     }  
  913. #endif
  914.  
  915.     for(uint32 entityIndex = 1; entityIndex < state->entityCount; ++entityIndex)
  916.     {
  917.         if(state->entityResidence[entityIndex] == EntityResidenceHigh)
  918.         {  
  919.             high_entity *highEntity = &state->highEntities[entityIndex];
  920.             dormant_entity *dormantEntity = &state->dormantEntities[entityIndex];
  921.  
  922.             highEntity->pos += entityOffset;
  923.            
  924.             real32 dt = input->dt;
  925.             real32 ddz = -9.8f;
  926.             real32 deltaZ = (0.5f * ddz * Square(dt) + highEntity->dz * dt);
  927.             highEntity->z += deltaZ;
  928.             highEntity->dz = ddz * dt + highEntity->dz;
  929.             if(highEntity->z < 0)
  930.             {
  931.                 highEntity->z = 0;             
  932.             }
  933.            
  934.             real32 playerR = 0.5f;
  935.             real32 playerG = 0.15f;
  936.             real32 playerB = 0.79f;
  937.    
  938.             vector playerGroundPoint = { screenCenter.x + metersToPixels * highEntity->pos.x,
  939.                                          screenCenter.y - metersToPixels * highEntity->pos.y };
  940.  
  941.             vector playerPixelDimensions = { metersToPixels * dormantEntity->width, metersToPixels * dormantEntity->height };
  942.    
  943.             vector playerLeftTop = { playerGroundPoint.x - 0.5f * metersToPixels * dormantEntity->width,
  944.                                      playerGroundPoint.y - 0.5f * metersToPixels * dormantEntity->height };
  945.    
  946.             vector playerRightBot = playerLeftTop + playerPixelDimensions;
  947.    
  948.             real32 z = -metersToPixels * highEntity->z;
  949.                        
  950.             vector jumpOffset = Vector(0, z);
  951.  
  952.             if(dormantEntity->type == EntityType_Player)
  953.             {
  954.                 player_bitmaps *bitmaps = &state->playerBitmaps[highEntity->facingDirection];
  955.                 DrawBitmap(buffer, &state->shadow, playerGroundPoint, bitmaps->alignX, bitmaps->alignY);   
  956.                 DrawBitmap(buffer, &bitmaps->torso, playerGroundPoint + jumpOffset, bitmaps->alignX, bitmaps->alignY); 
  957.                 DrawBitmap(buffer, &bitmaps->cape, playerGroundPoint + jumpOffset, bitmaps->alignX, bitmaps->alignY);  
  958.                 DrawBitmap(buffer, &bitmaps->head, playerGroundPoint + jumpOffset, bitmaps->alignX, bitmaps->alignY);
  959.             }
  960.             else
  961.             {
  962.                 DrawRectangle(buffer, playerLeftTop, playerRightBot,
  963.                               playerR, playerG, playerB);
  964.             }
  965.         }
  966.     }
  967. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement