src/video/nds/SDL_ndsvideo.c
author Darren Alton <dalton@stevens.edu>
Fri, 25 Jul 2008 23:39:14 +0000
branchgsoc2008_nds
changeset 2681 c15b6c758be5
parent 2680 4135aa9c5645
child 2682 f7594fc66bda
permissions -rw-r--r--
Some small bug fixes and more work on video
     1 /*
     2     SDL - Simple DirectMedia Layer
     3     Copyright (C) 1997-2006 Sam Lantinga
     4 
     5     This library is free software; you can redistribute it and/or
     6     modify it under the terms of the GNU Lesser General Public
     7     License as published by the Free Software Foundation; either
     8     version 2.1 of the License, or (at your option) any later version.
     9 
    10     This library is distributed in the hope that it will be useful,
    11     but WITHOUT ANY WARRANTY; without even the implied warranty of
    12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    13     Lesser General Public License for more details.
    14 
    15     You should have received a copy of the GNU Lesser General Public
    16     License along with this library; if not, write to the Free Software
    17     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    18 
    19     Sam Lantinga
    20     slouken@libsdl.org
    21 */
    22 #include "SDL_config.h"
    23 
    24 /* SDL Nintendo DS video driver implementation
    25  * based on dummy driver:
    26  * Initial work by Ryan C. Gordon (icculus@icculus.org). A good portion
    27  *  of this was cut-and-pasted from Stephane Peter's work in the AAlib
    28  *  SDL video driver.  Renamed to "DUMMY" by Sam Lantinga.
    29  */
    30 
    31 #include <stdio.h>
    32 #include <stdlib.h>
    33 #include <nds.h>
    34 #include <nds/arm9/sprite.h>
    35 #include <nds/arm9/trig_lut.h>
    36 #include <nds/arm9/video.h>
    37 
    38 #include "SDL_video.h"
    39 #include "SDL_mouse.h"
    40 #include "../SDL_sysvideo.h"
    41 #include "../SDL_pixels_c.h"
    42 #include "../../events/SDL_events_c.h"
    43 
    44 #include "SDL_ndsvideo.h"
    45 #include "SDL_ndsevents_c.h"
    46 #include "SDL_ndsrender_c.h"
    47 
    48 #define NDSVID_DRIVER_NAME "nds"
    49 
    50 /* Initialization/Query functions */
    51 static int NDS_VideoInit(_THIS);
    52 static int NDS_SetDisplayMode(_THIS, SDL_DisplayMode * mode);
    53 static void NDS_VideoQuit(_THIS);
    54 
    55 /* NDS sprite-related functions */
    56 
    57 #define SPRITE_DMA_CHANNEL 3
    58 #define SPRITE_ANGLE_MASK 0x01FF
    59 
    60 void
    61 NDS_OAM_Update(tOAM *oam)
    62 {
    63     DC_FlushAll();
    64     dmaCopyHalfWords(SPRITE_DMA_CHANNEL, oam->spriteBuffer, OAM,
    65                      SPRITE_COUNT * sizeof(SpriteEntry));
    66 }
    67 
    68 void
    69 NDS_OAM_RotateSprite(SpriteRotation *spriteRotation, u16 angle)
    70 {
    71     s16 s = SIN[angle & SPRITE_ANGLE_MASK] >> 4;
    72     s16 c = COS[angle & SPRITE_ANGLE_MASK] >> 4;
    73 
    74     spriteRotation->hdx = c;
    75     spriteRotation->hdy = s;
    76     spriteRotation->vdx = -s;
    77     spriteRotation->vdy = c;
    78 }
    79 
    80 void
    81 NDS_OAM_Init(tOAM *oam)
    82 {
    83     int i;
    84     for(i = 0; i < SPRITE_COUNT; i++) {
    85         oam->spriteBuffer[i].attribute[0] = ATTR0_DISABLED;
    86         oam->spriteBuffer[i].attribute[1] = 0;
    87         oam->spriteBuffer[i].attribute[2] = 0;
    88     }
    89     for(i = 0; i < MATRIX_COUNT; i++) {
    90         NDS_OAM_RotateSprite(&(oam->matrixBuffer[i]), 0);
    91     }
    92     swiWaitForVBlank();
    93     NDS_OAM_Update(oam);
    94 }
    95 
    96 void
    97 NDS_OAM_HideSprite(SpriteEntry *spriteEntry)
    98 {
    99     spriteEntry->isRotoscale = 0;
   100     spriteEntry->isHidden = 1;
   101 }
   102 
   103 void
   104 NDS_OAM_ShowSprite(SpriteEntry *spriteEntry, int affine, int double_bound)
   105 {
   106     if (affine) {
   107         spriteEntry->isRotoscale = 1;
   108         spriteEntry->rsDouble = double_bound;
   109     } else {
   110         spriteEntry->isHidden = 0;
   111     }
   112 }
   113 
   114 
   115 /* SDL NDS driver bootstrap functions */
   116 static int
   117 NDS_Available(void)
   118 {
   119     /*const char *envr = SDL_getenv("SDL_VIDEODRIVER");*/
   120     /*printf("NDS_Available()\n"); */
   121     return (1);
   122 }
   123 
   124 static void
   125 NDS_DeleteDevice(SDL_VideoDevice * device)
   126 {
   127     SDL_free(device);
   128 }
   129 
   130 static SDL_VideoDevice *
   131 NDS_CreateDevice(int devindex)
   132 {
   133     SDL_VideoDevice *device;
   134     /*printf("NDS_CreateDevice(%d)\n", devindex); */
   135 
   136 printf("+NDS_CreateDevice\n");
   137     /* Initialize all variables that we clean on shutdown */
   138     device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice));
   139     if (!device) {
   140         SDL_OutOfMemory();
   141         if (device) {
   142             SDL_free(device);
   143         }
   144         return (0);
   145     }
   146 
   147     /* Set the function pointers */
   148     device->VideoInit = NDS_VideoInit;
   149     device->VideoQuit = NDS_VideoQuit;
   150     device->SetDisplayMode = NDS_SetDisplayMode;
   151     device->PumpEvents = NDS_PumpEvents;
   152 
   153     device->num_displays = 2;   /* DS = dual screens */
   154 
   155     device->free = NDS_DeleteDevice;
   156 
   157 printf("-NDS_CreateDevice\n");
   158     return device;
   159 }
   160 
   161 VideoBootStrap NDS_bootstrap = {
   162     NDSVID_DRIVER_NAME, "SDL NDS video driver",
   163     NDS_Available, NDS_CreateDevice
   164 };
   165 
   166 int
   167 NDS_VideoInit(_THIS)
   168 {
   169     SDL_DisplayMode mode;
   170     int i;
   171 
   172 printf("+NDS_VideoInit\n");
   173     /* simple 256x192x16x60 for now */
   174     mode.w = 256;
   175     mode.h = 192;
   176     mode.format = SDL_PIXELFORMAT_ABGR1555;
   177     mode.refresh_rate = 60;
   178     mode.driverdata = NULL;
   179 
   180     SDL_AddBasicVideoDisplay(&mode);
   181     SDL_AddRenderDriver(0, &NDS_RenderDriver);
   182     /*SDL_AddBasicVideoDisplay(&mode); two screens, same mode. uncomment later
   183     SDL_AddRenderDriver(1, &NDS_RenderDriver);*/
   184 
   185     SDL_zero(mode);
   186     SDL_AddDisplayMode(0, &mode);
   187 
   188     /* hackish stuff to get things up and running for now, and for a console */
   189     powerON(POWER_ALL_2D);
   190     irqInit();
   191     irqEnable(IRQ_VBLANK);
   192     NDS_SetDisplayMode(_this, &mode);
   193 printf("-NDS_VideoInit\n");
   194     return 0;
   195 }
   196 
   197 static int
   198 NDS_SetDisplayMode(_THIS, SDL_DisplayMode * mode)
   199 {
   200 printf("+NDS_SetDisplayMode\n");
   201     /* right now this function is just hard-coded for 256x192 ABGR1555 */
   202     videoSetMode(MODE_5_2D |
   203         DISPLAY_BG2_ACTIVE | DISPLAY_BG3_ACTIVE
   204         DISPLAY_SPR_1D_LAYOUT | DISPLAY_SPR_ACTIVE); /* display on main core */
   205     videoSetModeSub(MODE_0_2D | DISPLAY_BG0_ACTIVE); /* debug text on sub */
   206     vramSetMainBanks(VRAM_A_MAIN_BG_0x06000000, VRAM_B_MAIN_BG_0x06020000,
   207                      VRAM_C_SUB_BG_0x06200000,  VRAM_D_SUB_BG_0x06220000);
   208     vramSetBankE(VRAM_E_MAIN_SPRITE);
   209     /* set up console for debug text 'n stuff */
   210     SUB_BG0_CR = BG_MAP_BASE(31);
   211     BG_PALETTE_SUB[255] = RGB15(31, 31, 31);
   212    /* debugging purposes, uncomment this later.  then remove it & add 2screen.
   213     consoleInitDefault((u16 *) SCREEN_BASE_BLOCK_SUB(31),
   214                        (u16 *) CHAR_BASE_BLOCK_SUB(0), 16);*/
   215 printf("-NDS_SetDisplayMode\n");
   216     return 0;
   217 }
   218 
   219 void
   220 NDS_VideoQuit(_THIS)
   221 {
   222 printf("+NDS_VideoQuit\n");
   223     videoSetMode(DISPLAY_SCREEN_OFF);
   224     videoSetModeSub(DISPLAY_SCREEN_OFF);
   225     vramSetMainBanks(VRAM_A_LCD, VRAM_B_LCD, VRAM_C_LCD, VRAM_D_LCD);
   226 printf("-NDS_VideoQuit\n");
   227 }
   228 
   229 /* vi: set ts=4 sw=4 expandtab: */