diff --git a/src/dawn/display/frame.c b/src/dawn/display/frame.c
index 4bf09f32..75d0339e 100644
--- a/src/dawn/display/frame.c
+++ b/src/dawn/display/frame.c
@@ -21,38 +21,11 @@ void frameInit() {
 }
 
 void frameUpdate() {
-  // Draw buffer
-  entity_t *ent;
-  tile_t tile;
-  uint32_t i;
-
   map_t *map = GAME.currentMap;
   if(map == NULL) return;
 
   // Draw the map area.
-  i = 0;
-  for(uint16_t y = 0; y < FRAME_HEIGHT - FRAME_BOTTOM_UI_HEIGHT; y++) {
-    for(uint16_t x = 0; x < FRAME_WIDTH; x++) {
-      if(x >= map->width || y >= map->height) {
-        FRAME_COLOR[i] = COLOR_BLACK;
-        FRAME_BUFFER[i++] = ' ';
-        continue;
-      }
-
-      // Entity?
-      ent = mapEntityGetByPosition(map, x, y);
-      if(ent != NULL) {
-        FRAME_COLOR[i] = symbolGetColorByEntity(ent);
-        FRAME_BUFFER[i++] = symbolGetCharByEntity(ent);
-        continue;
-      }
-
-      // Tile?
-      tile = mapTileGetByPosition(map, x, y, 0);
-      FRAME_COLOR[i] = symbolGetColorByTile(tile);
-      FRAME_BUFFER[i++] = symbolGetCharByTile(tile);
-    }
-  }
+  frameMapDraw();
 }
 
 void frameUIReset() {
@@ -90,4 +63,104 @@ void frameUIReset() {
     i = y * FRAME_WIDTH + FRAME_WIDTH - 1;
     FRAME_BUFFER[i] = '|';
   }
+}
+
+void frameMapDraw() {
+  // Draw the map area.
+  entity_t *ent;
+  tile_t tile;
+  uint32_t i;
+
+  map_t *map = GAME.currentMap;
+  if(map == NULL) return;
+
+  // Try get player
+  entity_t *player = mapEntityGetByType(map, ENTITY_TYPE_PLAYER);
+  uint16_t cameraPositionX, cameraPositionY;
+  if(player == NULL) {
+    cameraPositionX = 0;
+    cameraPositionY = 0;
+  } else {
+    cameraPositionX = player->x;
+    cameraPositionY = player->y;
+  }
+
+  // If the size of the map's smaller than the frame, center it, otherwise use
+  // the cameraPosition as the center point.
+  int16_t offsetX = 0, offsetY = 0;
+  if(map->width < FRAME_MAP_WIDTH) {
+    offsetX = (FRAME_MAP_WIDTH - map->width) / 2;
+  } else {
+    // Clamp to map bounds
+    if(cameraPositionX < FRAME_MAP_WIDTH / 2) {
+      offsetX = 0;
+    } else if(cameraPositionX >= map->width - (FRAME_MAP_WIDTH / 2)) {
+      offsetX = -(map->width - FRAME_MAP_WIDTH);
+    } else {
+      offsetX = -(cameraPositionX - (FRAME_MAP_WIDTH / 2));
+    }
+  }
+
+  if(map->height < FRAME_MAP_HEIGHT) {
+    offsetY = (FRAME_MAP_HEIGHT - map->height) / 2;
+  } else {
+    // Clamp to map bounds
+    if(cameraPositionY < FRAME_MAP_HEIGHT / 2) {
+      offsetY = 0;
+    } else if(cameraPositionY >= map->height - (FRAME_MAP_HEIGHT / 2)) {
+      offsetY = -(map->height - FRAME_MAP_HEIGHT);
+    } else {
+      offsetY = -(cameraPositionY - (FRAME_MAP_HEIGHT / 2));
+    }
+  }
+
+  // Draw the map
+  i = 0;
+  for(uint16_t y = 0; y < FRAME_MAP_HEIGHT; y++) {
+    for(uint16_t x = 0; x < FRAME_MAP_WIDTH; x++) {
+      if(x < offsetX || y < offsetY || x >= map->width + offsetX || y >= map->height + offsetY) {
+        FRAME_COLOR[i] = COLOR_BLACK;
+        FRAME_BUFFER[i++] = ' ';
+        continue;
+      }
+
+      // Entity?
+      ent = mapEntityGetByPosition(map, x - offsetX, y - offsetY);
+      if(ent != NULL) {
+        FRAME_COLOR[i] = symbolGetColorByEntity(ent);
+        FRAME_BUFFER[i++] = symbolGetCharByEntity(ent);
+        continue;
+      }
+
+      // Tile?
+      tile = mapTileGetByPosition(map, x - offsetX, y - offsetY, 0);
+      FRAME_COLOR[i] = symbolGetColorByTile(tile);
+      FRAME_BUFFER[i++] = symbolGetCharByTile(tile);
+    }
+  }
+
+  // Old code:
+  // i = 0;
+  // for(uint16_t y = 0; y < FRAME_HEIGHT - FRAME_BOTTOM_UI_HEIGHT; y++) {
+  //   for(uint16_t x = 0; x < FRAME_WIDTH; x++) {
+  //     if(x >= map->width || y >= map->height) {
+  //       FRAME_COLOR[i] = COLOR_BLACK;
+  //       FRAME_BUFFER[i++] = ' ';
+  //       continue;
+  //     }
+
+  //     // Entity?
+  //     ent = mapEntityGetByPosition(map, x, y);
+  //     if(ent != NULL) {
+  //       FRAME_COLOR[i] = symbolGetColorByEntity(ent);
+  //       FRAME_BUFFER[i++] = symbolGetCharByEntity(ent);
+  //       continue;
+  //     }
+
+  //     // Tile?
+  //     tile = mapTileGetByPosition(map, x, y, 0);
+  //     FRAME_COLOR[i] = symbolGetColorByTile(tile);
+  //     FRAME_BUFFER[i++] = symbolGetCharByTile(tile);
+  //   }
+  // }
 }
\ No newline at end of file
diff --git a/src/dawn/display/frame.h b/src/dawn/display/frame.h
index ba8407ac..ca100eb2 100644
--- a/src/dawn/display/frame.h
+++ b/src/dawn/display/frame.h
@@ -16,6 +16,9 @@
 
 #define FRAME_BOTTOM_UI_HEIGHT 8
 
+#define FRAME_MAP_WIDTH FRAME_WIDTH
+#define FRAME_MAP_HEIGHT (FRAME_HEIGHT - FRAME_BOTTOM_UI_HEIGHT)
+
 extern char_t FRAME_BUFFER[FRAME_HEIGHT * FRAME_WIDTH];
 extern uint8_t FRAME_COLOR[FRAME_HEIGHT * FRAME_WIDTH];
 
@@ -32,4 +35,9 @@ void frameUpdate();
 /**
  * Resets the UI area of the frame.
  */
-void frameUIReset();
\ No newline at end of file
+void frameUIReset();
+
+/**
+ * Redraws the entire map area of the frame.
+ */
+void frameMapDraw();
\ No newline at end of file
diff --git a/src/dawn/game.h b/src/dawn/game.h
index 3d1b1ac7..44ca640e 100644
--- a/src/dawn/game.h
+++ b/src/dawn/game.h
@@ -11,8 +11,12 @@
 #define GAME_UPDATE_RESULT_CONTINUE 0
 #define GAME_UPDATE_RESULT_EXIT 1
 
+#define GAME_STATE_RUNNING 0
+#define GAME_STATE_PAUSED 1
+
 typedef struct {
   map_t *currentMap;
+  uint8_t state;
 } game_t;
 
 extern game_t GAME;
diff --git a/src/dawn/rpg/world/map.c b/src/dawn/rpg/world/map.c
index 90dcafa5..4a587cb4 100644
--- a/src/dawn/rpg/world/map.c
+++ b/src/dawn/rpg/world/map.c
@@ -82,6 +82,18 @@ entity_t * mapEntityGetByPosition(
   return NULL;
 }
 
+entity_t * mapEntityGetByType(
+  map_t *map,
+  const uint8_t type
+) {
+  for(uint8_t i = 0; i < map->entityCount; i++) {
+    entity_t *entity = &map->entities[i];
+    if(entity->type == type) return entity;
+  }
+
+  return NULL;
+}
+
 tile_t mapTileGetByPosition(
   const map_t *map,
   const uint16_t x,
diff --git a/src/dawn/rpg/world/map.h b/src/dawn/rpg/world/map.h
index 63e281f6..76e195a0 100644
--- a/src/dawn/rpg/world/map.h
+++ b/src/dawn/rpg/world/map.h
@@ -68,6 +68,18 @@ entity_t * mapEntityGetByPosition(
   const uint16_t y
 );
 
+/**
+ * Gets the entity of the specified type.
+ * 
+ * @param map Map to get the entity from.
+ * @param type Type of entity to get.
+ * @return Entity of the specified type, or NULL if no entity is found.
+ */
+entity_t * mapEntityGetByType(
+  map_t *map,
+  const uint8_t type
+);
+
 /**
  * Gets the tile at the specified position.
  * 
diff --git a/src/dawn/rpg/world/maps/testmap.h b/src/dawn/rpg/world/maps/testmap.h
index 8b6565fa..8761d6a0 100644
--- a/src/dawn/rpg/world/maps/testmap.h
+++ b/src/dawn/rpg/world/maps/testmap.h
@@ -9,19 +9,23 @@
 #include "rpg/world/map.h"
 #include "assert/assert.h"
 
+#define TEST_MAP_WIDTH 50
+#define TEST_MAP_HEIGHT 50
+#define TEST_MAP_LAYERS 1
+
 void testMapInit(map_t *map) {
-  mapInit(map, 20, 20, 1);
+  mapInit(map, TEST_MAP_WIDTH, TEST_MAP_HEIGHT, TEST_MAP_LAYERS);
 
   entity_t *player = mapEntityAdd(map);
   entityInit(player, ENTITY_TYPE_PLAYER, map);
   entityPositionSet(player, 5, 5);
 
-  entity_t *npc = mapEntityAdd(map);
-  entityInit(npc, ENTITY_TYPE_NPC, map);
-  entityPositionSet(npc, 10, 10);
+  // entity_t *npc = mapEntityAdd(map);
+  // entityInit(npc, ENTITY_TYPE_NPC, map);
+  // entityPositionSet(npc, 10, 10);
 
-  tile_t tiles[42 * 42];
-  for(uint32_t i = 0; i < 42 * 42; i++) {
+  tile_t tiles[TEST_MAP_WIDTH * TEST_MAP_HEIGHT];
+  for(uint32_t i = 0; i < TEST_MAP_WIDTH * TEST_MAP_HEIGHT; i++) {
     tiles[i].id = TILE_ID_GRASS;
   }
 
@@ -31,22 +35,22 @@ void testMapInit(map_t *map) {
   tiles[14].id = TILE_ID_WATER;
   tiles[15].id = TILE_ID_WATER;
 
-  tiles[30].id = TILE_ID_WATER;
-  tiles[31].id = TILE_ID_WATER;
-  tiles[32].id = TILE_ID_WATER;
-  tiles[33].id = TILE_ID_WATER;
-  tiles[34].id = TILE_ID_WATER;
-  tiles[35].id = TILE_ID_WATER;
+  // tiles[30].id = TILE_ID_WATER;
+  // tiles[31].id = TILE_ID_WATER;
+  // tiles[32].id = TILE_ID_WATER;
+  // tiles[33].id = TILE_ID_WATER;
+  // tiles[34].id = TILE_ID_WATER;
+  // tiles[35].id = TILE_ID_WATER;
 
-  tiles[50].id = TILE_ID_WATER;
-  tiles[51].id = TILE_ID_WATER;
-  tiles[52].id = TILE_ID_WATER;
-  tiles[53].id = TILE_ID_WATER;
+  // tiles[50].id = TILE_ID_WATER;
+  // tiles[51].id = TILE_ID_WATER;
+  // tiles[52].id = TILE_ID_WATER;
+  // tiles[53].id = TILE_ID_WATER;
 
-  tiles[70].id = TILE_ID_WATER;
-  tiles[71].id = TILE_ID_WATER;
-  tiles[72].id = TILE_ID_WATER;
-  tiles[73].id = TILE_ID_WATER;
+  // tiles[70].id = TILE_ID_WATER;
+  // tiles[71].id = TILE_ID_WATER;
+  // tiles[72].id = TILE_ID_WATER;
+  // tiles[73].id = TILE_ID_WATER;
   
 
   mapTilesSet(map, tiles, 0);
diff --git a/src/dawn/ui/textbox.c b/src/dawn/ui/textbox.c
index d999a028..3c825b6f 100644
--- a/src/dawn/ui/textbox.c
+++ b/src/dawn/ui/textbox.c
@@ -92,7 +92,6 @@ void textboxUpdate() {
 
   // Update scrolling
   TEXTBOX.nextChar -= TIME.delta;
-  if(inputIsDown(INPUT_BIND_ACCEPT)) TEXTBOX.nextChar -= TIME.delta;
   if(TEXTBOX.nextChar > 0.0f) return;
   
   // Scroll text
diff --git a/src/dawn/ui/textbox.h b/src/dawn/ui/textbox.h
index 3186afd9..6e56d30f 100644
--- a/src/dawn/ui/textbox.h
+++ b/src/dawn/ui/textbox.h
@@ -11,7 +11,7 @@
 
 #define TEXTBOX_TITLE_MAX 16
 #define TEXTBOX_TEXT_MAX ((FRAME_BOTTOM_UI_HEIGHT-2) * (FRAME_WIDTH - 2))
-#define TEXTBOX_CHARS_PER_SECOND 15
+#define TEXTBOX_CHARS_PER_SECOND 25
 #define TEXTBOX_BLINKS_PER_SECOND 2
 
 typedef struct {