diff src/ljgba.c @ 0:c84446dfb3f5

initial add
author paulo@localhost
date Fri, 13 Mar 2009 00:39:12 -0700
parents
children
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/ljgba.c	Fri Mar 13 00:39:12 2009 -0700
     1.3 @@ -0,0 +1,230 @@
     1.4 +/* GBA frontend for LOCKJAW, an implementation of the Soviet Mind Game
     1.5 +
     1.6 +Copyright (C) 2006-2007 Damian Yerrick <tepples+lj@spamcop.net>
     1.7 +
     1.8 +This work is free software; you can redistribute it and/or modify
     1.9 +it under the terms of the GNU General Public License as published by
    1.10 +the Free Software Foundation; either version 2 of the License, or
    1.11 +(at your option) any later version.
    1.12 +
    1.13 +This program is distributed in the hope that it will be useful,
    1.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
    1.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1.16 +GNU General Public License for more details.
    1.17 +
    1.18 +You should have received a copy of the GNU General Public License
    1.19 +along with this program; if not, write to the Free Software
    1.20 +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    1.21 +
    1.22 +Original game concept and design by Alexey Pajitnov.
    1.23 +The Software is not sponsored or endorsed by Alexey Pajitnov, Elorg,
    1.24 +or The Tetris Company LLC.
    1.25 +
    1.26 +*/
    1.27 +
    1.28 +#include <stdio.h>
    1.29 +#include <string.h>
    1.30 +#include "ljgba.h"
    1.31 +#include "ljplay.h"
    1.32 +#include "options.h"
    1.33 +
    1.34 +#if 1
    1.35 +  #define LJ_VERSION "0.46 ("__DATE__")"
    1.36 +#else
    1.37 +  #define LJ_VERSION "WIP ("__DATE__")"
    1.38 +#endif
    1.39 +
    1.40 +#define SCREEN_W 30
    1.41 +#define SCREEN_H 20
    1.42 +#define DS_PFTOP 0
    1.43 +#define DS_PFLEFT 9
    1.44 +#include "ljgbads.inc"
    1.45 +
    1.46 +static unsigned int nSprites;
    1.47 +
    1.48 +LJBits readHWKeys(void) {
    1.49 +  return (~REG_KEYINPUT) & 0x03FF;
    1.50 +}
    1.51 +
    1.52 +void finishSprites() {
    1.53 +  for (int i = nSprites - 1; i >= 0; --i) {
    1.54 +    OAM[i].attr0 = 512;
    1.55 +  }
    1.56 +  nSprites = 128;
    1.57 +}
    1.58 +
    1.59 +void vsync(void) {
    1.60 +  VBlankIntrWait();
    1.61 +}
    1.62 +
    1.63 +void openWindow(void) {
    1.64 +  REG_DISPCNT = MODE_0 | BG0_ON | OBJ_ON;
    1.65 +  BGCTRL[0] = BG_TILE_BASE(0) | BG_MAP_BASE(31);
    1.66 +  BG_PALETTE[0] = RGB5(31, 31, 31);
    1.67 +  BG_PALETTE[1] = RGB5(0, 0, 0);
    1.68 +  SPRITE_PALETTE[0] = RGB5(31, 0, 31);
    1.69 +  SPRITE_PALETTE[1] = RGB5(0, 0, 0);
    1.70 +  setupPalette(srsColors);
    1.71 +}
    1.72 +
    1.73 +void playSoundEffects(LJView *v, LJBits sounds, int countdown) {
    1.74 +  if (sounds & LJSND_IRS) {
    1.75 +    gba_play_sound(v->plat, 6);
    1.76 +  } else if (sounds & LJSND_ROTATE) {
    1.77 +    gba_play_sound(v->plat, 1);
    1.78 +  }
    1.79 +  if (sounds & LJSND_SHIFT) {
    1.80 +    gba_play_sound(v->plat, 0);
    1.81 +  }
    1.82 +  if (sounds & LJSND_LAND) {
    1.83 +    gba_play_sound(v->plat, 2);
    1.84 +  }
    1.85 +  if (sounds & LJSND_LOCK) {
    1.86 +    gba_play_sound(v->plat, 3);
    1.87 +  }
    1.88 +  if (sounds & LJSND_B2B) {
    1.89 +    gba_play_sound(v->plat, 8);
    1.90 +  } else if (sounds & LJSND_SETB2B) {
    1.91 +    gba_play_sound(v->plat, 7);
    1.92 +  } else if (sounds & LJSND_LINE) {
    1.93 +    gba_play_sound(v->plat, 4);
    1.94 +  }
    1.95 +  if (sounds & LJSND_HOLD) {
    1.96 +    gba_play_sound(v->plat, 5);
    1.97 +  }
    1.98 +  if (sounds & LJSND_SECTIONUP) {
    1.99 +    gba_play_sound(v->plat, 9);
   1.100 +  }
   1.101 +  gba_poll_sound(v->plat);
   1.102 +}
   1.103 +
   1.104 +/**
   1.105 + * Draws a tetromino whose lower left corner of the bounding box is at (x, y)
   1.106 + * @param b the bitmap to draw to
   1.107 + * @param piece the piece to be drawn
   1.108 + * @param x distance from to left side of 4x4 box
   1.109 + * @param y distance from top of bitmap to bottom of 4x4 box
   1.110 + * @param the rotation state (0: U; 1: R; 2: D; 3: L; 4: Initial position)
   1.111 + * @param w width of each block
   1.112 + * @param h height of each block
   1.113 + * @param color Drawing style
   1.114 + * color == 0: draw shadow
   1.115 + * color == 0x10 through 0x70: draw in that color
   1.116 + * color == 0x80: draw as garbage
   1.117 + * color == -255 through -1: draw with 255 through 1 percent lighting
   1.118 + */
   1.119 +LJBits drawPiece(LJView *const v, void *const b,
   1.120 +                 int piece, int x, int y, int theta,
   1.121 +                 int color, int w, int h) {
   1.122 +  // Don't try to draw the -1 that's the sentinel for no hold piece
   1.123 +  if (piece < 0)
   1.124 +    return 0;
   1.125 +
   1.126 +  LJBits rows = 0;
   1.127 +  LJBlkSpec blocks[4];
   1.128 +
   1.129 +  expandPieceToBlocks(blocks, v->field, piece, 0, 0, theta);
   1.130 +  
   1.131 +  for (int blk = 0; blk < 4; ++blk) {
   1.132 +    int blkValue = blocks[blk].conn;
   1.133 +    if (blkValue) {
   1.134 +      int blkX = blocks[blk].x;
   1.135 +      int blkY = blocks[blk].y;
   1.136 +      const int dstX = x + w * blkX;
   1.137 +      const int dstY = y + h * (-1 - blkY);
   1.138 +    
   1.139 +      if (color == 0x80) {
   1.140 +        blkValue = 0x8001;  // garbage hold
   1.141 +      } else if (color != 0) {
   1.142 +        blkValue = ((blkValue & 0xF0) << 8) | 1;
   1.143 +      } else if (color == 0) {
   1.144 +        if (v->hideShadow == LJSHADOW_COLORED) {
   1.145 +          blkValue = ((blkValue & 0xF0) << 8) | 2;
   1.146 +        } else {
   1.147 +          blkValue = 0x0002;
   1.148 +        }
   1.149 +      }
   1.150 +    
   1.151 +      if (dstY > -8 && dstY < 160) {
   1.152 +        --nSprites;
   1.153 +        OAM[nSprites].attr0 = dstY & 0x00FF;
   1.154 +        OAM[nSprites].attr1 = dstX & 0x01FF;
   1.155 +        OAM[nSprites].attr2 = blkValue;
   1.156 +      }
   1.157 +
   1.158 +      rows |= 1 << blkY;
   1.159 +    }
   1.160 +  }
   1.161 +
   1.162 +  return rows;
   1.163 +}
   1.164 +
   1.165 +extern unsigned char prefs[OPTIONS_MENU_LEN];
   1.166 +
   1.167 +#include "gbamenus.h"
   1.168 +
   1.169 +int main(void) {
   1.170 +  LJField p = {
   1.171 +    .leftWall = 1,
   1.172 +    .rightWall = 11,
   1.173 +    .ceiling = 20
   1.174 +  };
   1.175 +  LJControl control = {
   1.176 +    .dasSpeed = 1,
   1.177 +    .dasDelay = 10,
   1.178 +    .initialDAS = 1,
   1.179 +    .allowDiagonals = 0,
   1.180 +    .softDropSpeed = 0,
   1.181 +    .softDropLock = 0,
   1.182 +    .hardDropLock = 1
   1.183 +  };
   1.184 +  struct LJPCView platView;
   1.185 +  LJView mainView = {
   1.186 +    .field = &p,
   1.187 +    .control = &control,
   1.188 +    .smoothGravity = 1,
   1.189 +    .plat = &platView,
   1.190 +    .backDirty = ~0
   1.191 +  };
   1.192 +
   1.193 +  videoSetMode(MODE_0_2D);
   1.194 +  BG_PALETTE[0] = RGB5(31, 0, 0);
   1.195 +  install_timer();
   1.196 +  openWindow();
   1.197 +  install_sound(&platView);
   1.198 +  initOptions(customPrefs);
   1.199 +  coprNotice();
   1.200 +  
   1.201 +  while (1) {
   1.202 +    LJView *const players[1] = {&mainView};
   1.203 +    REG_DISPCNT = MODE_0 | BG0_ON;
   1.204 +    BG_PALETTE[0] = RGB5(31, 31, 31);
   1.205 +    setupPalette(srsColors);
   1.206 +    options(&mainView, customPrefs);
   1.207 +    unpackCommonOptions(&mainView, customPrefs);
   1.208 +
   1.209 +    p.seed = curTime ^ (curTime << 16);
   1.210 +    play(players, 1);
   1.211 +    BG_PALETTE[0] = (control.countdown > 0)
   1.212 +                    ? RGB5(31, 15, 15) 
   1.213 +                    : RGB5(15, 31, 15);
   1.214 +    if (control.countdown > 0) {
   1.215 +      gba_play_sound(&platView, 10);
   1.216 +      gba_play_sound(&platView, 11);
   1.217 +    } else {
   1.218 +      gba_play_sound(&platView, 12);
   1.219 +      gba_play_sound(&platView, 13);
   1.220 +    }
   1.221 +    for (int i = 0; i < 60; ++i) {
   1.222 +      vsync();
   1.223 +      gba_poll_sound(&platView);
   1.224 +    }
   1.225 +#if 1
   1.226 +    debrief(&mainView);
   1.227 +#else
   1.228 +    textout(" Press  ", (SCREEN_W - 8) / 2, DS_PFTOP + 8, 0);
   1.229 +    textout("  Start ", (SCREEN_W - 8) / 2, DS_PFTOP + 9, 0);
   1.230 +    waitForStart();
   1.231 +#endif
   1.232 +  }
   1.233 +}