Page 126 of 126 FirstFirst ... 2676116124125126
Results 1,251 to 1,259 of 1259

Thread: Game Boy

  1. #1251
    EmuTalk Member
    Join Date
    Jun 2014
    Posts
    7
    Mentioned
    2 Post(s)
    sebi707 nice work. I'm not sure if you already did these things to optimize your display but I hope I can help a bit: I would consider removing any sprite sorting algorithm (if used). Since you use a pixel-per-pixel approach (yeah dat Prehistorik Man...) you should check the possibility getting SCX and SCY values from MMIO fires and also calculate the Y addresses in vram after LY increases. Also, you could render the whole line in one take, and don't give a **** about Prehistorik Man. After all it's just the intro. We tried something with a friend of mine to speed up the core. We are porting my gb emulator to ARM android (since java runs as sluggish as 20fps max), and I had that idea of creating fixed address ARM instructions for each gameboy opcode. So we've coded blocks of ARM instructions like a jump table but without the table:

    0x00 : NOP, not much to say here
    0x01 : LD BC,## Shifting 0x01 << 8 left becomes 0x100. So in our prefixed memory 0x100 contains instructions for LD BC,## , and our code reaches 0x1A0 where it jumps at the end. We fill ARM NOPs until 0x1FF, and next comes 0x02 gb instruction LD (BC),A corresponding to 0x200 of our memory.

    I cannot give you fps results yet since we have a lot of things to do in the ASM core, but I think it should give a considerable amount of speed.

    Also it's not cheating to frameskip a bit. If you find your core runs at a decent speed, and emulation is stalled due to display, you can skip a frame or two. The LCD "afterimage" fade, will mostly smoothen out 1 frameskip I assume.

    edit: forgot to mention. You could precalculate a table of 256 (0-255) mods with the number 8. That is to avoid storming the cpu with mods, as you need 1 for BG and 1 for Window to get the correct vram bit.
    Last edited by venge; November 10th, 2014 at 14:46. Reason: extras

  2. #1252
    EmuTalk Member
    Join Date
    Jun 2013
    Posts
    34
    Mentioned
    1 Post(s)
    Quote Originally Posted by sebi707 View Post
    What compiler and compiler/linker options are you using? We are using gcc with O3 (instead of Os) and link time optimization. We've found that both options increase performance by a fair amount.
    I'm using gcc with O2 or O3, which is a tad faster. I also tried lto, but it causes the emulator to crash somewhere inside the initialization routine from the 3rd party LCD library. To make things worse, gcc does not emit debug information when using lto...
    I managed to compile the library without lto and everything else with, but there does not seem to be a measurable performance difference. At least the binary is about 30% smaller.
    After some small optimizations, I'm at about 12fps, so no breakthrough there either .

  3. #1253
    EmuTalk Member
    Join Date
    Nov 2014
    Posts
    5
    Mentioned
    0 Post(s)
    Well, although I've only started my GB emulator, and it will be a long while before I get to this stage, I'd like to have a nice reference to look back on. I don't really see how graphics work. With chip-8, there was 1 opcode that drew to the screen. I know it's not like that for gb, so when I get to the graphics stage, I'd like to have a nice reference to look at.

    Thanks!

    ~shutterbug2000~

  4. #1254
    EmuTalk Member
    Join Date
    Mar 2014
    Location
    Chicago, IL
    Posts
    57
    Mentioned
    4 Post(s)
    I'd advise having a look through these tutorials/wikis to get an idea of what's going on ->

    http://imrannazar.com/GameBoy-Emulation-in-JavaScript
    http://realboyemulator.wordpress.com/getting-started/
    http://gbdev.gg8.se/wiki/articles/Main_Page

    You can easily find Nintendo's Official GB Programming guide floating around (Google is your friend) as well as Pan Docs. Give both a read regarding what you want to know more about.

    Regarding drawing things to the screen, there is no opcode to draw things on screen. The GB, like many other 2D consoles, uses tile-based graphics. The data sits in VRAM (Video RAM), and after a certain amount of CPU cycles, the LCD controller reads the relevant data and outputs something to the screen. This is a gross oversimplification of what's really going on, but you get the idea. Every once and a while, your emulated LCD's draw function will have to be called from the emulator itself (usually per-scanline after enough cycles have passed to draw one horizontal line, or less commonly per-pixel after enough cycles have passed to draw a single pixel).

  5. #1255
    EmuTalk Member
    Join Date
    Feb 2014
    Posts
    33
    Mentioned
    0 Post(s)
    http://problemkaputt.de/pandocs.htm

    This is the most complete reference I know.

  6. #1256
    EmuTalk Member
    Join Date
    Nov 2014
    Posts
    5
    Mentioned
    0 Post(s)
    Thanks for the resources, but I still don't quite get drawing.
    Particularly, when to draw, and, how to get tiles.
    If you wanted to, a detailed explained/ some documented code would really help me.

    ~Thanks! ~
    ~shutterbug2000~

  7. #1257
    EmuTalk Member
    Join Date
    Mar 2014
    Location
    Chicago, IL
    Posts
    57
    Mentioned
    4 Post(s)
    This is how I learned ->
    http://imrannazar.com/GameBoy-Emulat...t:-GPU-Timings
    http://imrannazar.com/GameBoy-Emulat...ript:-Graphics

    I'll try to elaborate as best as I can. The GB's LCD draws graphics scanline by scanline. It starts at the top (Line 0) and works it's way from left to right, top to bottom, until it reaches the last visible scanline. When drawing an individual pixel, the GB will look up which tile it needs to draw and the relevant palette data of the tile data. On real hardware, the LCD needs time to jump from the right-most pixel at the end of a scanline (pixel 159, Line 0) to the next scanline, first pixel (pixel 0, Line 1). This period is called Horizontal Blank or HBlank for short. Ignoring mid-scanline rendering (it is a fringe case, don't worry about it) In terms of drawing data to the screen in an emulator, this is the relevant time to render a scanline's pixels, since on real hardware HBlank basically says "Hey, we're done with this scanline, let's move on." The GB hardware is very precise, like most computers; HBlank will after a specific amount of CPU cycles have happened, so you'll always know when your enter HBlank as long as you keep track of that.

    The GB has what's called Tile Maps, which are basically 1-byte entries that point tiles. The GB's VRAM can hold two Tile Maps, each with a size of 32x32 tiles (tiles themselves are always 8x8, the BG size is 256x256 altogether). The Tile Maps would look something like this in hexadecimal:

    Code:
    01  00  02  07  00 ...
    In which case each byte represents a tile number (Tile #1, Tile #0, Tile#2, Tile #7, you get the idea). Pretend these are the first 5 bytes in our Tile Map. If we were going to draw this, we'd need to examine the pixel data contained in Tile #1 to get the first 8x8 section of graphics, then read Tile #0 to get the next 8x8 section of graphics, and so on (hope this ASCII chart works, if not see attachment...)

    Code:
    ==================================================================================
    <--- Pixels--->
    0............8.............16.............24.............32.............40........
    ----------------------------------------------------------------------------------
    |...TILE #1..|...TILE# 0...|....TILE #2...|....TILE #7...|....TILE #0...|.........
    ==================================================================================
    I should note that you should not draw the entire 8x8 section of the tile all at once, just the relevant line of that tile. That is to say, if the current scanline (modulus 8) is 0, draw pixels 0-7 of the tile. If the current scanline (modulus 8) is 1, draw pixels 8-15. If the current scanline (modulus 8) is 2, draw pixels 16-23, and so on. You can draw each 8x8 section at a time, but that would lead to incorrect results in a number of circumstances where Background Scroll X is changed between scanlines (used to create wave-like screen effects a la the beginning of the Oracle games, or used to properly draw the HUD in Super Mario Land). If you're curious about the reason for doing modulus 8 (% 8 in C++) let me know (it involves a bit of math) and I'll draw up a diagram to better explain it.

    Anyway, in the above example, you'd first see that the Tile Map says you need to look at Tile #1 for pixel data to draw. You simply then read the data at Tile #1's memory location, determine what color the pixel needs to be based on the current palette, then draw it to the screen. Again, a gross oversimplification, but that's the gist of it. If you have any specific questions, I'll try to answer them.
    Attached Images Attached Images  
    Last edited by Shonumi; November 28th, 2014 at 17:42.

  8. #1258
    EmuTalk Member
    Join Date
    Nov 2014
    Posts
    5
    Mentioned
    0 Post(s)
    That helps out lots! Thanks!
    I think I know what to do now, but I just need to know how many cpu cycles it takes to reach hblank. According to the javascript gameboy emulator tutorial, it takes 204, I just wanted to verify. Also, how do you retrieve the tIle itself, not just the tile map.

    ~Thanks!~
    ~shutterbug2000~

  9. #1259
    EmuTalk Member
    Join Date
    Mar 2014
    Location
    Chicago, IL
    Posts
    57
    Mentioned
    4 Post(s)
    The tile itself is nothing more than a series of bytes at a specified location in memory. The game logic itself will handle filling in the correct bytes (the game will copy portions of ROM into VRAM, so all you need for that part is decent CPU emulation and decent memory read/write emulation). To grab the tile, you simply read the bytes at the memory location for the tiles. The GB stores tiles from 0x8000 to 0x97FF. Depending on what values certain registers have, you will either look at 0x8000-0x87FF for Tile Set #1 or it will look at 0x8800-0x97FF for Tile Set #0



    Each tile occupies 16 bytes of memory, so if the GB is using Tile Set #1, and you want to grab something like Tile #9, you need to calculate its offset (0x8000 + (16 * 9)) = 0x8090. So then you need to read the following 16 bytes (0x8090-0x809F) to get the tile data.

Page 126 of 126 FirstFirst ... 2676116124125126

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •