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