Nuppiz

Gfx.c

Dec 2nd, 2021
861
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include "Shared.h"
  2. #include "Gfx.h"
  3.  
  4. // globals
  5. uint8_t far *VGA=(uint8_t *)0xA0000000L;        /* this points to video memory. */
  6. uint8_t far screen_buf [64000]; // double buffer
  7.  
  8. union REGS regs;
  9.  
  10. extern struct GameData g;
  11.  
  12. // reserve memory for sprites
  13. uint8_t far splash_screen [64000];
  14. uint8_t alphabet [4240];
  15. uint8_t sprites[NUM_SPRITES][TILE_AREA];
  16.  
  17. uint8_t* gfx_table[256];
  18.  
  19. void set_tile_gfx()
  20. {
  21.     _fmemset(gfx_table, ENT_ERROR, 256);
  22.     gfx_table['W'] = sprites[TILE_WALL];
  23.     gfx_table['-'] = sprites[TILE_FLOOR];
  24.     gfx_table['e'] = sprites[TILE_EXIT];
  25.     gfx_table['|'] = sprites[TILE_DOOR_C];
  26.     gfx_table['_'] = sprites[TILE_DOOR_O];
  27.     gfx_table['*'] = sprites[ITEM_KEY];
  28.     gfx_table['^'] = sprites[ITEM_MINE];
  29. }
  30.  
  31. void set_mode(uint8_t mode)
  32. {
  33.     regs.h.ah = SET_MODE;
  34.     regs.h.al = mode;
  35.     int86(VIDEO_INT, &regs, &regs);
  36. }
  37.  
  38. void fill_screen(uint8_t color)
  39. {
  40.     _fmemset(screen_buf, color, SCREEN_SIZE);
  41. }
  42.  
  43. void load_gfx(char* filename, uint8_t* destination, uint16_t data_size)
  44. {
  45.     FILE* file_ptr;
  46.     file_ptr = fopen(filename, "rb");
  47.     fread(destination, 1, data_size, file_ptr);
  48.     fclose(file_ptr);
  49. }
  50.  
  51. void load_sprite(int tile_id, char* filename)
  52. {
  53.     FILE* file_ptr;
  54.     file_ptr = fopen(filename, "rb");
  55.     fread(sprites[tile_id], 1, TILE_AREA, file_ptr);
  56.     fclose(file_ptr);
  57. }
  58.  
  59. void load_tiles()
  60. {
  61.     load_sprite(TILE_FLOOR, "GFX/FLOOR.7UP");
  62.     load_sprite(TILE_WALL, "GFX/BRICKS.7UP");
  63.     load_sprite(TILE_DOOR_C, "GFX/DOORC.7UP");
  64.     load_sprite(TILE_DOOR_O, "GFX/DOORO.7UP");
  65.     load_sprite(TILE_EXIT, "GFX/EXIT.7UP");
  66.     load_sprite(ITEM_KEY, "GFX/KEY.7UP");
  67.     load_sprite(ITEM_MINE, "GFX/MINE.7UP");
  68.     load_sprite(ENT_PLAYER, "GFX/PLAYER.7UP");
  69.     load_sprite(ENT_GUARD, "GFX/GUARD.7UP");
  70.     load_sprite(ENT_EXPLO, "GFX/EXPLO.7UP");
  71.     load_sprite(ENT_GRAVE, "GFX/GRAVE.7UP");
  72.     load_sprite(ENT_ERROR, "GFX/ERROR.7UP");
  73.     load_sprite(SHAD_IN_COR, "GFX/SHAD_IC.7UP");
  74.     load_sprite(SHAD_HORZ, "GFX/SHAD_H.7UP");
  75.     load_sprite(SHAD_VERT, "GFX/SHAD_V.7UP");
  76.     load_sprite(SHAD_OUT_COR, "GFX/SHAD_OC.7UP");
  77.     load_sprite(SHAD_MINE, "GFX/SHAD_M.7UP");
  78.     load_sprite(SHAD_KEY, "GFX/SHAD_K.7UP");
  79. }
  80.  
  81. void load_special_gfx()
  82. {
  83.     load_gfx("GFX/SPLASH.7UP", splash_screen, 64000);
  84.     load_gfx("GFX/FONT.7UP", alphabet, 4240);
  85. }
  86.  
  87. void draw_sprite(struct GameData* g, int x, int y, uint8_t* sprite)
  88. {
  89.     int index_x = 0;
  90.     int index_y = 0;
  91.     int i = 0;
  92.  
  93.     x += g->render_offset_x;
  94.     y += g->render_offset_y;
  95.  
  96.     for (index_y=0;index_y<TILE_HEIGHT;index_y++)
  97.     {
  98.         for (index_x=0;index_x<TILE_WIDTH;index_x++)
  99.         {
  100.             screen_buf[y*SCREEN_WIDTH+x]=sprite[i];
  101.             i++;
  102.             x++;
  103.         }
  104.         index_x = 0;
  105.         x -= TILE_WIDTH;
  106.         y++;
  107.     }
  108.     index_y = 0;
  109. }
  110.  
  111. void draw_sprite_tr(struct GameData* g, int x, int y, uint8_t* sprite)
  112. {
  113.     uint8_t index_x = 0;
  114.     uint8_t index_y = 0;
  115.     uint8_t i = 0;
  116.    
  117.     x += g->render_offset_x;
  118.     y += g->render_offset_y;
  119.  
  120.     for (index_y=0;index_y<TILE_HEIGHT;index_y++)
  121.     {
  122.         for (index_x=0;index_x<TILE_WIDTH;index_x++)
  123.         {
  124.             if (sprite[i] != 13)
  125.             {
  126.                 screen_buf[y*SCREEN_WIDTH+x]=sprite[i];
  127.                 i++;
  128.                 x++;
  129.             }
  130.             else
  131.             {
  132.                 i++;
  133.                 x++;
  134.             }
  135.         }
  136.         index_x = 0;
  137.         x = x - TILE_WIDTH;
  138.         y++;
  139.     }
  140.     index_y = 0;
  141. }
  142.  
  143. void draw_big(int x, int y, int w, int h, uint8_t* sprite)
  144. {
  145.     int index_x = 0;
  146.     int index_y = 0;
  147.     int i = 0;
  148.  
  149.     for (index_y=0; index_y<h;index_y++)
  150.     {
  151.         for (index_x=0; index_x<w;index_x++)
  152.         {
  153.             screen_buf[y*SCREEN_WIDTH+x]=sprite[i];
  154.             i++;
  155.             x++;
  156.         }
  157.         index_x = 0;
  158.         x -= w;
  159.         y++;
  160.     }
  161.     index_y = 0;
  162. }
  163.  
  164. void draw_rectangle(int x, int y, int w, int h, uint8_t color)
  165. {
  166.     int index_x = 0;
  167.     int index_y = 0;
  168.     int i = 0;
  169.  
  170.     for (index_y=0; index_y<h;index_y++)
  171.     {
  172.         for (index_x=0; index_x<w;index_x++)
  173.         {
  174.             screen_buf[y*SCREEN_WIDTH+x]=color;
  175.             i++;
  176.             x++;
  177.         }
  178.         index_x = 0;
  179.         x -= w;
  180.         y++;
  181.     }
  182.     index_y = 0;
  183. }
  184.  
  185. void draw_shadow(struct GameData* g, int x, int y)
  186. {    
  187.     int pixel_x = x*TILE_WIDTH;
  188.     int pixel_y = y*TILE_HEIGHT;
  189.    
  190.     if (TILE_AT(x-1, y-1) == 'W' &&
  191.         TILE_AT(x,   y-1) == 'W' &&
  192.         TILE_AT(x-1, y  ) == 'W')
  193.         draw_sprite_tr(g, pixel_x, pixel_y, sprites[SHAD_IN_COR]);
  194.        
  195.     else if (TILE_AT(x, y-1) == 'W')
  196.         draw_sprite_tr(g, pixel_x, pixel_y, sprites[SHAD_HORZ]);
  197.    
  198.     else if (TILE_AT(x-1, y) == 'W')
  199.         draw_sprite_tr(g, pixel_x, pixel_y, sprites[SHAD_VERT]);
  200.    
  201.     else if (TILE_AT(x-1, y-1) == 'W')
  202.         draw_sprite_tr(g, pixel_x, pixel_y, sprites[SHAD_OUT_COR]);
  203.  
  204.     else if (TILE_AT(x, y) == '^' && TILE_AT(x-1, y) == 'W')
  205.         draw_sprite_tr (g, pixel_x, pixel_y, sprites[SHAD_MINE]);
  206.  
  207.     else if (TILE_AT(x, y) == '*' && TILE_AT(x-1, y) == 'W')
  208.         draw_sprite_tr (g, pixel_x, pixel_y, sprites[SHAD_KEY]);
  209. }
  210.  
  211. void draw_text(int x, int y, int i, uint8_t color)
  212. {
  213.     uint8_t index_x = 0;
  214.     uint8_t index_y = 0;
  215.     i = i * CHARACTER_SIZE;
  216.  
  217.     for (index_y=0;index_y<TILE_HEIGHT;index_y++)
  218.     {
  219.         for (index_x=0;index_x<TILE_WIDTH;index_x++)
  220.         {
  221.             if (alphabet[i] != 13)
  222.             {
  223.                 screen_buf[y*SCREEN_WIDTH+x]=alphabet[i] + color;
  224.                 i++;
  225.                 x++;
  226.             }
  227.             else
  228.             {
  229.                 i++;
  230.                 x++;
  231.             }
  232.         }
  233.         index_x = 0;
  234.         x = x - TILE_WIDTH;
  235.         y++;
  236.     }
  237.     index_y = 0;
  238.     i= 0;
  239. }
  240.  
  241. void render_text(int x, int y, char* string, uint8_t color)
  242. {
  243.     int i = 0;
  244.     char c;
  245.    
  246.     while (string[i] != 0)
  247.     {
  248.         c = string[i];
  249.         draw_text(x, y, c - 32, color);
  250.         x = x + 10;
  251.         i++;
  252.     }
  253. }
  254.  
  255. void render_floor(struct GameData* g, int x, int y) // used to empty tiles after an item is picked up
  256. {
  257.     draw_sprite     (g, x * TILE_WIDTH,y * TILE_HEIGHT,sprites[TILE_FLOOR]);
  258.     draw_shadow     (g, x, y);
  259. }
  260.  
  261. void render_door(struct GameData* g, int x, int y) // used to draw an open door
  262. {
  263.     draw_sprite     (g, x * TILE_WIDTH,y * TILE_HEIGHT,sprites[TILE_FLOOR]);
  264.     draw_shadow     (g, x, y);
  265.     draw_sprite_tr  (g, x * TILE_WIDTH,y * TILE_HEIGHT,sprites[TILE_DOOR_O]);
  266. }
  267.  
  268. void render_mine(struct GameData* g, int x, int y) // used to draw mines, duh
  269. {
  270.     if (TILE_AT(x-1, y) != 'W')
  271.     {
  272.         draw_sprite     (g, x * TILE_WIDTH,y * TILE_HEIGHT,sprites[TILE_FLOOR]);
  273.         draw_shadow     (g, x, y);
  274.         draw_sprite_tr  (g, x * TILE_WIDTH,y * TILE_HEIGHT,sprites[ITEM_MINE]);
  275.     }
  276.     else if (TILE_AT(x-1, y) == 'W')
  277.     {
  278.         draw_sprite     (g, x * TILE_WIDTH,y * TILE_HEIGHT,sprites[TILE_FLOOR]);
  279.         draw_shadow     (g, x, y);
  280.         draw_sprite_tr  (g, x * TILE_WIDTH,y * TILE_HEIGHT,sprites[SHAD_MINE]);
  281.     }
  282. }
  283.  
  284. void typewriter(int x, int y, char* string, uint8_t color)
  285. {
  286.     int i = 0;
  287.     char c;
  288.    
  289.     while (string[i] != 0)
  290.     {
  291.         c = string[i];
  292.         draw_text(x, y, c - 32, color);
  293.         x = x + 10;
  294.         i++;
  295.         sound_typing();
  296.         memcpy(VGA,screen_buf,SCREEN_SIZE);
  297.         delay(100);
  298.     }
  299. }
  300.  
  301. void render_stats(struct GameData* g)
  302. {
  303.     char lvl_str[12];
  304.     char keys_str[12];
  305.     char lives_str[12];
  306.  
  307.     sprintf(lvl_str, "LEVEL: %d", g->level_num);
  308.     sprintf(keys_str, "KEYS: %d", g->keys_acquired);
  309.     sprintf(lives_str, "LIVES: %d", g->player_lives);
  310.  
  311.     render_text(1, 1, lvl_str, 15);
  312.  
  313.     if (g->keys_acquired < 100)
  314.         render_text(120, 1, keys_str, 15);
  315.     else
  316.         render_text(120, 1, "KEYS: 99", 15);
  317.    
  318.     if (g->player_lives > -1 && g->player_lives < 100)
  319.         render_text(230, 1, lives_str, 15);
  320.     else if (g->player_lives > 99)
  321.         render_text(230, 1, "LIVES: 99", 15);
  322.     else if (g->player_lives > -2)
  323.         render_text(230, 1, "LIVES: 0", 15);
  324. }
  325.  
  326. void render_maze(struct GameData* g)
  327. {  
  328.     int counter = 0;
  329.     int y = 0;
  330.     int x = 0;
  331.    
  332.     while (y < g->level_height)
  333.     {
  334.         while (x < g->level_width)
  335.         {
  336.             draw_sprite(g, x * TILE_WIDTH, y * TILE_HEIGHT, gfx_table[]);
  337.             counter++;
  338.             x++;
  339.         }
  340.     y++;
  341.     x = 0;
  342.     }
  343.  
  344.     render_stats(g);
  345. }
  346.  
  347. void render_actors(struct GameData* g)
  348. {
  349.     uint8_t* sprite;
  350.     int i;
  351.    
  352.     i = 0;
  353.     while (i < g->actor_count)
  354.     {
  355.        
  356.         switch (g->Actors[i].type)
  357.         {
  358.             case ACTOR_PLAYER:  sprite = sprites[ENT_PLAYER]; break;
  359.             case ACTOR_GUARD:   sprite = sprites[ENT_GUARD];  break;
  360.             default:            sprite = sprites[ENT_ERROR];  break;
  361.         }
  362.        
  363.         if (sprite == sprites[ENT_ERROR])
  364.         {
  365.             i++;
  366.             continue;
  367.         }
  368.        
  369.         draw_sprite_tr(g, g->Actors[i].x * TILE_WIDTH,
  370.                        g->Actors[i].y * TILE_HEIGHT,
  371.                        sprite);
  372.  
  373.         // if actor has changed position, render an empty floor tile in the old location, unless it's a door frame or mine        
  374.         if (g->Actors[i].x != g->Actors[i].old_x || g->Actors[i].y != g->Actors[i].old_y)
  375.         {
  376.             if (TILE_AT(g->Actors[i].old_x, g->Actors[i].old_y) == '-')
  377.                 render_floor(g, g->Actors[i].old_x, g->Actors[i].old_y);
  378.             else if (TILE_AT(g->Actors[i].old_x, g->Actors[i].old_y) == 'O')
  379.                 render_door(g, g->Actors[i].old_x, g->Actors[i].old_y);
  380.             else if (TILE_AT(g->Actors[i].old_x, g->Actors[i].old_y) == '^')
  381.                 render_mine(g, g->Actors[i].old_x, g->Actors[i].old_y);
  382.         }
  383.                      
  384.         i++;
  385.     }
  386.    
  387.     i = 0;
  388.     while (i < g->actor_count)
  389.     {
  390.        
  391.         switch (g->Actors[i].type)
  392.         {
  393.             case ACTOR_GRAVE:   sprite = sprites[ENT_GRAVE];  break;
  394.             case ACTOR_EXPLO:   sprite = sprites[ENT_EXPLO];   break;
  395.             case ACTOR_EMPTY:   sprite = sprites[ENT_GRAVE];  break;
  396.             default:            sprite = sprites[ENT_GRAVE];  break;
  397.         }
  398.        
  399.         if (sprite == sprites[ENT_ERROR])
  400.         {
  401.             i++;
  402.             continue;
  403.         }
  404.        
  405.         draw_sprite_tr(g, g->Actors[i].x * TILE_WIDTH,
  406.                        g->Actors[i].y * TILE_HEIGHT,
  407.                        sprite);                      
  408.         i++;
  409.     }
  410. }
  411.  
  412. void render_menu()
  413. {
  414.     draw_big(0, 0, 320, 200, splash_screen); // change to menu gfx or text later
  415. }
  416.  
  417. void render_end()
  418. {
  419.     fill_screen(0);
  420.     render_text(122, 96, "YOU WIN!", 14);
  421. }
  422.  
  423. void start_screen()
  424. {
  425.     fill_screen(0);
  426.    
  427.     typewriter(102, 96, "GET PSYCHED!", 1);
  428. }
  429.  
  430. void gameover_screen()
  431. {
  432.     draw_rectangle(111, 95, 98, 10, 0);
  433.     render_text(112, 96, "GAME OVER!", 4);
  434.     memcpy(VGA,screen_buf,SCREEN_SIZE);
  435. }
  436.  
  437. void debug_screen_e()
  438. {
  439.     draw_rectangle(66, 19, 188, 10, 1);
  440.     render_text(67, 20, "DEBUG MODE ENABLED!", 15);
  441.     memcpy(VGA,screen_buf,SCREEN_SIZE);
  442.     delay(1000);
  443.     draw_rectangle(61, 19, 198, 10, 0);
  444. }
  445.  
  446. void debug_screen_d()
  447. {
  448.     draw_rectangle(61, 19, 198, 10, 1);
  449.     render_text(62, 20, "DEBUG MODE DISABLED!", 15);
  450.     memcpy(VGA,screen_buf,SCREEN_SIZE);
  451.     delay(1000);
  452.     draw_rectangle(61, 19, 198, 10, 0);
  453. }
  454.  
  455. void render(struct GameData* g)
  456. {        
  457.     // in case playing, just died, or exited
  458.     // draw play field and objects
  459.     if (g->game_state == GAME_INGAME ||
  460.         g->game_state == GAME_OVER ||
  461.         g->game_state == GAME_WIN)
  462.     {
  463.         render_actors(g);
  464.     }
  465.     // if menu ...
  466.     else if (g->game_state == GAME_MENU)
  467.     {
  468.         render_menu();
  469.         render_text(200, 1, "VER. 0.0010A", 0);
  470.     }
  471.     // if end ...
  472.     else if (g->game_state == GAME_END)
  473.     {
  474.         render_end();
  475.     }
  476.     memcpy(VGA,screen_buf,SCREEN_SIZE);
  477. }
RAW Paste Data