src/video/nds/SDL_ndsrender.c
author Sam Lantinga
Tue, 08 Feb 2011 16:50:51 -0800
changeset 5229 c015d3e63631
parent 5149 be02be2ea897
child 5246 58265e606e4e
permissions -rw-r--r--
Fixed setting the texture unit, still doesn't work.
slouken@2735
     1
/*
slouken@2735
     2
    SDL - Simple DirectMedia Layer
slouken@3697
     3
    Copyright (C) 1997-2010 Sam Lantinga
slouken@2735
     4
slouken@2735
     5
    This library is free software; you can redistribute it and/or
slouken@2735
     6
    modify it under the terms of the GNU Lesser General Public
slouken@2735
     7
    License as published by the Free Software Foundation; either
slouken@2735
     8
    version 2.1 of the License, or (at your option) any later version.
slouken@2735
     9
slouken@2735
    10
    This library is distributed in the hope that it will be useful,
slouken@2735
    11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
slouken@2735
    12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
slouken@2735
    13
    Lesser General Public License for more details.
slouken@2735
    14
slouken@2735
    15
    You should have received a copy of the GNU Lesser General Public
slouken@2735
    16
    License along with this library; if not, write to the Free Software
slouken@2735
    17
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
slouken@2735
    18
slouken@2735
    19
    Sam Lantinga
slouken@2735
    20
    slouken@libsdl.org
slouken@2735
    21
*/
slouken@2735
    22
slouken@2735
    23
#include <stdio.h>
slouken@2735
    24
#include <stdlib.h>
slouken@2735
    25
#include <nds.h>
dalton@3073
    26
//#include <nds/arm9/video.h>
dalton@3073
    27
//#include <nds/arm9/sprite.h>
dalton@3073
    28
//#include <nds/arm9/trig_lut.h>
slouken@2735
    29
slouken@2735
    30
#include "SDL_config.h"
slouken@2735
    31
slouken@2735
    32
#include "SDL_video.h"
slouken@2735
    33
#include "../SDL_sysvideo.h"
slouken@2735
    34
#include "../SDL_yuv_sw_c.h"
slouken@2735
    35
#include "../SDL_renderer_sw.h"
slouken@2735
    36
slouken@2735
    37
/* SDL NDS renderer implementation */
slouken@2735
    38
slouken@2735
    39
static SDL_Renderer *NDS_CreateRenderer(SDL_Window * window, Uint32 flags);
slouken@2735
    40
static int NDS_ActivateRenderer(SDL_Renderer * renderer);
slouken@2735
    41
static int NDS_DisplayModeChanged(SDL_Renderer * renderer);
slouken@2735
    42
static int NDS_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture);
slouken@2735
    43
static int NDS_QueryTexturePixels(SDL_Renderer * renderer,
slouken@2735
    44
                                  SDL_Texture * texture, void **pixels,
slouken@2735
    45
                                  int *pitch);
slouken@2735
    46
static int NDS_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
slouken@2735
    47
                             const SDL_Rect * rect, const void *pixels,
slouken@2735
    48
                             int pitch);
slouken@2735
    49
static int NDS_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
slouken@2735
    50
                           const SDL_Rect * rect, int markDirty,
slouken@2735
    51
                           void **pixels, int *pitch);
slouken@2735
    52
static void NDS_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture);
slouken@2735
    53
static int NDS_RenderFill(SDL_Renderer * renderer, Uint8 r, Uint8 g,
slouken@2735
    54
                          Uint8 b, Uint8 a, const SDL_Rect * rect);
slouken@2735
    55
static int NDS_RenderCopy(SDL_Renderer * renderer,
slouken@2735
    56
                          SDL_Texture * texture,
slouken@2735
    57
                          const SDL_Rect * srcrect, const SDL_Rect * dstrect);
slouken@2735
    58
static void NDS_RenderPresent(SDL_Renderer * renderer);
slouken@2735
    59
static void NDS_DestroyTexture(SDL_Renderer * renderer,
slouken@2735
    60
                               SDL_Texture * texture);
slouken@2735
    61
static void NDS_DestroyRenderer(SDL_Renderer * renderer);
slouken@2735
    62
slouken@2735
    63
slouken@2735
    64
SDL_RenderDriver NDS_RenderDriver = {
slouken@2735
    65
    NDS_CreateRenderer,
slouken@2735
    66
    {"nds",                     /* char* name */
slouken@5142
    67
     (SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC),  /* u32 flags */
slouken@5149
    68
     2,                         /* u32 num_texture_formats */
slouken@2735
    69
     {
slouken@2735
    70
      SDL_PIXELFORMAT_ABGR1555,
slouken@2735
    71
      SDL_PIXELFORMAT_BGR555,
slouken@3139
    72
      },                        /* u32 texture_formats[20] */
slouken@2735
    73
     (256),                     /* int max_texture_width */
slouken@2735
    74
     (256),                     /* int max_texture_height */
slouken@2735
    75
     }
slouken@2735
    76
};
slouken@2735
    77
slouken@2735
    78
typedef struct
slouken@2735
    79
{
slouken@2735
    80
    u8 bg_taken[4];
dalton@3073
    81
    OamState *oam;
slouken@2735
    82
    int sub;
slouken@2735
    83
} NDS_RenderData;
slouken@2735
    84
slouken@2735
    85
typedef struct
slouken@2735
    86
{
slouken@2735
    87
    enum
slouken@2735
    88
    { NDSTX_BG, NDSTX_SPR } type;       /* represented in a bg or sprite. */
dalton@3073
    89
    int hw_index;               /* index of sprite in OAM or bg from libnds */
dalton@3073
    90
    int pitch, bpp;             /* useful information about the texture */
slouken@3139
    91
    struct
slouken@3139
    92
    {
slouken@3139
    93
        int x, y;
slouken@3139
    94
    } scale;                    /* x/y stretch (24.8 fixed point) */
slouken@3139
    95
    struct
slouken@3139
    96
    {
slouken@3139
    97
        int x, y;
slouken@3139
    98
    } scroll;                   /* x/y offset */
dalton@3073
    99
    int rotate;                 /* -32768 to 32767, texture rotation */
slouken@2735
   100
    u16 *vram_pixels;           /* where the pixel data is stored (a pointer into VRAM) */
slouken@2735
   101
    u16 *vram_palette;          /* where the palette data is stored if it's indexed. */
slouken@2735
   102
    /*int size; */
slouken@2735
   103
} NDS_TextureData;
slouken@2735
   104
slouken@2735
   105
slouken@2735
   106
slouken@2735
   107
SDL_Renderer *
slouken@2735
   108
NDS_CreateRenderer(SDL_Window * window, Uint32 flags)
slouken@2735
   109
{
slouken@3685
   110
    SDL_VideoDisplay *display = window->display;
slouken@2735
   111
    SDL_DisplayMode *displayMode = &display->current_mode;
slouken@2735
   112
    SDL_Renderer *renderer;
slouken@2735
   113
    NDS_RenderData *data;
slouken@2735
   114
    int i, n;
slouken@2735
   115
    int bpp;
slouken@2735
   116
    Uint32 Rmask, Gmask, Bmask, Amask;
slouken@2735
   117
slouken@2735
   118
    if (!SDL_PixelFormatEnumToMasks(displayMode->format, &bpp,
slouken@2735
   119
                                    &Rmask, &Gmask, &Bmask, &Amask)) {
slouken@2735
   120
        SDL_SetError("Unknown display format");
slouken@2735
   121
        return NULL;
slouken@2735
   122
    }
slouken@2735
   123
    switch (displayMode->format) {
slouken@2735
   124
    case SDL_PIXELFORMAT_ABGR1555:
slouken@2735
   125
    case SDL_PIXELFORMAT_BGR555:
slouken@2735
   126
        /* okay */
slouken@2735
   127
        break;
slouken@2735
   128
    case SDL_PIXELFORMAT_RGB555:
slouken@2735
   129
    case SDL_PIXELFORMAT_RGB565:
slouken@2735
   130
    case SDL_PIXELFORMAT_ARGB1555:
slouken@2735
   131
        /* we'll take these too for now */
slouken@2735
   132
        break;
slouken@2735
   133
    default:
slouken@2735
   134
        SDL_SetError("Warning: wrong display format for NDS!\n");
slouken@2735
   135
        break;
slouken@2735
   136
    }
slouken@2735
   137
slouken@2735
   138
    renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
slouken@2735
   139
    if (!renderer) {
slouken@2735
   140
        SDL_OutOfMemory();
slouken@2735
   141
        return NULL;
slouken@2735
   142
    }
slouken@2735
   143
slouken@2735
   144
    data = (NDS_RenderData *) SDL_malloc(sizeof(*data));
slouken@2735
   145
    if (!data) {
slouken@2735
   146
        NDS_DestroyRenderer(renderer);
slouken@2735
   147
        SDL_OutOfMemory();
slouken@2735
   148
        return NULL;
slouken@2735
   149
    }
slouken@2735
   150
    SDL_zerop(data);
slouken@2735
   151
slouken@2735
   152
    renderer->RenderFill = NDS_RenderFill;
slouken@2735
   153
    renderer->RenderCopy = NDS_RenderCopy;
slouken@2735
   154
    renderer->RenderPresent = NDS_RenderPresent;
slouken@2735
   155
    renderer->DestroyRenderer = NDS_DestroyRenderer;
slouken@2735
   156
    renderer->info.name = NDS_RenderDriver.info.name;
slouken@2735
   157
    renderer->info.flags = 0;
slouken@3685
   158
    renderer->window = window;
slouken@2735
   159
    renderer->driverdata = data;
slouken@2735
   160
    renderer->CreateTexture = NDS_CreateTexture;
slouken@2735
   161
    renderer->QueryTexturePixels = NDS_QueryTexturePixels;
slouken@2735
   162
    renderer->UpdateTexture = NDS_UpdateTexture;
slouken@2735
   163
    renderer->LockTexture = NDS_LockTexture;
slouken@2735
   164
    renderer->UnlockTexture = NDS_UnlockTexture;
slouken@2735
   165
    renderer->DestroyTexture = NDS_DestroyTexture;
slouken@2735
   166
slouken@2735
   167
    renderer->info.num_texture_formats =
slouken@2735
   168
        NDS_RenderDriver.info.num_texture_formats;
slouken@2735
   169
    SDL_memcpy(renderer->info.texture_formats,
slouken@2735
   170
               NDS_RenderDriver.info.texture_formats,
slouken@2735
   171
               sizeof(renderer->info.texture_formats));
slouken@2735
   172
    renderer->info.max_texture_width =
slouken@2735
   173
        NDS_RenderDriver.info.max_texture_width;
slouken@2735
   174
    renderer->info.max_texture_height =
slouken@2735
   175
        NDS_RenderDriver.info.max_texture_height;
slouken@2735
   176
slouken@3139
   177
    data->sub = 0;              /* TODO: this is hard-coded to the "main" screen.
slouken@3139
   178
                                   figure out how to detect whether to set it to
slouken@3139
   179
                                   "sub" screen.  window->id, perhaps? */
slouken@2735
   180
    data->bg_taken[2] = data->bg_taken[3] = 0;
slouken@2735
   181
slouken@2735
   182
    return renderer;
slouken@2735
   183
}
slouken@2735
   184
slouken@2735
   185
static int
slouken@2735
   186
NDS_ActivateRenderer(SDL_Renderer * renderer)
slouken@2735
   187
{
slouken@2735
   188
    NDS_RenderData *data = (NDS_RenderData *) renderer->driverdata;
slouken@2735
   189
slouken@2735
   190
    return 0;
slouken@2735
   191
}
slouken@2735
   192
slouken@2735
   193
static int
slouken@2735
   194
NDS_DisplayModeChanged(SDL_Renderer * renderer)
slouken@2735
   195
{
slouken@2735
   196
    NDS_RenderData *data = (NDS_RenderData *) renderer->driverdata;
slouken@2735
   197
slouken@2735
   198
    return 0;
slouken@2735
   199
}
slouken@2735
   200
slouken@2735
   201
static int
slouken@2735
   202
NDS_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
slouken@2735
   203
{
slouken@2735
   204
    NDS_RenderData *data = (NDS_RenderData *) renderer->driverdata;
slouken@2735
   205
    NDS_TextureData *txdat = NULL;
slouken@2735
   206
    int i;
slouken@2735
   207
    int bpp;
slouken@2735
   208
    Uint32 Rmask, Gmask, Bmask, Amask;
slouken@2735
   209
slouken@2735
   210
    if (!SDL_PixelFormatEnumToMasks
slouken@2735
   211
        (texture->format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) {
slouken@2735
   212
        SDL_SetError("Unknown texture format");
slouken@2735
   213
        return -1;
slouken@2735
   214
    }
slouken@2735
   215
slouken@2735
   216
    /* conditional statements on w/h to place it as bg/sprite
slouken@2735
   217
       depending on which one it fits. */
slouken@2735
   218
    if (texture->w <= 64 && texture->h <= 64) {
slouken@2735
   219
        int whichspr = -1;
dalton@3073
   220
        printf("NDS_CreateTexture: Tried to make a sprite.\n");
slouken@2735
   221
        txdat->type = NDSTX_SPR;
dalton@3073
   222
#if 0
slouken@2735
   223
        for (i = 0; i < SPRITE_COUNT; ++i) {
slouken@2735
   224
            if (data->oam_copy.spriteBuffer[i].attribute[0] & ATTR0_DISABLED) {
slouken@2735
   225
                whichspr = i;
slouken@2735
   226
                break;
slouken@2735
   227
            }
slouken@2735
   228
        }
slouken@2735
   229
        if (whichspr >= 0) {
slouken@2735
   230
            SpriteEntry *sprent = &(data->oam_copy.spriteBuffer[whichspr]);
slouken@2735
   231
            int maxside = texture->w > texture->h ? texture->w : texture->h;
slouken@2735
   232
            int pitch;
slouken@2735
   233
slouken@2735
   234
            texture->driverdata = SDL_calloc(1, sizeof(NDS_TextureData));
slouken@2735
   235
            txdat = (NDS_TextureData *) texture->driverdata;
slouken@2735
   236
            if (!txdat) {
slouken@2735
   237
                SDL_OutOfMemory();
slouken@2735
   238
                return -1;
slouken@2735
   239
            }
slouken@2735
   240
slouken@2735
   241
            sprent->objMode = OBJMODE_BITMAP;
slouken@2735
   242
            sprent->posX = 0;
slouken@2735
   243
            sprent->posY = 0;
slouken@2735
   244
            sprent->colMode = OBJCOLOR_16;      /* OBJCOLOR_256 for INDEX8 */
slouken@2735
   245
slouken@2735
   246
            /* the first 32 sprites get transformation matrices.
slouken@2735
   247
               first come, first served */
slouken@2735
   248
            if (whichspr < MATRIX_COUNT) {
slouken@2735
   249
                sprent->isRotoscale = 1;
slouken@2735
   250
                sprent->rsMatrixIdx = whichspr;
slouken@2735
   251
            }
slouken@2735
   252
slouken@2735
   253
            /* containing shape (square or 2:1 rectangles) */
slouken@2735
   254
            sprent->objShape = OBJSHAPE_SQUARE;
slouken@2735
   255
            if (texture->w / 2 >= texture->h) {
slouken@2735
   256
                sprent->objShape = OBJSHAPE_WIDE;
slouken@2735
   257
            } else if (texture->h / 2 >= texture->w) {
slouken@2735
   258
                sprent->objShape = OBJSHAPE_TALL;
slouken@2735
   259
            }
slouken@2735
   260
slouken@2735
   261
            /* size in pixels */
slouken@2735
   262
            /* FIXME: "pitch" is hardcoded for 2bytes per pixel. */
slouken@2735
   263
            sprent->objSize = OBJSIZE_64;
slouken@2735
   264
            pitch = 128;
slouken@2735
   265
            if (maxside <= 8) {
slouken@2735
   266
                sprent->objSize = OBJSIZE_8;
slouken@2735
   267
                pitch = 16;
slouken@2735
   268
            } else if (maxside <= 16) {
slouken@2735
   269
                sprent->objSize = OBJSIZE_16;
slouken@2735
   270
                pitch = 32;
slouken@2735
   271
            } else if (maxside <= 32) {
slouken@2735
   272
                sprent->objSize = OBJSIZE_32;
slouken@2735
   273
                pitch = 64;
slouken@2735
   274
            }
slouken@2735
   275
slouken@2735
   276
            /* FIXME: this is hard-coded and will obviously only work for one
slouken@2735
   277
               sprite-texture.  tells it to look at the beginning of SPRITE_GFX
slouken@2735
   278
               for its pixels. */
slouken@2735
   279
            sprent->tileIdx = 0;
slouken@2735
   280
slouken@2735
   281
            /* now for the texture data */
slouken@2735
   282
            txdat->type = NDSTX_SPR;
slouken@2735
   283
            txdat->hw_index = whichspr;
slouken@2735
   284
            txdat->dim.hdx = 0x100;
slouken@2735
   285
            txdat->dim.hdy = 0;
slouken@2735
   286
            txdat->dim.vdx = 0;
slouken@2735
   287
            txdat->dim.vdy = 0x100;
slouken@2735
   288
            txdat->dim.pitch = pitch;
slouken@2735
   289
            txdat->dim.bpp = bpp;
slouken@3139
   290
            txdat->vram_pixels =
slouken@3139
   291
                (u16 *) (data->sub ? SPRITE_GFX_SUB : SPRITE_GFX);
dalton@3073
   292
            /* FIXME: use tileIdx*boundary
slouken@3139
   293
               to point to proper location */
slouken@2735
   294
        } else {
slouken@2735
   295
            SDL_SetError("Out of NDS sprites.");
slouken@2735
   296
        }
dalton@3073
   297
#endif
slouken@2735
   298
    } else if (texture->w <= 256 && texture->h <= 256) {
slouken@2735
   299
        int whichbg = -1, base = 0;
slouken@2735
   300
        if (!data->bg_taken[2]) {
slouken@2735
   301
            whichbg = 2;
slouken@2735
   302
        } else if (!data->bg_taken[3]) {
slouken@2735
   303
            whichbg = 3;
slouken@2735
   304
            base = 4;
slouken@2735
   305
        }
slouken@2735
   306
        if (whichbg >= 0) {
slouken@2735
   307
            texture->driverdata = SDL_calloc(1, sizeof(NDS_TextureData));
slouken@2735
   308
            txdat = (NDS_TextureData *) texture->driverdata;
slouken@2735
   309
            if (!txdat) {
slouken@2735
   310
                SDL_OutOfMemory();
slouken@2735
   311
                return -1;
slouken@2735
   312
            }
dalton@3073
   313
// hard-coded for 256x256 for now...
dalton@3073
   314
// TODO: a series of if-elseif-else's to find the closest but larger size.
slouken@3139
   315
            if (!data->sub) {
slouken@3139
   316
                if (bpp == 8) {
slouken@3139
   317
                    txdat->hw_index =
slouken@3139
   318
                        bgInit(whichbg, BgType_Bmp8, BgSize_B8_256x256, 0, 0);
dalton@3073
   319
                } else {
slouken@3139
   320
                    txdat->hw_index =
slouken@3139
   321
                        bgInit(whichbg, BgType_Bmp16, BgSize_B16_256x256, 0,
slouken@3139
   322
                               0);
dalton@3073
   323
                }
dalton@3073
   324
            } else {
slouken@3139
   325
                if (bpp == 8) {
slouken@3139
   326
                    txdat->hw_index =
slouken@3139
   327
                        bgInitSub(whichbg, BgType_Bmp8, BgSize_B8_256x256, 0,
slouken@3139
   328
                                  0);
dalton@3073
   329
                } else {
slouken@3139
   330
                    txdat->hw_index =
slouken@3139
   331
                        bgInitSub(whichbg, BgType_Bmp16, BgSize_B16_256x256,
slouken@3139
   332
                                  0, 0);
dalton@3073
   333
                }
dalton@3073
   334
            }
slouken@2735
   335
dalton@3073
   336
/*   useful functions
dalton@3073
   337
        bgGetGfxPtr(bg3);            
dalton@3073
   338
		bgSetCenter(bg3, rcX, rcY);
dalton@3073
   339
		bgSetRotateScale(bg3, angle, scaleX, scaleY);
dalton@3073
   340
		bgSetScroll(bg3, scrollX, scrollY);
dalton@3073
   341
		bgUpdate(bg3);
dalton@3073
   342
*/
slouken@2735
   343
            txdat->type = NDSTX_BG;
slouken@3139
   344
            txdat->pitch = (texture->w) * (bpp / 8);
dalton@3073
   345
            txdat->bpp = bpp;
dalton@3073
   346
            txdat->rotate = 0;
dalton@3073
   347
            txdat->scale.x = 0x100;
dalton@3073
   348
            txdat->scale.y = 0x100;
dalton@3073
   349
            txdat->scroll.x = 0;
dalton@3073
   350
            txdat->scroll.y = 0;
slouken@3139
   351
            txdat->vram_pixels = (u16 *) bgGetGfxPtr(txdat->hw_index);
slouken@2735
   352
dalton@3073
   353
            bgSetCenter(txdat->hw_index, 0, 0);
dalton@3073
   354
            bgSetRotateScale(txdat->hw_index, txdat->rotate, txdat->scale.x,
dalton@3073
   355
                             txdat->scale.y);
dalton@3073
   356
            bgSetScroll(txdat->hw_index, txdat->scroll.x, txdat->scroll.y);
dalton@3073
   357
            bgUpdate(txdat->hw_index);
dalton@3073
   358
dalton@3073
   359
            data->bg_taken[whichbg] = 1;
slouken@2735
   360
            /*txdat->size = txdat->dim.pitch * texture->h; */
slouken@2735
   361
        } else {
slouken@2735
   362
            SDL_SetError("Out of NDS backgrounds.");
slouken@2735
   363
        }
slouken@2735
   364
    } else {
slouken@2735
   365
        SDL_SetError("Texture too big for NDS hardware.");
slouken@2735
   366
    }
slouken@2735
   367
slouken@2735
   368
    if (!texture->driverdata) {
slouken@2735
   369
        return -1;
slouken@2735
   370
    }
slouken@2735
   371
slouken@2735
   372
    return 0;
slouken@2735
   373
}
slouken@2735
   374
slouken@2735
   375
static int
slouken@2735
   376
NDS_QueryTexturePixels(SDL_Renderer * renderer, SDL_Texture * texture,
slouken@2735
   377
                       void **pixels, int *pitch)
slouken@2735
   378
{
slouken@2735
   379
    NDS_TextureData *txdat = (NDS_TextureData *) texture->driverdata;
slouken@2735
   380
    *pixels = txdat->vram_pixels;
dalton@3073
   381
    *pitch = txdat->pitch;
slouken@2735
   382
    return 0;
slouken@2735
   383
}
slouken@2735
   384
slouken@2735
   385
static int
slouken@2735
   386
NDS_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
slouken@2735
   387
                  const SDL_Rect * rect, const void *pixels, int pitch)
slouken@2735
   388
{
slouken@2735
   389
    NDS_TextureData *txdat;
slouken@2735
   390
    Uint8 *src, *dst;
slouken@2735
   391
    int row;
slouken@2735
   392
    size_t length;
slouken@2735
   393
slouken@2735
   394
    txdat = (NDS_TextureData *) texture->driverdata;
slouken@2735
   395
slouken@2735
   396
    src = (Uint8 *) pixels;
slouken@2735
   397
    dst =
dalton@3073
   398
        (Uint8 *) txdat->vram_pixels + rect->y * txdat->pitch + rect->x *
dalton@3073
   399
        ((txdat->bpp + 1) / 8);
dalton@3073
   400
    length = rect->w * ((txdat->bpp + 1) / 8);
slouken@2735
   401
slouken@2735
   402
    if (rect->w == texture->w) {
slouken@2735
   403
        dmaCopy(src, dst, length * rect->h);
slouken@2735
   404
    } else {
slouken@2735
   405
        for (row = 0; row < rect->h; ++row) {
slouken@2735
   406
            dmaCopy(src, dst, length);
slouken@2735
   407
            src += pitch;
dalton@3073
   408
            dst += txdat->pitch;
slouken@2735
   409
        }
slouken@2735
   410
    }
slouken@2735
   411
slouken@2735
   412
    return 0;
slouken@2735
   413
}
slouken@2735
   414
slouken@2735
   415
static int
slouken@2735
   416
NDS_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
slouken@2735
   417
                const SDL_Rect * rect, int markDirty, void **pixels,
slouken@2735
   418
                int *pitch)
slouken@2735
   419
{
slouken@2735
   420
    NDS_TextureData *txdat = (NDS_TextureData *) texture->driverdata;
slouken@2735
   421
dalton@3073
   422
    *pixels = (void *) ((u8 *) txdat->vram_pixels + rect->y * txdat->pitch +
dalton@3073
   423
                        rect->x * ((txdat->bpp + 1) / 8));
dalton@3073
   424
    *pitch = txdat->pitch;
slouken@2735
   425
slouken@2735
   426
    return 0;
slouken@2735
   427
}
slouken@2735
   428
slouken@2735
   429
static void
slouken@2735
   430
NDS_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
slouken@2735
   431
{
slouken@2735
   432
    /* stub! */
slouken@2735
   433
}
slouken@2735
   434
slouken@2735
   435
static int
slouken@2735
   436
NDS_RenderFill(SDL_Renderer * renderer, Uint8 r, Uint8 g, Uint8 b,
slouken@2735
   437
               Uint8 a, const SDL_Rect * rect)
slouken@2735
   438
{
slouken@2735
   439
    NDS_RenderData *data = (NDS_RenderData *) renderer->driverdata;
slouken@2735
   440
    SDL_Rect real_rect = *rect;
slouken@2735
   441
    u16 color;
slouken@2735
   442
    int i, j;
slouken@2735
   443
dalton@3073
   444
    printf("NDS_RenderFill: stub\n");
slouken@3139
   445
    color = RGB8(r, g, b);      /* macro in libnds that makes an ARGB1555 pixel */
slouken@2735
   446
    /* TODO: make a single-color sprite and stretch it.
slouken@2735
   447
       calculate the "HDX" width modifier of the sprite by:
slouken@2735
   448
       let S be the actual sprite's width (like, 32 pixels for example)
slouken@2735
   449
       let R be the rectangle's width (maybe 50 pixels)
slouken@2735
   450
       HDX = (R<<8) / S;
slouken@2735
   451
       (it's fixed point, hence the bit shift.  same goes for vertical.
slouken@2735
   452
       be sure to use 32-bit int's for the bit shift before the division!)
slouken@2735
   453
     */
slouken@2735
   454
slouken@2735
   455
    return 0;
slouken@2735
   456
}
slouken@2735
   457
slouken@2735
   458
static int
slouken@2735
   459
NDS_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
slouken@2735
   460
               const SDL_Rect * srcrect, const SDL_Rect * dstrect)
slouken@2735
   461
{
slouken@2735
   462
    NDS_RenderData *data = (NDS_RenderData *) renderer->driverdata;
slouken@2735
   463
    NDS_TextureData *txdat = (NDS_TextureData *) texture->driverdata;
slouken@3685
   464
    SDL_Window *window = renderer->window;
slouken@3685
   465
    SDL_VideoDisplay *display = window->display;
dalton@3073
   466
    int Bpp = SDL_BYTESPERPIXEL(texture->format);
slouken@2735
   467
slouken@2735
   468
    if (txdat->type == NDSTX_BG) {
dalton@3073
   469
        txdat->scroll.x = dstrect->x;
dalton@3073
   470
        txdat->scroll.y = dstrect->y;
slouken@2735
   471
    } else {
slouken@2735
   472
        /* sprites not fully implemented yet */
dalton@3073
   473
        printf("NDS_RenderCopy: used sprite!\n");
dalton@3073
   474
//        SpriteEntry *spr = &(data->oam_copy.spriteBuffer[txdat->hw_index]);
dalton@3073
   475
//        spr->posX = dstrect->x;
dalton@3073
   476
//        spr->posY = dstrect->y;
dalton@3073
   477
//        if (txdat->hw_index < MATRIX_COUNT && spr->isRotoscale) {          
dalton@3073
   478
//        }
slouken@2735
   479
    }
slouken@2735
   480
slouken@2735
   481
    return 0;
slouken@2735
   482
}
slouken@2735
   483
slouken@2735
   484
slouken@2735
   485
static void
slouken@2735
   486
NDS_RenderPresent(SDL_Renderer * renderer)
slouken@2735
   487
{
slouken@2735
   488
    NDS_RenderData *data = (NDS_RenderData *) renderer->driverdata;
slouken@3685
   489
    SDL_Window *window = renderer->window;
slouken@3685
   490
    SDL_VideoDisplay *display = window->display;
slouken@2735
   491
slouken@2735
   492
    /* update sprites */
dalton@3073
   493
//    NDS_OAM_Update(&(data->oam_copy), data->sub);
slouken@2735
   494
    /* vsync for NDS */
slouken@2735
   495
    if (renderer->info.flags & SDL_RENDERER_PRESENTVSYNC) {
slouken@2735
   496
        swiWaitForVBlank();
slouken@2735
   497
    }
slouken@2735
   498
}
slouken@2735
   499
slouken@2735
   500
static void
slouken@2735
   501
NDS_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture)
slouken@2735
   502
{
slouken@2735
   503
    NDS_TextureData *txdat = texture->driverdata;
slouken@2735
   504
    /* free anything else allocated for texture */
slouken@2735
   505
    SDL_free(txdat);
slouken@2735
   506
}
slouken@2735
   507
slouken@2735
   508
static void
slouken@2735
   509
NDS_DestroyRenderer(SDL_Renderer * renderer)
slouken@2735
   510
{
slouken@2735
   511
    NDS_RenderData *data = (NDS_RenderData *) renderer->driverdata;
slouken@2735
   512
    int i;
slouken@2735
   513
slouken@2735
   514
    if (data) {
slouken@2735
   515
        /* free anything else relevant if anything else is allocated. */
slouken@2735
   516
        SDL_free(data);
slouken@2735
   517
    }
slouken@2735
   518
    SDL_free(renderer);
slouken@2735
   519
}
slouken@2735
   520
slouken@2735
   521
/* vi: set ts=4 sw=4 expandtab: */