git.y1.nz

gbdk-2020

GameBoy Development Kit
download: https://git.y1.nz/archives/gbdk.tar.gz
README | Files | Log | Refs | LICENSE

gbdk-lib/examples/gb/rand/src/rand.c

      1 /***************************************************************************
      2  *                                                                         *
      3  * Module  : rand.c                                                        *
      4  *                                                                         *
      5  * Purpose : A test for the rand() function, for the GBDK                  *
      6  *                                                                         *
      7  * Version : 1, Januari 6 1998                                             *
      8  *                                                                         *
      9  * Author  : Luc Van den Borre ( Homepage : NOC.BASE.ORG )                 *
     10  *                                                                         *
     11  **************************************************************************/
     12 
     13 #include <gb/gb.h>
     14 #include <rand.h>
     15 #include <gb/drawing.h>
     16 #include <stdio.h>
     17 #include <string.h>
     18 #include <stdint.h>
     19 
     20 #define RANGE_SIZE       (160u / 4u)
     21 #define HALF_RANGE_SIZE  (RANGE_SIZE / 2u)
     22 
     23 UBYTE accu[RANGE_SIZE];
     24 UBYTE accua[RANGE_SIZE];
     25 UBYTE accut[RANGE_SIZE];
     26 UBYTE accub[RANGE_SIZE];
     27 
     28 // Fast alternative to modulo for arbitrary 8 bit range sizes
     29 // (range sizes that are exact powers of 2 can use faster bit shift or mask reductions)
     30 //
     31 // see: https://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/
     32 //
     33 // Max value for RANGE is 256
     34 #define RAND_RANGE_8BIT(randval, range) (uint8_t)(((randval & 0xFFu) * range) >> 8)
     35 
     36 void main(void)
     37 {
     38     uint16_t seed;
     39 
     40     memset(accu, 0, sizeof(accu));
     41     memset(accua, 0, sizeof(accua));
     42     memset(accut, 0, sizeof(accut));
     43     memset(accut, 0, sizeof(accub));
     44 
     45     /* We use the DIV register to get a random initial seed */
     46     puts("Getting seed");
     47     puts("Push any key (1)");
     48     waitpad(0xFF);
     49     waitpadup();
     50     seed = DIV_REG;
     51     puts("Push any key (2)");
     52     waitpad(0xFF);
     53     waitpadup();
     54     seed |= (UWORD)DIV_REG << 8;
     55 
     56     // initarand() calls initrand()
     57     initarand(seed);
     58 
     59     // Draw some divider lines
     60     line(RANGE_SIZE * 1, 0, RANGE_SIZE * 1, 143);
     61     line(RANGE_SIZE * 2, 0, RANGE_SIZE * 2, 143);
     62     line(RANGE_SIZE * 3, 0, RANGE_SIZE * 3, 143);
     63 
     64     while (1) {
     65 
     66         // Generate standard random values in the range of 0 .. RANGE_SIZE - 1
     67         // and accumulate the values into buckets, then plot the bucket sizes
     68 
     69         // Using rand()
     70         uint8_t r = RAND_RANGE_8BIT(rand(), RANGE_SIZE);
     71 
     72         // Using arand()
     73         uint8_t ra = RAND_RANGE_8BIT(arand(), RANGE_SIZE);
     74 
     75         // Create a triangle distribution using (rand - rand)
     76         uint8_t rt1 = RAND_RANGE_8BIT(rand(), HALF_RANGE_SIZE);
     77         uint8_t rt2 = RAND_RANGE_8BIT(rand(), HALF_RANGE_SIZE);
     78         uint8_t rt = HALF_RANGE_SIZE + (rt1 - rt2);
     79 
     80         // Create a bell-curve-ish distribution using (rand - rand) + (rand - rand)
     81         uint8_t rb1 = RAND_RANGE_8BIT(rand(), HALF_RANGE_SIZE / 2);
     82         uint8_t rb2 = RAND_RANGE_8BIT(rand(), HALF_RANGE_SIZE / 2);
     83         uint8_t rb3 = RAND_RANGE_8BIT(rand(), HALF_RANGE_SIZE / 2);
     84         uint8_t rb4 = RAND_RANGE_8BIT(rand(), HALF_RANGE_SIZE / 2);
     85         uint8_t rb = HALF_RANGE_SIZE + (rb1 - rb2) + (rb3 - rb4);
     86 
     87 
     88         // Plot the updated rand value buckets
     89         //
     90         // rand | arand | rand with triangle distribution | bell-curve-ish
     91 
     92         uint8_t r_bucket_height = ++accu[r];
     93         if (r_bucket_height > 144) break;
     94         plot(r  + (RANGE_SIZE * 0), 144-r_bucket_height, LTGREY, SOLID);
     95 
     96         uint8_t ra_bucket_height = ++accua[ra];
     97         if (ra_bucket_height > 144) break;
     98         plot(ra + (RANGE_SIZE * 1), 144 - ra_bucket_height, DKGREY, SOLID);
     99 
    100         uint8_t rt_bucket_height = ++accut[rt];
    101         if (rt_bucket_height > 144) break;
    102         plot(rt + (RANGE_SIZE * 2), 144 - rt_bucket_height, BLACK, SOLID);
    103 
    104         uint8_t rb_bucket_height = ++accub[rb];
    105         if (rb_bucket_height > 144) break;
    106         plot(rb + (RANGE_SIZE * 3), 144 - rb_bucket_height, BLACK, SOLID);
    107     }
    108 }
    109 

This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.